TechDoc: Events and Messages for Smart Spaces

Posted on May 6, 2011

0


All SmartSpaces Object do three things:

  1. Send messages – Which can either be:
    1. A Request for information – Sent to the group
    2. A Response on the Request – Sent back to the Requester
    3. An Event that took place – For others to respond on, but not to respond to
    4. A message – Which can be anything in any internal format and is the basis of all three above
  2. Receive messages – Which can be any of the above
  3. Process messages – Which involves the content of each message and what will be done with what is received.

Sending Messages

Messages currently consists of the following main components:

  1. The message Header – Mainly for the Server. This states:
    1. Who should receive it – A comma-separated tag-list to route the message to anyone who observes these tags.
    2. Who is the sender – Filled in by the Server
    3. Who is the Base Server serving the Sender – Filled in by the SandBox Server the Sender is directly connected to
    4. The message type – Is it a Request, a Response, an Event or a Message?
  2. A separator – This is ASCII code 02, stating “Begin of text”
  3. The Message Body – For you. This can be anything you want in clear text.
  4. A terminator – For some environments a terminator is needed to determine if the bytestream of a message is ended.

Code example

A C# code example

ClientMessage message = new ClientMessage ();

// Define what the message is about and thus: who can receive the message
message.tags= "door opened; switch light on";

message.type=ClientMessage.TYPE_EVENT
message.body="";

// Send it
ApplicationSandBox.sendMessage("my sandbox",message);

// Done

Grouping your tags

You can group events to specify who will receive them further like this:

ClientMessage message = new ClientMessage ();

// Group tags message.tags= "room1{door opened, switch light on};";

message.type=ClientMessage.TYPE_EVENT
message.body="";

// Send it
ApplicationSandBox.sendMessage("my sandbox",message);

// Done

How grouped tags are translated

The Server will split these tags in the code examples above into separate specific events like this:

  • room1_door_opened
  • room1_switch_light_on

When you add more items to the prefix, like this:

  • general, room1{door opened, switch light on}

The Server will split these tags into separate items like this:

  • general_door_opened
  • general_switch_light_on
  • room1_door_opened
  • room1_switch_light_on

Receiving messages

To receive messages you need to do two things:

  1. State which tags in which Sandbox you are observing – Every Message is distributed to other SmartSpace Objects using tags. By telling the SmartSpaces Servers which tags you are listening to, Messages containing those tags will be passed through to you
  2. Add an event listener to the Sandbox Class – As everything within the framework is Event based

Code example – stating what you want to observe where

C#

void defineMyObservations()
{
 // We define what generic tags we want to observe/listen to string tagPackage="room1,room2{light on, light off, door open, door close};"  + "light1,light2{switch on, switch off}";

 // We define the sandbox in which we think it is happening
   string sandBox="my sandbox";

   // When we receive a message,. we can take action
   ApplicationSandBox.observe(sandBox, tagPackage, onMessage);
}
// We use a standard C# event handler
void onMessage(object message, EventArgs arg)
{
   // Do something with the message
}

Adding tags later

You can call this method as many times as you like, adding more tags to observe.

Tag packages, or: how tags are treated

Every time you add a new tag package to the Application Sandbox, a new Tag Package object is created and numbered. The ID of this tag package is sent to the Smart Spaces Server and when any Message passes with one or more items from your Tag Package in its Header, that specific Tag Package is triggered.

Using Specific Tag Packages to separate objects or events

Let’s say you have a house with 4 rooms and you want to observe each room separately. Your tag packages would look like this:

  • tagPackage1 = "room1{light on, light off}"; callBack1 = onRoom1MessageHandler
  • tagPackage2 = "room2{light on, light off}"; callBack2 = onRoom2MessageHandler
  • tagPackage3 = "room3{light on, light off}"; callBack1 = onRoom3MessageHandler
  • tagPackage4 = "room4{light on, light off}"; callBack2 = onRoom4MessageHandler

Each has to be registered separately.

When the event: “room1_light_on” is received, only the event handler onRoom1Message will be triggered.

Having a lot of objects: Using Virtual Objects and the Message Content

The model as described above is working in simple circumstances where the amount of objects is known.

At a certain point you might want to consider leaving the observer Tag Packages simple and move towards using Virtual Objects.

Virtual Objects represent the actual objects on the other side. So, instead of listening to “room1_door_open” you start listening to the representative of “door 1”.

Example of message content for “door 1”

object:door
{
   doorID:123;
   state:closed;
}

Example of using the Door Object

public class Door
{
 // Make us a object pool to inject values in
   private List<Door> doorList=new List<Door>()

 // A door can be open or closed
   public string state="";

 // It has some ID
   public int doorID;

 // We want to know what is was before
   private string previousState="";

 // Then we want to inject random data and make sure we have
   public static void translateMessageBody(string messageBody)
   {
       Door disposableDoor= new Door();
       // Parse the JSON data to a disposable Door object

       // Inject the data in the persistant door Object we use
       injectData(disposableDoor); 

   }

   public static void injectData(Door disposableDoor)
   {
       Door myDoor=getDoor(disposableDoor.doorID)

       // Copy the values form the disposable object
       // See if this triggered anything
       if(myDoor.previousState != myDoor.state)
       {
            // Door is opened or closed since last time!  // Dispatch Event
       }
   }

   public static Door getDoor(int doorID)
   {
      // Do some magic to find the door according to the given ID
      Door doorFromPool=someMagic(doorID)
 // Return that door
      return doorFromPool;
   }
}
Advertisements
Posted in: techdoc