Skip to main content
Jump to: navigation, search

Difference between revisions of "OM2M/Developer"

(Test Scenario)
(The IPU Monitor class)
Line 161: Line 161:
 
      
 
      
 
     public void start () {
 
     public void start () {
 
System.out.println("Hello World!!");
 
LOGGER.info("Lamp waiting for attachement..");
 
 
 
 
// Create initial resources for the sensor
 
// Create initial resources for the sensor
 
String lampId = "lamp_0";  
 
String lampId = "lamp_0";  
    createLampResources(lampId, false, APOCPATH);
+
        createLampResources(lampId, false, APOCPATH);
  
   
+
        // Create initial resources for the sensor
LOGGER.info("sensors waiting for attachement..");
+
        String sensorId = "sensor_0";
+
        createSensorResources(sensorId, APOCPATH);
    // Create initial resources for the sensor
+
    String sensorId = "sensor_0";
+
    createSensorResources(sensorId, APOCPATH);
+
 
      
 
      
  

Revision as of 10:26, 22 September 2014

Prerequisite

  • Eclipse kepler (for RCP and RAP Developers).
  • To build the OM2M project into Eclipse, a Tycho m2e connector is needed. Installation of m2e connectors is accomplished as follows: click Window -> Preferences -> maven -> discovery -> open catalog and type Tycho. Check the “Tycho Configurator” checkbox.
Git clone

Build OM2M from source using Eclipse

Clone The OM2M project

  • Select Windiow->Show View -> Other .
  • In the dialog box, select the Git view.
  • Click on “Clone a Git repository”.
Git clone
  • In the second page, keep the “master” branch checkbox selected and click Next.
Git clone
  • In the third page, check the “clone submodules” and “import all existing projects after clone finishes” and click “Finish”.
Git clone
  • The OM2M project is now cloned and is visible on the Git repositories’ and Package’ explorers.
  • Now we will add the required libraries. This step will be removed when all third libraries will be validated by Eclipse.
  • Download the libraries from this link: http://wiki.eclipse.org/OM2M/Download
  • Extract OM2M-libs and add the following libraries to "org.eclipse.om2m" repository as follows:
    • "db4o-core-java5-8.1-SNAPSHOT.jar" library under "org.eclipse.om2m.core\libs",
    • "obix.jar" library under "org.eclipse.om2m.commons\libs",
    • "xsd" folder under "org.eclipse.om2m.commons\src\main\resources".

Build OM2M using maven

  • Select “org.eclipse.om2m” package and right click. Select “Run as -> maven install”.
  • Two Eclipse products will be generated after a successful built:
    • The NSCL product can be found on this directory: "om2m/org.eclipse.om2m/org.eclipse.om2m.site.nscl/target/products/nscl/<os>/<ws>/<arch>"
    • The GSCL product can be found on this directory: "om2m/org.eclipse.om2m/org.eclipse.om2m.site.gscl/target/products/gscl/<os>/<ws>/<arch>"

Develop a new plug-in

Create a new plug-in project

  • Create a new plug-in project called org.eclipse.om2m.sample.ipu via File → New → Other → Plug-in Project.
  • Enter the data as depicted in the following screenshots.
create a plug-in project: step 1
create a plug-in project: step 2
  • Uncheck the Create a plug-in using one of the templates checkbook and press the Finish button.
create a plug-in project: step 3
  • As result the following project is created.
sample ipu plug-in

Convert the plugin into maven project

  • Open the build.properties file in XML and update the src attributes as depicted in the following figure.
build-properties build
  • Select the created plug-in "org.eclipse.om2m.sample.ipu" → right click → configure → maven to maven project.
  • Enter the data as illustrated in the following and press the Finish button.
maven conversion: POM edition
  • Once the plug-in is converted, open the pom.xml file to edit the parent filed.
  • Click on "select Parent" icon and enter "org.eclipse.om2m" in the "Enter groupId, artifactId or sh1 prefix or pattern" field.
  • Select "org.om2m.eclipse" and press ok.
maven conversion: Parent edition
  • We end this step by updating the plug-inf project. For this, select the "org.eclipse.om2m.sample.ipu" project → maven → update project.

Add the plugin as a maven module to the OM2M parent project

  • In this part, we will add the created plug-in as a module to the om2m platform:
    • Open the pom file of the org.eclipse.om2m package.
    • Go to the modules tab and press Add button.
    • Select the org.eclipse.ipu.om2m.sample.ipu plug-in and press ok.
    • Build the om2m package and its sub-projects. To do this, select the "om2m.org.eclipse" package → right click → Run as → maven install.
    • Check the org.eclipse.om2m.sample.ipu was successfully built. At the buid end, we should get this result.
om2m build
  • Remark: To keep the same display pattern for all the platform' plugins, you can add description and name tags to the org.eclipse.om2m.sample.ipu' pom.xml file.
<project>
......
  <name>org.eclipse.om2m :: sample ipu</name>
  <description>org.eclipse.om2m :: sample ipu</description>
.....
</project>

Add the plugin to the OM2M product(s)

  • The final step consists of adding the created plug-in to one of om2m platform products, i.e the gscl or the nscl executable. In the following, we choose to add the org.eclipse.om2m.sample.ipu plug-in to the gscl product:
  • select the org.eclipse.om2m.site.gscl package.
  • open the om2m.product file.
  • Press Add button and Type org.eclipse.om2m.sample.ipu
  • Click on ok button and save.
  • Build the om2m package and its sub-projects: select the "om2m.org.eclipse" package -> right click -> Run as -> maven install.
  • To check that the "org.eclipse.om2m.sample.ipu" was successfully added to the gscl product, run the gscl and verify in the console if the "org.eclipse.om2m.sample.ipu" is displayed.
gscl product

The IPU Monitor

The IPU Monitor class

In the following, we give a snippet of the IpuMonitor class which perform the creation of the required M2M resources on the gscl resource tree to enable simulated M2M devices monitoring. The org.eclipse.om2m.sample.ipu.IpuMonitor class locally triggers the SCLService.doRequest method to create applications, containers, and contentInstances resources on the gateway. In this tutorial, we create sensor_0 and lamp_0 application and each one has two containers: Descriptor to store the lamp/ sensor description and Data to store lamp/ senor measured values. We simulate a sensor that sends data every two seconds. This is performed by creating a new sensor_0 Data' contentInstance for each publication.


package org.eclipse.om2m.sample.ipu;
 
 
import obix.Bool;
import obix.Contract;
import obix.Obj;
import obix.Op;
import obix.Str;
import obix.Uri;
import obix.io.ObixEncoder;
 
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.om2m.commons.resource.Application;
import org.eclipse.om2m.commons.resource.ContentInstance;
import org.eclipse.om2m.commons.resource.StatusCode;
import org.eclipse.om2m.commons.resource.Container;
import org.eclipse.om2m.commons.rest.RequestIndication;
import org.eclipse.om2m.commons.rest.ResponseConfirm;
import org.eclipse.om2m.core.service.SclService;
 
 
 
 
public class IpuMonitor {
	 /** Logger */
    private static Log LOGGER = LogFactory.getLog(IpuMonitor.class);
    /** Sclbase id */
    public final static String SCLID = System.getProperty("org.eclipse.om2m.sclBaseId","");
    /** Admin requesting entity */
    static String REQENTITY = System.getProperty("org.eclipse.om2m.adminRequestingEntity","");
    /** Generic create method name */
    public final static String METHOD_CREATE = "CREATE";
    /** Generic execute method name */
    public final static String METHOD_EXECUTE = "EXECUTE";
    /** State container id */
    public final static String DATA = "DATA";
    /** Descriptor container id */
    public final static String DESC = "DESCRIPTOR";
    /** Discovered SCL service*/
    static SclService SCL;
    public final static String APOCPATH = "ipu";
    /**
     * Constructor
     * @param scl - discovered SCL
     */
 
    public IpuMonitor(SclService scl) {
        SCL=scl;
    }
 
    public void start () {
 
	// Create initial resources for the sensor
	String lampId = "lamp_0"; 
        createLampResources(lampId, false, APOCPATH);
 
         // Create initial resources for the sensor
         String sensorId = "sensor_0";
        createSensorResources(sensorId, APOCPATH);
 
 
 
 
}  
    /**
     * Creates all required resources.
     * @param appId - Application ID
     * @param aPoCPath - sensor aPocPath
     */
 
 public void createSensorResources(String appId, String aPoCPath) {
        // Create the Application resource
        ResponseConfirm response = SCL.doRequest(new RequestIndication(METHOD_CREATE,SCLID+"/applications",REQENTITY,new Application(appId,aPoCPath)));
        // Create Application sub-resources only if application not yet created
            // Create DESCRIPTOR container sub-resource
            SCL.doRequest(new RequestIndication(METHOD_CREATE,SCLID+"/applications/"+appId+"/containers",REQENTITY,new Container(DESC)));
            // Create STATE container sub-resource
            SCL.doRequest(new RequestIndication(METHOD_CREATE,SCLID+"/applications/"+appId+"/containers",REQENTITY,new Container(DATA)));
 
            String content, targetID;
            // Create DESCRIPTION contentInstance on the DESCRIPTOR container resource
            content = Sensor.getDescriptorRep(SCLID, appId, DATA, aPoCPath);
            targetID= SCLID+"/applications/"+appId+"/containers/"+DESC+"/contentInstances";
            SCL.doRequest(new RequestIndication(METHOD_CREATE,targetID,REQENTITY,new ContentInstance(content.getBytes())));
 
            while (true) {
 
            // Create initial contentInstance on the STATE container resource
            int initValue = 10 + (int)(Math.random()*100); 
            content = Sensor.getStateRep(appId, initValue);
            targetID = SCLID+"/applications/"+appId+"/containers/"+DATA+"/contentInstances";
            SCL.doRequest(new RequestIndication(METHOD_CREATE,targetID,REQENTITY,new ContentInstance(content.getBytes())));
 
            try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
            }
    }
 
 
 /**
     * Creates all required resources.
     * @param appId - Application ID
     * @param initValue - initial lamp value
     * @param aPoCPath - lamp aPocPath
     */
 
 public void createLampResources(String appId, boolean initValue, String aPoCPath) {
        // Create the Application resource
        ResponseConfirm response = SCL.doRequest(new RequestIndication(METHOD_CREATE,SCLID+"/applications",REQENTITY,new Application(appId,aPoCPath)));
        // Create Application sub-resources only if application not yet created
        if(response.getStatusCode().equals(StatusCode.STATUS_CREATED)) {
            // Create DESCRIPTOR container sub-resource
            SCL.doRequest(new RequestIndication(METHOD_CREATE,SCLID+"/applications/"+appId+"/containers",REQENTITY,new Container(DESC)));
            // Create STATE container sub-resource
            SCL.doRequest(new RequestIndication(METHOD_CREATE,SCLID+"/applications/"+appId+"/containers",REQENTITY,new Container(DATA)));
 
            String content, targetID;
            // Create DESCRIPTION contentInstance on the DESCRIPTOR container resource
            content = Lamp.getDescriptorRep(SCLID, appId, DATA, aPoCPath);
            targetID= SCLID+"/applications/"+appId+"/containers/"+DESC+"/contentInstances";
            SCL.doRequest(new RequestIndication(METHOD_CREATE,targetID,REQENTITY,new ContentInstance(content.getBytes())));
 
            // Create initial contentInstance on the STATE container resource
            content = Lamp.getStateRep(appId, initValue);
            targetID = SCLID+"/applications/"+appId+"/containers/"+DATA+"/contentInstances";
            SCL.doRequest(new RequestIndication(METHOD_CREATE,targetID,REQENTITY,new ContentInstance(content.getBytes())));
        }
    }
 
 /**
     * Creates a ContentInstance resource on STATE container.
     * @param lampId - Application ID
     * @param value - measured state
     */
    public static void createContentResource(String lampId, boolean value) {
        // Creates lampCI with new State
        String content = Lamp.getStateRep(lampId, value);
        String targetID = SCLID+"/applications/"+lampId+"/containers/"+DATA+"/contentInstances";
        SCL.doRequest(new RequestIndication(METHOD_CREATE,targetID,REQENTITY,new ContentInstance(content.getBytes())));
    }
 
    /**
     * Sets the lamp state.
     * @param appId - Application ID
     * @param value - measured state
     */
 
    public static void setLampState(final String appId, String value) {
        final boolean newState;
        boolean currentState = Lamp.getState(appId);
        String str = Boolean.toString(currentState);
        if(value.equals(str)) {
            newState = !currentState;
            createContentResource(appId, newState);
        } else {
            newState = Boolean.parseBoolean(value);
            // Create the CI in the case when the newState is different to the Current Lamp State
            if (newState != currentState) {
                createContentResource(appId, newState);
            }
        }
        //Lamps.LAMPS_STATES.set(index, newState);
        Lamp.setState(newState);
    }
 
 
}

You notice that when creating a contentInstance of a Desccriptor/ Data Container we use getDescriptorRep getSateRep methods of the Sensor/ Lamp classes. In the following, we give a snippet of these latter.

The Sensor class

The sensor class allows us to manage a sensor by recovering its description, and its state.

package org.eclipse.om2m.sample.ipu;
 
import obix.Contract;
import obix.Obj;
import obix.Op;
import obix.Str;
import obix.Uri;
import obix.io.ObixEncoder;
 
public class Sensor {
 
	/**
     * Returns an obix XML representation describing the lamp.
     * @param sclId - SclBase id
     * @param appId - Application Id
     * @param stateCont - the STATE container id
     * @return Obix XML representation
     */
    public static String getDescriptorRep(String sclId, String appId, String stateCont, String aPoCPath) {
 
        // oBIX
        Obj obj = new Obj();
        obj.add(new Str("type", "Sensor"));
        obj.add(new Str("location","Home"));
        obj.add(new Str("appId",appId));
        // OP GetState from SCL DataBase
        Op opState = new Op();
        opState.setName("getState");
        opState.setHref(new Uri(sclId+"/"+"applications/"+appId+"/containers/"+stateCont+"/contentInstances/latest/content"));
        opState.setIs(new Contract("retrieve"));
        opState.setIn(new Contract("obix:Nil"));
        opState.setOut(new Contract("obix:Nil"));
        obj.add(opState);
        // OP GetState from SCL IPU
        Op opStateDirect = new Op();
        opStateDirect.setName("getState(Direct)");
        opStateDirect.setHref(new Uri(sclId+"/"+"applications/"+appId+"/"+aPoCPath));
        opStateDirect.setIs(new Contract("retrieve"));
        opStateDirect.setIn(new Contract("obix:Nil"));
        opStateDirect.setOut(new Contract("obix:Nil"));
        obj.add(opStateDirect);
 
        return ObixEncoder.toString(obj);
    }
 
    /**
     * Returns an obix XML representation describing the current state.
     * @param appId - Application Id
     * @param value - current sensor state
     * @return Obix XML representation
     */
 
    public static String getStateRep(String appId, int value) {
        // oBIX
        Obj obj = new Obj();
        obj.add(new Str("type","sensor"));
        obj.add(new Str("location","Home"));
        obj.add(new Str("appId",appId));
        String strValue = Integer.toString(value);
        obj.add(new Str("state",strValue));
        return ObixEncoder.toString(obj);
 
    }
 
 
}

The Lamp class

The Lamp class allows us to manage a lamp by recovering its description, and its state.

package org.eclipse.om2m.sample.ipu;
 
import obix.Bool;
import obix.Contract;
import obix.Obj;
import obix.Op;
import obix.Str;
import obix.Uri;
import obix.io.ObixEncoder;
 
 
public class Lamp {
	 /** Lamp state */
    private static boolean state = false;
 
 
	 /**
     * Returns an obix XML representation describing the current state.
     * @param appId - Application Id
     * @param value - current lamp state
     * @return Obix XML representation
     */
 
	public static String getStateRep(String appId, boolean initValue) {
		// oBIX
        Obj obj = new Obj();
        obj.add(new Str("type","LAMP"));
        obj.add(new Str("location","Kitchen"));
        obj.add(new Str("appId",appId));
        obj.add(new Bool("state",initValue));
        return ObixEncoder.toString(obj);
	}
 
	public static String getDescriptorRep(String sclId, String appId, String stateCont, String aPoCPath) {
        // oBIX
        Obj obj = new Obj();
        obj.add(new Str("type", "LAMP"));
        obj.add(new Str("location","Home"));
        obj.add(new Str("appId",appId));
        // OP GetState from SCL DataBase
        Op opState = new Op();
        opState.setName("getState");
        opState.setHref(new Uri(sclId+"/"+"applications/"+appId+"/containers/"+stateCont+"/contentInstances/latest/content"));
        opState.setIs(new Contract("retrieve"));
        opState.setIn(new Contract("obix:Nil"));
        opState.setOut(new Contract("obix:Nil"));
        obj.add(opState);
        // OP GetState from SCL IPU
        Op opStateDirect = new Op();
        opStateDirect.setName("getState(Direct)");
        opStateDirect.setHref(new Uri(sclId+"/"+"applications/"+appId+"/"+aPoCPath));
        opStateDirect.setIs(new Contract("retrieve"));
        opStateDirect.setIn(new Contract("obix:Nil"));
        opStateDirect.setOut(new Contract("obix:Nil"));
        obj.add(opStateDirect);
 
        return ObixEncoder.toString(obj);
    }
 
	 /**
     * Gets lampState
     * @return lampState
     */
    public static boolean getState(String lampId) {
        return state;
    }
 
    /**
     * Sets lampState
     */
    public static void setState(boolean state) {
        Lamp.state = state;
    }
 
}

The IPU contoller

The org.eclipse.om2m.sample.ipu.IpuController implements the IpuService interface to enable communications from SCL to the org.eclipse.om2m.sample.ipu plug-in.

For each Retrieve request, we have to extract the application identifier (appId) from the requestIndication targetID attribute. Then extarct type and index from appId based on the appId template <type>_<index>.

For each Execute request we have to extract the application appId and the action value from the requestIndication targetID.


package org.eclipse.om2m.sample.ipu;
 
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.om2m.commons.resource.ErrorInfo;
import org.eclipse.om2m.commons.resource.StatusCode;
import org.eclipse.om2m.commons.rest.RequestIndication;
import org.eclipse.om2m.commons.rest.ResponseConfirm;
import org.eclipse.om2m.ipu.service.IpuService;
 
 
 
public class IpuController implements IpuService {
	public final static String APOCPATH = "ipu";
	private static Log LOGGER = LogFactory.getLog(IpuController.class);
 
 
 
	public ResponseConfirm doExecute(RequestIndication requestIndication) {
		 String[] info = requestIndication.getTargetID().split("/");
	        String lampId = info[info.length-3];
	        String type = lampId.split("_")[0];
	        String value = info[info.length-1];
	        try {
	            if(type.equals("lamp")) {
	                IpuMonitor.setLampState(lampId, value);
	                return new ResponseConfirm(StatusCode.STATUS_OK);
	            } else{
	                return new ResponseConfirm(StatusCode.STATUS_NOT_FOUND,type+" Not found");
	            }
	        } catch (Exception e) {
	            LOGGER.error("IPU Lamp Error",e);
	            return new ResponseConfirm(StatusCode.STATUS_NOT_IMPLEMENTED,"IPU Lamp Error");
	        }
	}
 
 
	public ResponseConfirm doRetrieve(RequestIndication requestIndication) {
		 String[] info = requestIndication.getTargetID().split("/");
	        String appId = info[info.length-2];
	        String type= appId.split("_")[0];
	        int contvalue;
	        boolean value;
	        String content=null; 
	        try {
	        	if (type.equals("sensor")){
	            // Get a random Value for the sensor
	        	contvalue = 10 + (int)(Math.random()*100); 
	        	content = Sensor.getStateRep(appId, contvalue);
	        	}
	        	else if (type.equals("lamp")){
	        		 // Get the boolean Value for the lamp
	        		value = Lamp.getState(appId);
	        		content = Lamp.getStateRep(appId, value);
	        	}
	        	return new ResponseConfirm(StatusCode.STATUS_OK,content);	
	        } catch (Exception e) {
	            LOGGER.error("Hello sample Error",e);
	            return new ResponseConfirm(StatusCode.STATUS_NOT_IMPLEMENTED,"IPU Sample Error" );
	        }
	}
 
 
	public ResponseConfirm doUpdate(RequestIndication requestIndication) {
		return new ResponseConfirm(new ErrorInfo(StatusCode.STATUS_NOT_IMPLEMENTED,requestIndication.getMethod()+" Method not Implemented"));
	}
 
 
	public ResponseConfirm doDelete(RequestIndication requestIndication) {
		return new ResponseConfirm(new ErrorInfo(StatusCode.STATUS_NOT_IMPLEMENTED,requestIndication.getMethod()+" Method not Implemented"));
	}
 
 
	public ResponseConfirm doCreate(RequestIndication requestIndication) {
		 return new ResponseConfirm(new ErrorInfo(StatusCode.STATUS_NOT_IMPLEMENTED,requestIndication.getMethod()+" Method not Implemented"));
	}
 
 
	public String getAPOCPath() {
		// TODO Auto-generated method stub
		return APOCPATH;
	}
 
}

The IPU Activator

This class customizes the starting and stopping of a the org.eclipse.om2m.sample.ipu plug-in.


package org.eclipse.om2m.sample.ipu;
 
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.om2m.core.service.SclService;
import org.eclipse.om2m.ipu.service.IpuService;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.ServiceTracker;
 
 
 
public class Activator implements BundleActivator {
 
	/*
	 * (non-Javadoc)
	 * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
	 */
 
	 /** Logger */
    private static Log logger = LogFactory.getLog(Activator.class);
    /** SCL service tracker */
    private ServiceTracker<Object, Object> sclServiceTracker;
 
	public void start(BundleContext  context) throws Exception {
 
		logger.info("Register IpuService..");
        context.registerService(IpuService.class.getName(), new IpuController(), null);
        logger.info("IpuService is registered.");
 
        sclServiceTracker = new ServiceTracker<Object, Object>(context, SclService.class.getName(), null) {
            public void removedService(ServiceReference<Object> reference, Object service) {
                logger.info("SclService removed");
            }
 
            public Object addingService(ServiceReference<Object> reference) {
                logger.info("SclService discovered");
                SclService sclService = (SclService) this.context.getService(reference);
                final IpuMonitor IpuMonitor = new IpuMonitor(sclService);
                new Thread(){
                    public void run(){
                        try {
                            IpuMonitor.start();
                        } catch (Exception e) {
                            logger.error("IpuMonitor error", e);
                        }
                    }
                }.start();
                return sclService;
            }
        };
        sclServiceTracker.open();
    }
	/*
	 * (non-Javadoc)
	 * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
	 */
	public void stop(BundleContext context) throws Exception {
		System.out.println("End Ipu sample");		
	}
 
 
}

Test Scenario

To check that the "sensor_0" and "lamp_0" applications are successfully created, run the NSCL and GSCL products. Then go to the GSCL OSGi console and enter the ss command to list all deployed plugins. Start the "org.eclipse.om2m.sample.ipu" plugin (id=28 in this example) by typing the following command: start 28. The interworking proxy plug-in creates all required resources to enable to monitor and control sensor and lamp remotely and in a standardized way.

Open the NSCL web interface (127.0.0.1:8080), and move to the GSCL resource tree. Click on the "applications" resource to list all registered applications. You will find the following resources:

  • "lamp_0": an application resource enables to handle lamp 0.
  • "sensor_0": an application resource enables to handle sensor 0.


Lamp and sensor applications


This figure illustrates a contentInstance description.


ContentInstance resource


Execute a command using the following uri: "http://127.0.0.1:8080/om2m/gcl/applications/lamp_0/ipu/true" to switch on the lamp. You can verify if the command was successfully executed by checking the Lamp's descriptor contentInstance in the resource tree.

Switch on the lamp

Back to the top