Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

This section gives you a quick introduction on how to integrate a new device with WSO2 IoT Server. For this purpose let's look at how Connected Cup gets connected to WSO2 IoT Server. 

Table of Contents
maxLevel3
minLevel3

Note

If you only want to get Connected cup up and running, follow the steps given under Starting Connected Cup.

Planetbucks Connected Cup

Planetbucks is a local coffee vendor, well known and liked for their variety of exquisite coffee blends. They have a large customer base and most of the customers drop in on their way to work and after-work to grab a cup of coffee.

Planetbucks, Amy and Connected Cup

Amy, the manager of Planetbucks is amazed by the number of customers walking in and out of the store daily. She notices that most of these customers are in a hurry to grab a coffee and rush back to work/home. She feels that Planetbucks can get a competitive advantage in the market if they are able to take the coffee to the customer's work place/home, without them having to come to the store. With this idea in mind Amy moves on to start a Valued-Customer Program where all the Planetbucks regular customers are given a custom designed cup, which not only holds coffee but looks at including the following features:

  1. Display the level of coffee and temperature on the cup.

  2. Allow customers to order coffee by clicking a button on the cup.

  3. Allow customers to remotely monitor the cup and see the status of the coffee.

  4. Allow Planetbucks to study the customer drinking patterns and the coffee consumption.

Connected Cup and Steve

Amy approaches a local Device Manufacturer named Steve to get the connected cup designed, manufactured and connected. 

Steve is successful in manufacturing the hardware and is now in the look out for a suitable software platform to manage and control all the Connected Cups that Planetbucks hope to distribute to its customers. Steve searches through the internet and finds out that WSO2 IoTS is able to provide a viable solution to manage the cups that he manufactured.

He then starts using WSO2 IoT Server. Follow the steps given below for a walk through on how Steve got Connected Cup and the IoT Server to work together. You can follow the same steps to connect your device with WSO2 IoTS.

Downloading WSO2 IoT Server

To begin, Steve downloads WSO2 IoTS and starts it up on his production environment by following the steps given below.

Insert excerpt
IoTS300:Downloading the Product
IoTS300:Downloading the Product
nopaneltrue

Writing the Connected Cup device plugin

In WSO2 IoTS, each device type is required to have its own device plugin. Therefore, Steve writes a device plugin for Connected Cup. 

Info
iconfalse

WSO2 IoTS is built on top of the WSO2 Connected Device Management Framework (CDMF). A device plugin is an OSGI bundle that gets wired with WSO2 CDMF. For more information, see Writing Device Types.

Paneltip
titlePrerequisite

Open the Connected Cup sample, that is in the <IoTS_HOME>/samples/connectedcup directory via IntelliJ IDEA or a preferred IDE.

Example:

  • If you are using IntelliJ IDEA, import the pom file to open the Connected Cup project.
  • If you are using the Eclipse, navigate to the <IoTS_HOME>/samples/connectedcup directory, run the mvn eclipse:eclipse command to create a project and then import that project in eclipse.

