Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "OM2M/Developer"

(Add specific jar dependencies)
(Add specific jar dependencies)
Line 112: Line 112:
 
* Go to the "classpath" tab and click on the "Add" button.  
 
* Go to the "classpath" tab and click on the "Add" button.  
 
* Select the required jar and click on "ok" button.
 
* Select the required jar and click on "ok" button.
[[File:jars.png|thumb|center|900px|plugin specific jar dependencies]]
+
[[File:jars.png|thumb|center|800px|plugin specific jar dependencies]]
  
 
=== The IPU Monitor ===
 
=== The IPU Monitor ===

Revision as of 08:38, 5 December 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 “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 → convert 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

Add required plugin dependencies

  • Open the manifest file of the created plugin and select Dependencies tab.
  • Add the dependencies depicted in the following figure.
plugin dependencies


Add specific jar dependencies

  • Create a "libs" folder on your plugin project.
  • Put required specific jar on the "libs" folder.
  • Open the manifest file of the created plugin and select "runtime" tab.
  • Go to the "classpath" tab and click on the "Add" button.
  • Select the required jar and click on "ok" button.
plugin specific jar dependencies

The IPU Monitor

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 {
 
	/** sensor state */
    private static int state;
 
	/**
     * 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);
 
    }
 
    /**
     * Gets SensorState
     * @return SensorState
     */
    public static void setState(int state) {
    	int Value = 10 + (int)(Math.random()*100);
        Sensor.state = Value;
    }
 
}

The Actuator class

  • In this tutorial, we take a lamp as an actuator. Let's consider the following Lamp class which is dedicated to handle the information and state.
package org.eclipse.om2m.sample.ipu;
 
import obix.*;
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 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.
  • You notice that when creating a contentInstance of a Desccriptor/ Data Container we use getDescriptorRep getSateRep methods of the Sensor/ Lamp classes described above.

package org.eclipse.om2m.sample.ipu;
 
import obix.*;
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
        createLampResources("lamp_0", false, APOCPATH);
 
         // Create initial resources for the sensor
        createSensorResources("sensor_0", 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);
    }
 
 
}

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];
	        String trueCase = "true"; 
	        String falseCase = "false"; 
	        try {
	            if(type.equals("lamp")) {
	                IpuMonitor.setLampState(lampId, value);
	                if (value.equals(trueCase)) {
	                	javax.swing.JOptionPane.showMessageDialog(null, "the lamp is switched on");
	                } else if (value.equals(falseCase)) {
	                	javax.swing.JOptionPane.showMessageDialog(null, "the lamp is switched off");
	                }
	                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


Switch on the lamp: the command
Switch on the lamp: the message box

Copyright © Eclipse Foundation, Inc. All Rights Reserved.