Unknown macro: {style}

.ia-secondary-container

Unknown macro: { margin}
Unknown macro: {div}
Kaa releases
Unknown macro: {div}
Shortcuts

Page tree
Skip to end of metadata
Go to start of metadata

The Kaa event subsystem enables messages delivery across the endpoints (EP). Events can be thought of as commands or structured chunks of data. For example, an event from a smartphone application can toggle the lights in the room.

Structure of the data carried by events is defined by an Event Class (EC) data schema configured on the Kaa server and built into Kaa SDK. ECs are grouped into Event Class Families (ECF) by the topic. Kaa allows delivering events among EPs that belong to the same or different applications. As of Kaa r0.6, endpoints must be associated with the same user in order to be able to send events to each other. Please review the events system design reference for more background.

From this guide you will learn how to use Kaa events functionality for enabling communication across the endpoints.

Configuring Kaa

This section provides guidance on how to configure ECFs in Kaa.

Creating ECFs

ECFs are shared between applications and there is no default ECFs created automatically. A tenant admin can create multiple ECFs on the Kaa server using the Admin UI or REST API.

In this guide, we will use the following ECF that allows you to remotely control a thermostat using your cell phone.

[  
    {  
        "namespace":"org.kaaproject.kaa.schema.sample.thermo",
        "type":"record",
        "classType":"event",
        "name":"ThermostatInfoRequest",
        "fields":[  

        ]
    },
    {  
        "namespace":"org.kaaproject.kaa.schema.sample.thermo",
        "type":"record",
        "classType":"object",
        "name":"ThermostatInfo",
        "fields":[  
            {  
                "name":"currentTemperature",
                "type":"int"
            },
            {  
                "name":"targetTemperature",
                "type":"int"
            }
        ]
    },
    {  
        "namespace":"org.kaaproject.kaa.schema.sample.thermo",
        "type":"record",
        "classType":"event",
        "name":"ThermostatInfoResponse",
        "fields":[  
            {  
                "name":"thermostatInfo",
                "type":"org.kaaproject.kaa.schema.sample.thermo.ThermostatInfo"
            }
        ]
    },
    {  
        "namespace":"org.kaaproject.kaa.schema.sample.thermo",
        "type":"record",
        "classType":"event",
        "name":"ChangeTemperatureCommand",
        "fields":[  
            {  
                "name":"temperature",
                "type":"int"
            }
        ]
    }
]

 

Application mapping

Our sample ECF contains three events: ThermostatInfoRequestThermostatInfoResponse and ChangeTemperatureCommand. We will create the following two applications in this guide: Controller and Thermostat. It is logical that Controller should be able to send the ThermostatInfoRequest event (act as a source) and receive the ThermostatInfoResponse event (act as a sink), while Thermostat should be able to send the ThermostatInfoResponse event and receive the ThermostatInfoResponse event. Based on such logic of our application, we will create the following application mapping for our sample ECF:

ApplicationThermostatInfoRequestThermostatInfoResponseChangeTemperatureCommand
Controllersourcesinksource
Thermostatsinksourcesink

A tenant admin can set up application mapping using the Admin UI or REST API.

Generating SDK

During the SDK generation, the Control server generates the event object model and extends APIs to support methods for sending events and registering event listeners. An application SDK can support multiple ECFs. However, it cannot simultaneously support multiple versions of the same ECF.

Coding

This section provides code samples which illustrate practical usage of events in Kaa. The event subsystem API varies depending on the target SDK platform, but the general approach is the same.

Attach endpoint to user

To enable sending/receiving events to/from endpoints, at first the client should attach the endpoint to the user as shown in the following screenshot.

Java
import org.kaaproject.kaa.client.KaaClient;
import org.kaaproject.kaa.client.KaaDesktop;
import org.kaaproject.kaa.client.event.registration.EndpointRegistrationManager;
import org.kaaproject.kaa.client.event.registration.UserAuthResultListener;
 