Let's take a look at how Steve implemented the device plugin for Connected Cup by following the steps given below. You can follow the same to create a new device type plugin:

  1. Anchor
    step1.1
    step1.1
    Implement the DeviceManagementService by importing org.wso2.carbon.device.mgt.common.spi.DeviceManagementService, as shown in the ConnectedCupManagerService.java file that is in the <IoTS_HOME>/samples/connectedcup/component/plugin/src/main/java/org
    /coffeeking/connectedcup/plugin/impl
     directory. 

    Info
    iconfalse
    titleInfo from Steve

    In order to be identified as a device type in WSO2 CDMF, I implemented an interface for Connected Cup and registerd it as an OSGI service.

    Panel
    borderColor#11375B
    bgColor#ffffff
    borderWidth2

    Take a look at the DeviceManagementService interface implementation in WSO2 CDMF.

    Code Block
    titleThe DeviceManagementService interface.
    public interface DeviceManagementService {
        void init() throws DeviceManagementException;
        String getType();
        OperationMonitoringTaskConfig getOperationMonitoringConfig();
        DeviceManager getDeviceManager();
        ApplicationManager getApplicationManager();
        ProvisioningConfig getProvisioningConfig();
        PushNotificationConfig getPushNotificationConfig();
        PolicyMonitoringManager getPolicyMonitoringManager();
    }
    Expand
    titleClick here for more information on the methods used in the DeviceManager interface
    MethodDescription

    init()

    Includes the custom initialization implementations. The private variable should be initialized in the init() method as WSO2 CDMF calls this method when checking for implementations that have the deviceManagerService interface.

    Example:

    Code Block
    @Override
    public void init() throws DeviceManagementException 
    {
       this.deviceManager=new ConnectedCupManager();
    }
    getType()

    Retrieves the name of the device type.

    Example:

    Code Block
    @Override
    public String getType() 
    {
       return ConnectedCupConstants.DEVICE_TYPE;
    }

    getOperationMonitoringConfig()

    Returns an object, which is an implementation of the org.wso2.carbon.device.mgt.common.OperationMonitoringTaskConfig interface. Example:

    Code Block
    @Override
    public OperationMonitoringTaskConfig getOperationMonitoringConfig() 
    {
       return null;
    }

    getDeviceManager()

    The implementation of this interface should have a private variable of the device manager. It returns an object, which is an implementation of the org.wso2.carbon.device.mgt.common.DeviceManager interface.

    Example:

    Code Block
    @Override
    public DeviceManager getDeviceManager() 
    {
       return deviceManager;
    }

    getApplicationManager()

    Returns an object, which is an implementation of the org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManager interface.

    Example:

    Code Block
    @Override
    public ApplicationManager getApplicationManager() 
    {
       return null;
    }
    getProvisioningConfig()

    Returns the provisioning details, which includes the name of the tenant domain that the device type needs to be registered to and indicates whether the device type is to be shared with all the tenants. true indicates that the device-type should be visible to all tenants and false indicates that it is not visible to other tenants).

    Code Block
    @Override
    public ProvisioningConfig getProvisioningConfig() 
    {
     return new ProvisioningConfig("carbon.super", true);
    }
    getPolicyMonitoringManager()

    Returns an object, which is an implementation of the org.wso2.carbon.device.mgt.common.policy.mgt.PolicyMonitoringManager interface. Example:

    Code Block
    @Override
    public PolicyMonitoringManager getPolicyMonitoringManager() 
    {
      return null;
    }

     

  2. Implement the DeviceManager interface.

    Info
    titleInfo from Steve

    Implement the interface DeviceManager for Connected Cup via the org.wso2.carbon.device.mgt.common.DeviceManager in order to implement the getDeviceManager() method that is shown in step 1. The DeviceManager interface will be used for enrolling, disenrolling, activating and deactivating a device.

    1. Create a Database Access Object (DAO) on the ConnectedCupManager interface to manage data source connections.
      Example: 

      Code Block
      @Override
      public boolean updateDeviceInfo(DeviceIdentifier deviceIdentifier, Device device) throws DeviceManagementException {
          boolean status;
          try {
              if (log.isDebugEnabled()) {
                  log.debug(
                      "updating the details of Connected Cup device : " + deviceIdentifier);
              }
              ConnectedCupDAOUtil.beginTransaction();
              status = CONNECTED_CUP_DAO_UTIL.getConnectedCupDeviceDAO().updateDevice(device);
              ConnectedCupDAOUtil.commitTransaction();
          } catch (ConnectedCupDeviceMgtPluginException e) {
              try {
                  ConnectedCupDAOUtil.rollbackTransaction();
              } catch (ConnectedCupDeviceMgtPluginException iotDAOEx) {
                  String msg = "Error occurred while roll back the update device info transaction :" + device.toString();
                  log.warn(msg, iotDAOEx);
              }
              String msg =
                  "Error while updating the Connected Cup device : " + deviceIdentifier;
              log.error(msg, e);
              throw new DeviceManagementException(msg, e);
          }
          return status;
      }
  3. Register the service as an OSGI service by creating the ConnectedCupServiceComponent.java file as shown in the  <IoTS_HOME>/samples/connectedcup/component/plugin/src/main/java/org/coffeeking/connectedcup/plugin/internal directory.

The implemented interface manages the device type data, such as information related to enrollment, status, ownership, claimable, license and tenant configuration. When the OSGI bundle  ConnectedCupServiceComponent is activated, the device type will be registered on WSO2 CDMF. The successfully configured Connected Cup plugin component consists of the the following primary classes:

ClassDescription
ConnectedCupManagerImplements the org.wso2.carbon.device.mgt.common.DeviceManager.
ConnectedCupManagerServiceImplements the DeviceManagementService.
ConnectedCupServiceComponentThe OSGI Service Component that registers the ManagementService.
ConnectedCupDAOAdditionally it consists of the ConnectedCupDAO and the ConnectedCupDAOImp classes that are Data Access specific.
ConnectedCupDAOImp

Writing device type APIs for Connected Cup

The Connected Cup needs to communicate with the user's mobile application that monitors the cup, and send details on the consumer buying patterns and the coffee consumption data to Planetbucks. Therefore, Steve creates APIs for the Connected Cup device to communicate with external devices, the server and the device management console.

Info

For more information, see Writing Device APIs.

