Hacking with a Pervasive Expert System (AI) my electronic toothbrush

970401_10151619375122570_47370022_n

Just made some progress on my Mobile & Pervasive Expert System tool, finally enabling some Pervasive dimensions but, most importantly, drafting a first round over the AI-side of the system.

The current goal for this step is: enable the system to be pervasively aware when I’m using my electronic toothbrush, infer how much time I’ve used, and then finally post the result to Facebook.

The current implementation, which I’m going to briefly describe in this post, is based on the following technologies and Java libraries:

Description of the process

I will starting describing from the physical world. I’ve put an IR-sensor in front of the toothbrush stand, as shown in the picture above.

Then I connected this sensor, using some simple electronics, to the XBee module in order to perform the ADC and therefore to have the sensor’s measurement available in digital form.

ebe6275ac6f611e28efa22000a1fbd9c_7

This XBee mesh provides a wireless way to communicate the reading from the toothbrush stand, located in the bathroom, to the actual room where my pc/server is located having the software application running.

This concludes for the physical/hardware part, in fact the biggest part is actually in the software world!

Fortunately there is for the XBee modules a Java library called “xbee-api” available on Google Code, so in my case I just wanted to write for myself an Apache Camel component, to serve as a wrapper for the sensor readings. The code I’ve written for this, is available on GitHub, although the wrapper implementation is only partial at present – implementing only the “receive” direction of the packets from the XBee mesh to the USB, meaning from XBee to the Camel Endpoint, in turn to the Camel Consumer, and in turn you’ll have the packets on the Camel routes.

The great thing about this approach, is that you can later latch the Camel routing in a very simple way, thanks to this wrapper:

from("xbeeapi://?baud=9600&tty=/dev/tty.usbserial-A4004CwJ")
	.to("seda:xbeeAsyncBuffer")
	;

from("seda:xbeeAsyncBuffer")
	.choice()
		.when(body().isInstanceOf(ZNetRxIoSampleResponse.class))
			.log("route log ${body.getAnalog1()}")
			.to("ejb:java:global/mpes-core/MpesExpertSystem?method=insert")
		.otherwise()
			.log("I don't know what to do with this packet from the XBee mesh: ${body}")
	;

In this case I’ve used the Camel SEDA to have the two routes asynchronous to each other.

Then it comes the Expert System, AI part. I’ve always been a big fan and used extensively JBoss/RedHat Drools.

The main idea is to be able to write a simple rule, something as the following mock-up:

Screen Shot 2013-06-01 at 15.39.10

In the example picture, the rule should be self-explanatory, as it’s responsible to infer when a fact, representing current and previous status of the “Home Toothbrush” object, has changed from UNDOCKED to DOCKED, where this transition did last for more than 30 seconds.

However, in order to get there, I first still needed to transform the sensor readings in terms of the status object.

So first, I needed to have all XBee analog readings represented as an Event:

declare ZNetRxIoSampleResponse
	@role(event)
end

This way, I see each sensor reading as an Event proper in the CEP (Complex Event Processing) working memory of the Rule Engine.

This, in turns, enable me to write a rule to detect the current status as DOCKED of the toothbrush object:

/*
 * Detect Docked
 * The analog sensor reading for docked is about 1023.
 * The rule shall detect the Home Toothbrush as docked when the average is above 950 including at least 3 analog sensor reading.
 */
rule "Detect Docked"
no-loop 
when
    accumulate ( ZNetRxIoSampleResponse( containsAnalog == true, $analog1 : analog1 ) over window:length( 3 );
    			 $avg : average( $analog1 ),
    			 $count : count( $analog1 );  
    			 $avg > 950 , $count == 3
    )
    $cp : CurStatusPrevStatus( id == "Home Toothbrush" , curStatus != "DOCKED")
then
	$cp.shiftCurIntoPrev();
    $cp.setCurStatus("DOCKED");
    $cp.setCurStatusTs(drools.getWorkingMemory().getSessionClock().getCurrentTime());
    update($cp);
end

In this case I want the toothbrush object set to DOCKED when the average of the last 3 sensor readings is above 950 (this is the converted ADC value from the XBee).

Notice the accumulate function in this case constraints not only on the average, but also on the count: this is important otherwise the sliding-window defined by window:length(3) would also intercept the initial warm-up of the system, when only just one or two sensor reading Event are available in the working memory. I want the status be detected over at least 3 continuous readings.

The rest of the work is really all about Unit testing, testing, and more testing; and then, writing some little more JavaEE code, deploying it on the JBoss AS Container…

…and it works! :)

And you can find the source code, evolving, on GitHub of course.

Why do I blog this

I think there is a lot nowadays revolving around “Internet of Things” that’s just the tip of the iceberg, and to me that’s really all about technologies becoming more and more pervasive in our daily life. Personally, I’m very interested how Expert System can benefit in this scenario, and I find amazing the little hacks you can start to do even at home!!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s