EndpointRegistrationManager registrationManager = kaaClient.getEndpointRegistrationManager();
 
registrationManager.attachUser("userExternalId", "userAccessToken", new UserAuthResultListener()
{
    @Override
    public void onAuthResult(UserAttachResponse response) {
        System.out.println("Attach response" + response.getResult());
    }
});
C++
#include <memory>

#include <kaa/Kaa.hpp>
#include <kaa/IKaaClient.hpp>
#include <kaa/event/registration/IEndpointAttachStatusListener.hpp>
using namespace kaa;
class DummyEndpointAttachStatusListener : public IEndpointAttachStatusListener
{
public:
    virtual void onAttachSuccess(const std::string& userExternalId, const std::string& endpointAccessToken) {
        // Some code
    }
    virtual void onAttachFailure() {
        // Some code
    }
    virtual void onDetachSuccess(const std::string& endpointAccessToken) {
        // Some code
    }
    virtual void onDetachFailure() {
        // Some code
    }
};
...
Kaa::start();
IKaaClient& kaaClient = Kaa::getKaaClient();
IEndpointRegistrationManager& registrationManager = kaaClient.getEndpointRegistrationManager();
...
std::unique_ptr<IEndpointAttachStatusListener> listener(new DummyEndpointAttachStatusListener);
registrationManager.attachUser("userExternalId", "userAccessToken", listener.get());
C
#include <kaa.h>

void kaa_sdk_on_user_attached(KAA_BOOL is_attached)
{
	// Process the "user attach" response
}
...
kaa_set_user_attached_callback(&kaa_sdk_on_user_attached);
kaa_attach_to_user("userExternalId", "userAccessToken");

 

Get ECF factory and create ECF object

To access the Kaa event functionality, the client should implement the two following blocks of code.

Get ECF factory from Kaa

Java
import org.kaaproject.kaa.client.event.EventFamilyFactory;
 
EventFamilyFactory eventFamilyFactory = kaaClient.getEventFamilyFactory();
C++
#include <kaa/event/gen/EventFamilyFactory.hpp>
 
EventFamilyFactory& eventFamilyFactory = kaaClient.getEventFamilyFactory();

Get specific ECF object from ECF factory

Java
import org.kaaproject.kaa.demo.smarthouse.thermo.ThermoEventClassFamily;
 
ThermoEventClassFamily tecf = eventFamilyFactory.getThermoEventClassFamily();
C++
#include <kaa/event/gen/ThermoEventClassFamily.hpp>
 
ThermoEventClassFamily& tecf = eventFamilyFactory.getThermoEventClassFamily();

Send events

To send one or more events, the client should proceed as described in this section.

Get endpoint addresses

Execute the asynchronous findEventListeners method to request a list of the endpoints supporting all specified EC FQNs (FQN stands for fully qualified name).

 

Java
import org.kaaproject.kaa.client.event.EventListenersResolver;
import org.kaaproject.kaa.client.event.FetchEventListeners;
 
List<String> FQNs = new LinkedList<>();
FQNs.add("org.kaaproject.kaa.schema.sample.thermo.ThermostatInfoRequest");
FQNs.add("org.kaaproject.kaa.schema.sample.thermo.ChangeTemperatureCommand");

EventListenersResolver eventListenersResolver = kaaClient.getEventListenerResolver();

eventListenersResolver.findEventListeners(FQNs, new FetchEventListeners() {
    @Override
    public void onRequestFailed() {
        // Some code
    }
    @Override
    public void onEventListenersReceived(List<String> eventListeners) {
        // Some code
    }
});
C++
#include <kaa/event/IFetchEventListeners.hpp>
#include <kaa/event/IEventListenersResolver.hpp>
 