You can follow the steps on how Steve wrote APIs for Connected Cup and do the same for your device type:

  1. Create a JAXRS web application for the controller and manager APIs as shown in the <IoTS_HOME>/sample/connectedcup/component/api/src/main/java/org/coffeeking/api directory.

    Info
    titleInfo from Steve
    • The controller APIs are used by devices to communicate with the server, for the server to communicate with the devices and to communicate outside of WSO2 IoTS. 

    • The device management APIs are specifically used when carrying out internal functions. They are used for device-management tasks, such as enrolling, disenrolling, updating information and more. 

  2. Annotate the web app with the name and context, so that all the APIs of a device are grouped and can be identified instantly.
    Example: Take a look at the implemented api/ConnectedCupService.java file.

    Code Block
    @SwaggerDefinition(
        info = @Info(
            version = "1.0.0",
            title = "",
            extensions = {
                @Extension(properties = {
                    @ExtensionProperty(name = "name", value = "connectedcup"),
                    @ExtensionProperty(name = "context", value = "/connectedcup"),
                })
            }
        ),
        tags = {
            @Tag(name = "connectedcup", description = "")
        }
    )
    @Scopes(
        scopes = {
            @Scope(
                name = "Enroll device",
                description = "",
                key = "perm:connectedcup:enroll",
                permissions = {
                    "/device-mgt/devices/enroll/connectedcup"
                }
            )
        }
    )
  3. Annotate the APIs using the swagger annotations.  For more information on swagger annotations, see Annotations-1.5.X.
    Example:

    Code Block
    @Path("device/ordercoffee")
    @POST
    @ApiOperation(
        consumes = MediaType.APPLICATION_JSON,
        httpMethod = "POST",
        value = "Order Coffee",
        notes = "",
        response = Response.class,
        tags = "connectedcup",
        extensions = {
            @Extension(properties = {
                @ExtensionProperty(name = SCOPE, value = "perm:connectedcup:enroll")
            })
        }
    )
    Response orderCoffee(@QueryParam("deviceId") String deviceId);
  4. The resources used by external entities can be secured with WSO2 API Manager by including specific XML elements to the respective web.xml file of the web application that implements the APIs.
    Example:

    Info
    Expand
    titleClick here for to view a configured web.XML file.
    Code Block
    <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
       <display-name>ConnectedCup-Webapp</display-name>
       <servlet>
          <servlet-name>CXFServlet</servlet-name>
          <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
          <load-on-startup>1</load-on-startup>
       </servlet>
       <servlet-mapping>
          <servlet-name>CXFServlet</servlet-name>
          <url-pattern>/*</url-pattern>
       </servlet-mapping>
       <context-param>
          <param-name>isAdminService</param-name>
          <param-value>false</param-value>
       </context-param>
       <context-param>
          <param-name>doAuthentication</param-name>
          <param-value>true</param-value>
       </context-param>
       <context-param>
          <param-name>isSharedWithAllTenants</param-name>
          <param-value>true</param-value>
       </context-param>
       <context-param>
          <param-name>providerTenantDomain</param-name>
          <param-value>carbon.super</param-value>
       </context-param>
       <!--publish to apim-->
       <context-param>
          <param-name>managed-api-enabled</param-name>
          <param-value>true</param-value>
       </context-param>
       <context-param>
          <param-name>managed-api-owner</param-name>
          <param-value>admin</param-value>
       </context-param>
    </web-app>
    Expand
    titleClick here for more information on the XML properties

    Insert excerpt
    Writing Device APIs
    Writing Device APIs
    nopaneltrue

Writing batch analytics for Connected Cup

Steve needs to gather data on the level of coffee in the cup and its temperature. Using the coffee level Planetbucks is able to know, if the customer requires a refill and promote the customer to order again. Knowing the temperature of the coffee will help the customer heat up the coffee via the Connected Cup. In this step let's take a look at how Steve uses the coffee level sensor to gather the data of the coffee level.

Each sensor needs to have a set of Data Analytic Server (DAS) artifacts. For more information, see Writing Analytics.

The sample DAS Capp folder structure to get the coffee level in the cup is shown below. The DAS Capp defines the artifacts, and ships them to DAS as an archive. 

  • receivers - Includes the content to bind the streams to the stores.

  • stores - Includes the schema to persist and format the streaming data.

  • streams - Includes the content to define the data format of the streaming data.

  • scripts - Includes the analytics script used to summarize data streams.

Follow the step on how Steve wrote batch analytics for the coffee level in the cup:

  1. Create the event stream artifact as shown in the <IoTS_HOME>/samples/connectedcup/component/analytics/src/main/resources/carbonapps
    /coffee_level/coffee_level_stream
     directory.
    1. Create the stream format JSON file using a unique name, such as org.wso2.iot.devices.coffeelevel_1.0.0, to stream the coffee level data.
      The stream JSON definition consists of 2 main sections named metaData and payloadData.

      Info
      titleInfo from Steve

      Make sure to only modify the payloadData as it contains the data that will be published. If you wish to customize the metaData, you need to update the sparkscript too. The spark scripts are configured in step 4.

      Example: 

      Code Block
      titleStream JSON format to gather data of the coffee level
      {
        "name": "org.wso2.iot.devices.coffeelevel",
        "version": "1.0.0",
        "nickName": "CoffeeLevel",
        "description": "Coffee Level data received from the Device",
        "metaData": [
          {"name":"owner","type":"STRING"},     
          {"name":"deviceType","type":"STRING"},
          {"name":"deviceId","type":"STRING"},  
          {"name":"time","type":"LONG"}
        ],
        "payloadData": [
          {
            "name": "coffeelevel","type": "FLOAT"
          }
        ]
      }
    2. Define the event stream as an artifact by configuring the artifact.xml file.

      Info
      titleInfo from Steve

      The artifact.xml is added to notify WSO2 IoTS to refer the org.wso2.iot.devices.coffeelevel_1.0.0.json file for event streaming.

      Example:

      Code Block
      titleSample artifact.xml
      <artifact name="coffee_level_stream" version="1.0.0" type="event/stream" serverRole="DataAnalyticsServer">
         <file>org.wso2.iot.devices.coffeelevel_1.0.0.json</file>
      </artifact>
  2. Create the event store artifact as shown in the <IoTS_HOME>/samples/connectedcup/component/analytics /src/main/resources/carbonapps
    /coffee_level/coffee_level_store
     directory.
    1. Create an XML file containing the details on how to persist data to the internal DAS tables.
      The <ColumnDefinition> tags are used to define the table definitions for the stream. The <Type> tag of the column supports primitive data types and a special data type named facet.  

      Info
      titleInfo from Steve

      Facet is an attribute of indexed records, which is used to classify the records by the attribute value. For more information, see the WSO2 DAS docs on facets.

      Example:

      Code Block
      titleSample XML configured to persist data
      <EventStoreConfiguration>
          <Source>
              <StreamId>org.wso2.iot.devices.coffeelevel:1.0.0</StreamId>
          </Source>
          <RecordStoreName>EVENT_STORE</RecordStoreName>
          <TableSchema>
            <ColumnDefinition>
               <Name>meta_owner</Name>
               <EnableIndexing>true</EnableIndexing>
               <IsPrimaryKey>true</IsPrimaryKey>
               <EnableScoreParam>false</EnableScoreParam>
               <Type>STRING</Type>
            </ColumnDefinition>
            <ColumnDefinition>
               <Name>meta_deviceType</Name>
               <EnableIndexing>true</EnableIndexing>
               <IsPrimaryKey>true</IsPrimaryKey>
               <EnableScoreParam>false</EnableScoreParam>
               <Type>STRING</Type>
            </ColumnDefinition>
            <ColumnDefinition>
               <Name>meta_deviceId</Name>
               <EnableIndexing>true</EnableIndexing>
               <IsPrimaryKey>true</IsPrimaryKey>
               <EnableScoreParam>false</EnableScoreParam>
               <Type>STRING</Type>
            </ColumnDefinition>
            <ColumnDefinition>
               <Name>meta_time</Name>
               <EnableIndexing>true</EnableIndexing>
               <IsPrimaryKey>true</IsPrimaryKey>
               <EnableScoreParam>false</EnableScoreParam>
               <Type>LONG</Type>
            </ColumnDefinition>
            <ColumnDefinition>
               <Name>coffeelevel</Name>
               <EnableIndexing>false</EnableIndexing>
               <IsPrimaryKey>false</IsPrimaryKey>
               <EnableScoreParam>false</EnableScoreParam>
               <Type>FLOAT</Type>
            </ColumnDefinition>
          </TableSchema>
      </EventStoreConfiguration>
    2. Define the event store as an artifact by configuring the artifact.xml file.

      Info
      titleInfo from Steve

      The artifact.xml is added to notify the IoT Server to refer the org_wso2_iot_devices_coffeelevel.xml file for event storing.

      Example:

      Code Block
      <artifact name="coffee_level_store" version="1.0.0" type="analytics/eventstore" serverRole="DataAnalyticsServer">
          <file>org_wso2_iot_devices_coffeelevel.xml</file>
      </artifact>
  3. Creating the event receiver artifact as shown in the <IoTS_HOME>/samples/connectedcup/component/analytics /src/main/resources/carbonapps
    /coffee_level/coffee_level_receiver
     directory.
    1. Create an XML file containing the details on binding the stream to the table using receivers.  

      Example:

      Code Block
      <eventReceiver name="coffee_level_receiver" statistics="disable" trace="disable" xmlns="http://wso2.org/carbon/eventreceiver">
          <from eventAdapterType="wso2event">
              <property name="events.duplicated.in.cluster">false</property>
          </from>
          <mapping customMapping="disable" type="wso2event"/>
          <to streamName="org.wso2.iot.devices.coffeelevel" version="1.0.0"/>
      </eventReceiver>
    2. Define the event receiver as an artifact by configuring the artifact.xml file.

      Info
      iconfalse
      titleInfo from Steve

      The artifact.xml is added to notify the IoT Server to refer the coffee_level_receiver.xml file for event receiving.

      Example:

      Code Block
      <artifact name="coffee_level_receiver" version="1.0.0" type="event/receiver" serverRole="DataAnalyticsServer">
          <file>coffee_level_receiver.xml</file>
      </artifact>
  4. Anchor
    sparkScript
    sparkScript
    Create an analytics script artifact as shown in the <IoTS_HOME>/samples/connectedcup/component/analytics /src/main/resources/carbonapps
    /coffee_level/coffee_level_script
     directory.

    1. Create a Spark script to correctly summarize the content.
      Example:

      Code Block
      <Analytics>
         <Name>coffee_level_script</Name>
         <Script>CREATE TEMPORARY TABLE DeviceCoffeeLevelData USING CarbonAnalytics OPTIONS(tableName "ORG_WSO2_IOT_DEVICES_COFFEELEVEL");
      
              CREATE TEMPORARY TABLE DeviceCoffeeLevelSummaryData USING CarbonAnalytics OPTIONS (tableName "DEVICE_COFFEELEVEL_SUMMARY", schema "coffeelevel FLOAT, deviceType STRING -i, deviceId STRING -i, owner STRING -i, time LONG -i",primaryKeys "deviceType, deviceId, owner, time");
      
              insert into table DeviceCoffeeLevelSummaryData select coffeelevel, meta_deviceType as deviceType, meta_deviceId as deviceId, meta_owner as owner, cast(meta_time/1000 as BIGINT)as time from DeviceCoffeeLevelData group by coffeelevel, meta_deviceType, meta_deviceId, meta_owner, cast(meta_time/1000 as BIGINT);</Script>
         <CronExpression>0 0/5 * * * ?</CronExpression>
      </Analytics>
    2. Define the analytics script as an artifact by configuring the artifact.xml file.

      Code Block
      <artifact name="coffee_level_script" version="1.0.0" type="analytics/spark" serverRole="DataAnalyticsServer">
          <file>coffee_level_script.xml</file>
      </artifact>
  5. Create a deployable artifcat to create an archive of all the artifacts created above as shown in the <IoTS_HOME>/samples/connectedcup/component/analytics /src/main/resources/carbonapps
    /coffee-level/artifact.xml
     file.

    Example:

    Code Block
    <artifacts>
        <artifact name="coffee_level" version="1.0.0" type="carbon/application">
          <dependency artifact="coffee_level_stream" version="1.0.0" include="true" serverRole="DataAnalyticsServer"/>
          <dependency artifact="coffee_level_store" version="1.0.0" include="true" serverRole="DataAnalyticsServer"/>
          <dependency artifact="coffee_level_receiver" version="1.0.0" include="true" serverRole="DataAnalyticsServer"/>
          <dependency artifact="coffee_level_script" version="1.0.0" include="true" serverRole="DataAnalyticsServer"/>
        </artifact>
    </artifacts>
  6. Configure the build.xml for analytics as shown in the <IoTS_HOME>/samples/connectedcup/component/analytics directory.

    Info
    iconfalse
    titleInfo from Steve

    The build.xml file is used to create a normal .zip file with .car extension. The zip achieve contains all the artifacts and the artifacts.xml at the root level of the zip

    Example: 

    Code Block
    <project name="create-connectedcup-capps" default="zip" basedir=".">
       <property name="project-name" value="${ant.project.name}" />
       <property name="target-dir" value="target/carbonapps" />
       <property name="src-dir" value="src/main/resources/carbonapps" />
       <property name="ConnectedCup_dir" value="connected_cup" />
       <property name="CoffeeLevel_Sensor_dir" value="coffee_level" />
       <target name="clean">
          <delete dir="${target-dir}" />
       </target>
       <target name="zip" depends="clean">
          <mkdir dir="${target-dir}" />
          <zip destfile="${target-dir}/${ConnectedCup_dir}.car">
             <zipfileset dir="${src-dir}/${ConnectedCup_dir}" />
          </zip>
          <zip destfile="${target-dir}/${CoffeeLevel_Sensor_dir}.car">
             <zipfileset dir="${src-dir}/${CoffeeLevel_Sensor_dir}" />
          </zip>
       </target>
    </project>

Writing UI extensions for Connected Cup

Steve then looks at developing the User Interface. The UI of WSO2 IoTS is built using the WSO2 Unified UI Framework (UUF) allowing you to create extensions for customized UI developments.

Info

For more information, see WSO2 Unified UI Framework.

  1. Write the device type view using the cdmf.unit.device.type.connectedcup.type-view unit as shown in the <IoTS_HOME>/samples/connectedcup/ui
    /src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.connectedcup.type-view
    directory. You need to explain the device type and its functionality, and t he steps to register an instance of the device in this jaggery application page.

    Info
    titleInfo from Steve

    This unit gets fetched when you click on a specific device type from the device-type-listings page.

  2. Write the device details UI using the  cdmf.unit.device.type.connectedcup.device-view unit as shown in the <IoTS_HOME>/samples/connectedcup/ui
    /src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.connectedcup.device-view
     directory.

    Info
    titleInfo from Steve
    • This unit that gets fetched when an end-user clicks on a specific instance of a device-type that he/she has already registered to.
    • You need to include the real time analytics UI unit when writing this UI init.

  3. Write the UI to represent the real time data received from the device using the cdmf.unit.device.type.connectedcup.realtime.analytics-view unit as shown in the  <IoTS_HOME>/samples/connectedcup/ui/src /main/resources/jaggeryapps/devicemgt/app/units
    /cdmf.unit.device.type.connectedcup.realtime.analytics-view
    directory.

  4. Write the UI to represent the historical data received from the device using the cdmf.unit.device.type.connectedcup.analytics-view unit as shown in the <IoTS_HOME>/samples/connectedcup/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.connectedcup.analytics-view directory.

Creating the Carbon feature for Connected Cup

Steve then identifies that WSO2 IoTS is a collection of Carbon components. It is developed by plugging various Carbon components that provide different features. Therefore, he follow the steps given below to convert the configured device type to a feature. Steve identifies that the following folder structure has to be maintained to create the feature as shown in the <IoTS_HOME>/samples/feature directory.

  1. Create and configure the agent.
    1. Define the device configurations in the /agent/deviceConfig.properties file as shown below:

      Info
      titleInfo from steve

      The properties in the file will be replaced with the related information when the agent is being downloaded so that the information can be used to communicate with the IoT Server and the agent.

      Code Block
      owner=${DEVICE_OWNER}
      deviceId=${DEVICE_ID}
      device-name=${DEVICE_NAME}
      controller-context=/${deviceType}/controller
      mqtt-ep=${MQTT_EP}
      auth-method=token
      auth-token=${DEVICE_TOKEN}
      refresh-token=${DEVICE_REFRESH_TOKEN}
      push-interval=15
    2. Create the /agent/sketch.properties file. It contains the information for the IoT Server to find the agent template and the name of the zip file.

      Code Block
      templates=deviceConfig.properties
      zipfilename=connectedCup.zip
  2. Define the database scripts in the <IoTS_HOME>/samples/connectedcup/feature/connectedcup-feature/src/main/resources/datasources folder having the name in the <DEVICE_TYPE>- datasources.xml format.
    Example: connectedCup -datasources.xml file.

    Code Block
    <datasources-configuration xmlns:svns="http://org.wso2.securevault/configuration">
       <providers>
          <provider>org.wso2.carbon.ndatasource.rdbms.RDBMSDataSourceReader</provider>
       </providers>
       <datasources>
          <datasource>
             <name>ConnectedCupDM_DB</name>
             <description>The datasource used for the Connected Cup database</description>
             <jndiConfig>
                <name>jdbc/ConnectedCupDM_DB</name>
             </jndiConfig>
             <definition type="RDBMS">
                <configuration>
                   <url>jdbc:h2:repository/database/ConnectedCupDM_DB;DB_CLOSE_ON_EXIT=FALSE</url>
                   <username>wso2carbon</username>
                   <password>wso2carbon</password>
                   <driverClassName>org.h2.Driver</driverClassName>
                   <maxActive>50</maxActive>
                   <maxWait>60000</maxWait>
                   <testOnBorrow>true</testOnBorrow>
                   <validationQuery>SELECT 1</validationQuery>
                   <validationInterval>30000</validationInterval>
                </configuration>
             </definition>
          </datasource>
       </datasources>
    </datasources-configuration>
  3. Create the database scripts in the <IoTS_HOME>/samples/connectedcup/feature/connectedcup-feature/src/main/resources/dbscripts folder.
    A sample implementation of the database script is shown below, you will need to customize it to suite your requirement.

    Code Block
    -- -----------------------------------------------------
    -- Table `CONNECTED_CUP_DEVICE`
    -- -----------------------------------------------------
    CREATE TABLE IF NOT EXISTS `CONNECTED_CUP_DEVICE` (
      `CONNECTED_CUP_DEVICE_ID` VARCHAR(45) NOT NULL ,
      `DEVICE_NAME` VARCHAR(100) NULL DEFAULT NULL,
      PRIMARY KEY (`CONNECTED_CUP_DEVICE_ID`) ); 
  4. Create the pom.xml file to create the device type as a feature in the P2 repository as shown in the <IoTS_HOME>/samples/connectedcup/feature/connectedcup-feature directory. The file contains information on the device type and configuration details used by Maven to build the feature.
    Example: 
    1. Include a task to create the databases based on the database scripts created in step 1, in the P2 repository.
      Example:

      Code Block
      <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-antrun-plugin</artifactId>
         <executions>
            <execution>
               <!-- Creating Connected Cup Plugin Management schema -->
               <id>create-connected-cup-plugin-mgt-schema</id>
               <phase>package</phase>
               <goals>
                  <goal>run</goal>
               </goals>
               <configuration>
                  <tasks>
                     <property name="db.dir" value="target/maven-shared-archive-resources/database" />
                     <property name="userid" value="wso2carbon" />
                     <property name="password" value="wso2carbon" />
                     <property name="dbURL" value="jdbc:h2:file:${basedir}/${db.dir}/ConnectedCupDM_DB;DB_CLOSE_ON_EXIT=FALSE" />
                     <mkdir dir="${basedir}/${db.dir}" />
                     <sql driver="org.h2.Driver" url="${dbURL}" userid="${userid}" password="${password}" autocommit="true" onerror="continue">
                        <classpath refid="maven.dependency.classpath" />
                        <classpath refid="maven.compile.classpath" />
                        <classpath refid="maven.runtime.classpath" />
                        <fileset file="${basedir}/src/main/resources/dbscripts/h2.sql" />
                     </sql>
                  </tasks>
               </configuration>
            </execution>
         </executions>
      </plugin>
    2. Define a task to copy the JAXRS web application implemented for the controller and device manager APIs to the P2 repository.
      Example:

      Code Block
      <execution>
         <id>copy-jaxrs-war</id>
         <phase>package</phase>
         <goals>
            <goal>copy</goal>
         </goals>
         <configuration>
            <artifactItems>
               <artifactItem>
                  <groupId>org.coffeeking</groupId>
                  <artifactId>org.coffeeking.connectedcup.api</artifactId>
                  <type>war</type>
                  <overWrite>true</overWrite>
                  <outputDirectory>${project.build.directory}/maven-shared-archive-resources/webapps/</outputDirectory>
                  <destFileName>connectedcup.war</destFileName>
               </artifactItem>
               <artifactItem>
                  <groupId>org.coffeeking</groupId>
                  <artifactId>org.coffeeking.connectedcup.agent</artifactId>
                  <type>war</type>
                  <overWrite>true</overWrite>
                  <outputDirectory>${project.build.directory}/maven-shared-archive-resources/webapps/</outputDirectory>
                  <destFileName>connected-cup-agent.war</destFileName>
               </artifactItem>
            </artifactItems>
         </configuration>
      </execution>
    3. Optionally, if your device type includes a device agent, define a task to copy the respective JAXRS web application to the P2 repository.
      Example:

      Code Block
      <execution>
         <id>copy-jaxrs-agent-war</id>
         <phase>package</phase>
         <goals>
            <goal>copy</goal>
         </goals>
         <configuration>
            <artifactItems>
               <artifactItem>
                  <groupId>org.wso2.carbon.devicemgt-plugins</groupId>
                  <artifactId>org.coffeeking.agent</artifactId>
                  <type>war</type>
                  <overWrite>true</overWrite>
                  <outputDirectory>${project.build.directory}/maven-shared-archive-resources/webapps/</outputDirectory>
                  <destFileName>connected-cup-agent.war</destFileName>
               </artifactItem>
            </artifactItems>
         </configuration>
      </execution>
    4. Define a task to create the main feature plugin in the P2 repository.
      Example:

      Code Block
      <plugin>
         <groupId>org.wso2.maven</groupId>
         <artifactId>carbon-p2-plugin</artifactId>
         <executions>
            <execution>
               <id>p2-feature-generation</id>
               <phase>package</phase>
               <goals>
                  <goal>p2-feature-gen</goal>
               </goals>
               <configuration>
                  <id>org.coffeeking.connectedcup</id>
                  <propertiesFile>../../../features/etc/feature.properties</propertiesFile>
                  <adviceFile>
                     <properties>
                        <propertyDef>org.wso2.carbon.p2.category.type:server</propertyDef>
                        <propertyDef>org.eclipse.equinox.p2.type.group:true</propertyDef>
                     </properties>
                  </adviceFile>
                  <bundles>
                     <bundleDef>org.coffeeking:org.coffeeking.connectedcup.plugin:${wso2.iot.version}</bundleDef>
                  </bundles>
                  <importFeatures>
                     <importFeatureDef>org.wso2.carbon.core.server:${carbon.kernel.version}</importFeatureDef>
                     <importFeatureDef>org.wso2.carbon.device.mgt.server:${carbon.device.mgt.version}</importFeatureDef>
                  </importFeatures>
               </configuration>
            </execution>
         </executions>
      </plugin>
    5. Define a task to copy the carbonapps and jaggeryapps to the P2 repository.
      Example:

      Code Block
      <execution>
         <id>unpack</id>
         <phase>package</phase>
         <goals>
            <goal>unpack</goal>
         </goals>
         <configuration>
            <artifactItems>
               <artifactItem>
                  <groupId>org.wso2.carbon.devicemgt-plugins</groupId>
                  <artifactId>org.coffeeking.connectedcup.analytics</artifactId>
                  <version>${project.version}</version>
                  <type>zip</type>
                  <overWrite>true</overWrite>
                  <outputDirectory>${project.build.directory}/maven-shared-archive-resources/carbonapps</outputDirectory>
                  <includes>*/</includes>
               </artifactItem>
               <artifactItem>
                  <groupId>org.wso2.carbon.devicemgt-plugins</groupId>
                  <artifactId>org.coffeeking.connectedcup.ui</artifactId>
                  <version>${project.version}</version>
                  <type>zip</type>
                  <overWrite>true</overWrite>
                  <outputDirectory>${project.build.directory}/maven-shared-archive-resources/jaggeryapps/devicemgt
                  </outputDirectory>
                  <includes>*/</includes>
               </artifactItem>
            </artifactItems>
         </configuration>
      </execution>
  5. Create the p2.inf file. It contains the details on copying the files from the P2 repository to the WSO2 IoTS pack.
    Example: A configured p2.inf file.

    Code Block
    instructions.configure = \
    org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../conf/device-types/);\
    org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.coffeeking.connectedcup_${feature.version}/configs/,target:${installFolder}/../../conf/device-types/,overwrite:true);\
    org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../deployment/server/webapps/);\
    org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.coffeeking.connectedcup_${feature.version}/webapps/,target:${installFolder}/../../deployment/server/webapps/,overwrite:true);\
    org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../deployment/server/carbonapps/);\
    org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.coffeeking.connectedcup_${feature.version}/carbonapps/,target:${installFolder}/../../deployment/server/carbonapps/,overwrite:true);\
    org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../resources/sketches/);\
    org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../resources/sketches/connectedcup/);\
    org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.coffeeking.connectedcup_${feature.version}/agent/,target:${installFolder}/../../resources/sketches/connectedcup/,overwrite:true);\
    org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.coffeeking.connectedcup_${feature.version}/dbscripts/,target:${installFolder}/../../../dbscripts/cdm/plugins/connectedcup,overwrite:true);\
    org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.coffeeking.connectedcup_${feature.version}/datasources/,target:${installFolder}/../../conf/datasources/,overwrite:true);\
    org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../deployment/server/jaggeryapps/);\
    org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.coffeeking.connectedcup_${feature.version}/jaggeryapps/,target:${installFolder}/../../deployment/server/jaggeryapps/,overwrite:true);\
    org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../database/);\
    org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.coffeeking.connectedcup_${feature.version}/database/,target:${installFolder}/../../database/,overwrite:true);\
    Info

    For more information on the P2 touch point commands, see provisioning actions and touch points.

  6. Configure the samples-deployer.xml file as shown in the <IoTS_HOME>/samples-deployer.xml.

    Info
    titleInfo from Steve

    I am using the the samples-deployer.xml file in this use case as this is a sample scenario. When creating your device type, you need add the content in this step to the <IoT_HOME>/plugins/device-deployer.xml file.


    1. Add the new module under the <modules> tag.
      Example:

      Code Block
      <modules>
         <module>samples/connectedcup</module>
      </modules>
    2. Add the device type feature under the <featureArtifacts> tag.

      Code Block
      <featureArtifactDef>
         org.coffeeking:org.coffeeking.connectedcup.feature:1.0.0-SNAPSHOT
      </featureArtifactDef>
    3. Add the device type feature group under the <features> tag.

      Code Block
      <features>
         <feature>
            <id>org.coffeeking.connectedcup.feature.group</id>
            <version>1.0.0-SNAPSHOT</version>
         </feature>
      </features>