class DummyFetchEventListeners : public IFetchEventListeners
{
    virtual void onEventListenersReceived(const std::vector<std::string>& eventListeners) {
        // Some code
    }
    virtual void onRequestFailed() {
        // Some code
    }
};
...
IEventListenersResolver& eventListenersResolver = kaaClient.getEventListenersResolver();
...
std::list<std::string> FQNs = {"org.kaaproject.kaa.schema.sample.thermo.ThermostatInfoRequest"
                              ,"org.kaaproject.kaa.schema.sample.thermo.ChangeTemperatureCommand"};
std::unique_ptr<IFetchEventListeners> fetchEventListener(new DummyFetchEventListeners);

eventListenersResolver.findEventListeners(FQNs, fetchEventListener.get());

Send one event to all endpoints

To send an event to all endpoints which were previously located by the findEventListeners method, execute the sendEventToAll method upon the specific ECF object.

Java
import org.kaaproject.kaa.schema.sample.thermo.ThermostatInfoRequest;
 
tecf.sendEventToAll(new ThermostatInfoRequest());
C++
#include <kaa/event/gen/ThermoEventClassFamilyGen.hpp>
 
nsThermoEventClassFamily::ThermostatInfoRequest thermoRequest;
tecf.sendEventToAll(thermoRequest);
C
#include <event/kaa_thermo_event_class_family.h>
 
kaa_thermo_event_class_family_thermostat_info_request_t thermo_request;
kaa_send_kaa_thermo_event_class_family_thermostat_info_request(&thermo_request, NULL, 0);

Send one event to one endpoint

To send an event to a single endpoint which was previously located by the findEventListeners method, execute the sendEvent method upon the specific ECF object and this endpoint.

Java
import org.kaaproject.kaa.schema.sample.thermo.ChangeTemperatureCommand;
 
ChangeTemperatureCommand cdc = new ChangeTemperatureCommand(-30);
// Assume the target variable is one of the received in the findEventListeners method
tecf.sendEvent(cdc, target);
C++
#include <kaa/event/gen/ThermoEventClassFamilyGen.hpp>
 
nsThermoEventClassFamily::ChangeTemperatureCommand cdc;
cdc.temperature = -30;
 
// Assume the target variable is one of the received in the findEventListeners method
tecf.sendEvent(cdc, target);
C
#include <event/kaa_thermo_event_class_family.h>
 
kaa_thermo_event_class_family_change_temperature_command_t cdc;
cdc.temperature = -30;
kaa_send_kaa_thermo_event_class_family_change_temperature_command(&cdc, "home_thermostat", 15);

Send batch of events to endpoint(s)

To send a batch of events at once to a single or all endpoints, execute the following code.

Java
import org.kaaproject.kaa.client.event.EventFamilyFactory;
import org.kaaproject.kaa.demo.smarthouse.thermo.ThermoEventClassFamily;
import org.kaaproject.kaa.schema.sample.thermo.ThermostatInfoRequest;
import org.kaaproject.kaa.schema.sample.thermo.ChangeTemperatureCommand;


// Get instance of EventFamilyFactory
EventFamilyFactory eventFamilyFactory = kaaClient.getEventFamilyFactory();
ThermoEventClassFamily tecf = eventFamilyFactory.getThermoEventClassFamily();
 
// Register a new event block and get a unique block id
TransactionId trxId = eventFamilyFactory.startEventsBlock();


// Add events to the block
// Adding a broadcasted event to the block
tecf.addEventToBlock(trxId, new ThermostatInfoRequest());
// Adding a targeted event to the block
tecf.addEventToBlock(trxId, new ChangeTemperatureCommand(-30), "home_thermostat");


// Send added events in a batch
eventFamilyFactory.submitEventsBlock(trxId);
// Dismiss the event batch (if the batch was not submitted as shown in the previous line)
eventFamilyFactory.removeEventsBlock(trxId);
 
C++
#include <kaa/Kaa.hpp>
#include <kaa/IKaaClient.hpp>
#include <kaa/event/gen/EventFamilyFactory.hpp>
#include <kaa/event/gen/ThermoEventClassFamily.hpp>
#include <kaa/event/gen/ThermoEventClassFamilyGen.hpp>

using namespace kaa;

// Get an instance of EventFamilyFactory
EventFamilyFactory &eventFamilyFactory = Kaa::getClient().getEventFamilyFactory();
ThermoEventClassFamily & tecf = eventFamilyFactory.getThermoEventClassFamily();

// Register a new event block and get a unique block id
TransactionIdPtr trxId = eventFamilyFactory.startEventsBlock();

// Add events to the block
// Adding a broadcasted event to the block
nsThermoEventClassFamily::ThermostatInfoRequest thermoRequest;
tecf.addEventToBlock(trxId, thermoRequest);
// Adding a targeted event to the block
nsThermoEventClassFamily::ChangeTemperatureCommand cdc;
cdc.temperature = -30;
tecf.addEventToBlock(trxId, cdc, "home_thermostat");


// Send added events in a batch
eventFamilyFactory.submitEventsBlock(trxId);
// Dismiss the event batch (if the batch was not submitted as shown in the previous line)
eventFamilyFactory.removeEventsBlock(trxId);
 
С
#include <kaa.h>
#include <event/kaa_thermo_event_class_family.h>

// Register a new event block and get a unique block id
kaa_trx_id trx_id = kaa_start_event_block();

// Add events to the block
// Adding a broadcasted event to the block
kaa_thermo_event_class_family_thermostat_info_request_t thermo_request;
kaa_add_kaa_thermo_event_class_family_thermostat_info_request_event_to_block(&thermo_request, NULL, 0, trx_id);
// Adding a targeted event to the block
kaa_thermo_event_class_family_change_temperature_command_t cdc;
cdc.temperature = -30;
kaa_add_kaa_thermo_event_class_family_change_temperature_command_event_to_block(&cdc, "home_thermostat", 15, trx_id);


// Send added events in a batch
kaa_send_event_block(trx_id);
// Dismiss the event batch (if the batch was not submitted as shown in the previous line)
kaa_remove_event_block(trx_id);

Receive events

To start listening to incoming events, execute the addListener method upon the specific ECF object.

Java
import org.kaaproject.kaa.demo.smarthouse.thermo.ThermoEventClassFamily;
 
tecf.addListener(new ThermoEventClassFamily.DefaultEventFamilyListener() {
    @Override
    public void onEvent(ChangeTemperatureCommand arg0, String arg1) {
        // Some code
    }
    @Override
    public void onEvent(ThermostatInfoResponse arg0, String arg1) {
        // Some code
    }
    @Override
    public void onEvent(ThermostatInfoRequest arg0, String arg1) {
        // Some code
    }
});
C++
#include <kaa/event/gen/ThermoEventClassFamilyGen.hpp>
 
class DummyThermoEventClassFamilyListener: public ThermoEventClassFamily::ThermoEventClassFamilyListener
{
public:
    virtual void onEvent(const nsThermoEventClassFamily :: ThermostatInfoRequest& event, const std::string& source) {
        // Some code
    }
    virtual void onEvent(const nsThermoEventClassFamily :: ThermostatInfoResponse& event, const std::string& source) {
        // Some code
    }
    virtual void onEvent(const nsThermoEventClassFamily :: ChangeTemperatureCommand& event, const std::string& source) {
        // Some code
    }
};
...
std::unique_ptr< ThermoEventClassFamily::ThermoEventClassFamilyListener> eventsListener(new DummyThermoEventClassFamilyListener);
tecf.addEventFamilyListener(eventsListener.get());
С
#include <kaa_mem.h>
#include <event/kaa_thermo_event_class_family.h>
 
void on_thermostat_info_response(kaa_thermo_event_class_family_thermostat_info_response_t *r)
{
    // Process the response
	...
    // Deallocate the event data
    r->destruct(r);
    KAA_FREE(r);
}
 
set_kaa_thermo_event_class_family_thermostat_info_response_listener(&on_thermostat_info_response);

Copyright © 2014, CyberVision, Inc.

  • No labels