Starting Connected Cup

It's finally time to rejoice! Steve is successful in making the Connected Cup and WSO2 IoT Server to work together. He then let's Amy run the Connected and try it out by following the steps given below.

Note

Stop the WSO2 IoT Server if you have started it previously. You need to stop all the three profiles, i.e, WSO2 Message Broker, WSO2 Connected Device Management Framework (WSO2 CDMF) and WSO2 Data Analytics Server profiles, to stop WSO2 IoTS.

  1. Build the Connected Cup device type.

    Code Block
    cd <IoT_HOME>/samples/connectedcup
    mvn clean install
  2. Run the samples-deployer.xml file.

    Code Block
    cd <IOTS_HOME>/samples
    mvn clean install -f connectedcup-samples-deployer.xml
  3. Start or restart WSO2 IoTS.

    Expand
    titleClick here for more information.
    Localtabgroup
    Localtab
    activetrue
    titleWindows/Linux/Mac OS

    Follow the steps given below:

    1. Open a command prompt by following the instructions below:
      • On Windows: Click  Start > Run,  type  cmd  at the prompt, and then press Enter.
      • On Linux/Mac OS: Establish an SSH connection to the server, log on to the text Linux console, or open a terminal window.
    2. Navigate to the <IOTS_HOME>/bin directory using the Command Prompt to start the WSO2 IoTS core, broker and analytics profiles all at ones.

    3. Start the profiles in the following order:
      1. Start the broker profile, which corresponds to the WSO2 Message Broker profile.

        Localtabgroup
        Localtab
        activetrue
        titleLinux/Mac OS
        Code Block
        cd <IoTS_HOME>/bin
        ./broker.sh
        Localtab
        titleWindows
        Code Block
        cd <IoTS_HOME>\bin
        broker.bat

        The default port assigned for the broker is 9446.

      2. Start the core profile, which corresponds to the WSO2 Connected Device Management Framework (WSO2 CDMF) profile.

        Localtabgroup
        Localtab
        activetrue
        titleLinux/Mac OS
        Code Block
        ./iot-server.sh
        Localtab
        titleWindows
        Code Block
        iot-server.bat

        The default port assigned for the core is 9443. 

      3. Start the analytics profile, which corresponds to the WSO2 Data Analytics Server profile.

        Localtabgroup
        Localtab
        activetrue
        titleLinux/Mac OS
        Code Block
        ./analytics.sh
        Localtab
        titleWindows
        Code Block
        analytics.bat

        The default port assigned for analytics is 9445.

      The operation log appears in the command window. When the product server has successfully started, the log displays the message WSO2 Carbon started in 'n' seconds

    Localtab
    titleSolaris

    Follow the steps given below:

    Note

    Following instructions are tested on an Oracle Solaris 10 8/11 x86 environment.

    1. Anchor
      instructions
      instructions
      Click Launch > Run Applications, type dtterm at the Prompt, and then press Enter, to open a Command Prompt.
    2. Navigate to the <IoTS_HOME>/bin directory using the Command Prompt.
    3. Start the profiles in the following order:
      1. Start the broker profile, which corresponds to the WSO2 Message Broker profile.

        Code Block
        cd <IoTS_HOME>bin
        ./broker.sh

        The default port assigned for the broker is 9446.

      2. Start the core profile, which corresponds to the WSO2 Carbon Device Management Framework (CDMF) profile.

        Code Block
        ./iot-server.sh

        The default port assigned for the core is 9443. 

      3. Start the analytics profile, which corresponds to the WSO2 Data Analytics Server profile.

        Code Block
        ./analytics.sh

        The default port assigned for analytics is 9445.

    4. The operation log appears in the command window. When the product server has successfully started, the log displays the message WSO2 Carbon started in 'n' seconds.

    Info
    You need to do the following modification to the <IOTS_HOME>/bin/iot-server.sh file, to start the product as a service/nohup mode in Solaris.
    1. Open the respective iot-server.sh file.
      For example, for the core profile open the <IoTS_HOME>/bin/iot-server.sh file in a text editor.
    2. Search for the following occurrences: nohup sh "$CARBON_HOME"/bin/iot-server.sh $args > /dev/null 2>&1 &
    3. Replace those occurrences with the following:  nohup bash "$CARBON_HOME"/bin/iot-server.sh $args > /dev/null 2>&1 &

      Tip

      The only change is replacing sh with bash. This is required only for Solaris.

    4. Start the product by following the above instructions.

  4. Access the device management console and log in using admin as both the username and password.
    Example: https://localhost:9443/devicemgt

    Info

    For more information, see accessing the device management console.

    You will see the connected cup device in the device page.

  5. Click Try Out next to Connected Cup and create an instance.
  6. Try out the Connected Cup device type.

Amy is over joyed with the new Connected Cup and the software platform used (WSO2 IoT Server). When she introduces the Connected Cup to the Planetbucks top management. They strongly believe that it would give them a competitive advantage in the market place. 

What's next?

Are you planning on writing your own device? If yes, the following sections will guide you on how to create your own device type.

Page Tree
rootDevice Manufacturer Guide