OpenMTC

Quick Start

In this short tutorial you will:

  1. Setup an OpenMTC Gateway
  2. Create an application resource and corresponding content instance via the REST API
  3. Using the REST API to get this content instance Clone the OpenMTC repository

        git clone https://github.com/OpenMTC/OpenMTC OpenMTC
        

All following commands should be executed from within the repo folder


        cd OpenMTC
        

The next steps need Docker to be installed on your system. If you need help for the installation, follow this guide.

Build the gateway Image


        ./create-binary-docker gateway
        

To check if this step was successful run:


        docker image ls
        

If there is an entry "openmtc/gateway" the image was created successfully.
Run the gateway Docker image


        docker run -d --name gateway  -p 0.0.0.0:8000:8000  \
            -e "LOGGING_LEVEL=DEBUG"    openmtc/gateway -vv
        

Create an application resource on your gateway


        curl -X POST localhost:8000/onem2m/ -H "Content-Type: application/vnd.onem2m-res+json" \
             -d '{"m2m:ae": {"rn": "EXAMPLE_APP_NAME", "api": "placeholder", "rr": "TRUE"}}'
        

Create a container resource on your gateway


        curl -X POST localhost:8000/onem2m/EXAMPLE_APP_NAME/ -H "Content-Type: application/vnd.onem2m-res+json" \
             -d '{"m2m:cnt": {"rn": "EXAMPLE_CONTAINER_NAME"}}'
        

Create plain text content


        curl -X POST localhost:8000/onem2m/EXAMPLE_APP_NAME/EXAMPLE_CONTAINER_NAME/ \
             -H "Content-Type: application/vnd.onem2m-res+json" \
             -d '{"m2m:cin": {"con": "EXAMPLE_VALUE", "cnf": "text/plain:0"}}'
        

Get the Content


        curl -X GET localhost:8000/onem2m/EXAMPLE_APP_NAME/EXAMPLE_CONTAINER_NAME/latest
        

Introduction to OpenMTC

Using OpenMTC for IoT/M2M applications

OpenMTC provides an implementation of the oneM2M standard. This allows you to develop new or test existing IoT/M2M applications, create your own IoT/M2M infrastructure, or extend an existing one.

How is data represented in an OpenMTC-based system?

In an OpenMTC system, all entities are represented as resources. Resources are either:

  • Containers consisting of other containers (subcontainer) or content instances
  • Content Instances holding actual values

This results in a hierarchical resource tree with content instances as leafs. Each resource within the resource tree is uniquely addressable by an unique identifier (URI).

Example

Lets assume you have a ZigBee device providing informations about the current temperature and its battery status. This will result in the following resource tree: Resource Tree

How to access and provide data from/to an OpenMTC-based system?

OpenMTC provides mechanisms to create, change, update, and delete resources in the resource tree. Therefore, an application is needed that will use one of the following two approaches:

  • A REST API (external interface)
  • The OpenMTC SDK (internal interface)

Using the REST API, it is possible to provide your application logic by just using your preferred HTTP client.

In addition, it is also possible to use the OpenMTC SDK to write your application. Common problems, like how to create a subscription that will notify your application whenever a particular resources are changed or have a new content instance available, are easily to be solved, using the SDK.

How to structure your OpenMTC-based IoT system?

Using OpenMTC, it is possible to create your own IoT/M2M infrastructure. Consider an IoT system that collects data from different sensors, in different field domains, and automatically distributes the data to central nodes of multiple field domains.
Example OpenMTC Architecture With OpenMTC you would setup an OpenMTC Gateway for every field domain. All oneM2M devices within this field domain would register themself with the gateway. Non-oneM2M devices would need an Interworking Proxy inbetween to translate to oneM2M.
The gateways are registered at an OpenMTC Backend within the infrastructure domain.
OpenMTC Applications could either connect directly to the gateways or the backend to provide/collect data.

Application (AE)

An application is provided by you and others to access data within the OpenMTC-based IoT system.

An example for an application is the server part of Graphical User Interface (GUI), that allows to visualize data stored in the resource tree.
Another example would be an application using device data to do some analytics and providing the results within the resource tree.

Interworking Proxy (IPE)

A special kind of application -- in a matter of speaking -- is an IPE. An IPE allows to translate data from a non-oneM2M domain to a oneM2M domain.

An example for an IPE could be an application that reads out sensor values from your sensor device by using a vendor-specific binary interface and translates it to oneM2M.

OpenMTC Gateway

A software node that is central to a particular small field domain that allows to collect data from various IPEs. A local application can access the resource tree, via the OpenMTC Gateway. It is possible to create a hierarchy of OpenMTC Gateways. This allows to travel data from one part in your IoT system to another one.

OpenMTC Backend

If you need a central software node within the infrastructure domain, the OpenMTC Backend is the exact choice. Usually, it acts as the root node within a hierarchy of OpenMTC Gateways.

OpenMTC Deployment

How to initialize OpenMTC for development?

This step-by-step tutorial assumes you have Ubuntu -- or any other Debian-based Linux distribution -- installed. Particularly, this guide works best with Ubuntu 16.04, Ubuntu 14.04 or Debian Jessie.

Your OpenMTC development setup may be based on running OpenMTC components with:

  • Docker (recommended)
  • purely based on Python

How to setup a development environment using Docker?

Note: If you do not have a running docker setup, we provide a docker installation guide. Alternatively you can use the official docker documentation. For this scenario, be sure to build Docker container images for following OpenMTC components:

  • sdk
  • gateway
  • backend

Building Docker container images for OpenMTC components

For the following, it is expected that the OpenMTC code repository is prepared in a directory named:


        OpenMTC
        

OpenMTC container images will be created through a hierarchy of dependent images. For example when creating image 'sdk', a dependent 'base' image will be created. After completing the build process for each Docker image, the image is to be found in the machine's local Docker repository. Be sure to have installed Docker.io in version 1.6.2 at minimum.


        cd OpenMTC
        ./create-binary-docker sdk
        ./create-binary-docker gateway
        

This will create Docker image for the machine's architecture and store them in the local Docker repository. These freshly generated Docker images will have names dependent on your architecture.

Crossbuilding OpenMTC Docker container images

Similarly to the last subsection, it is possible to crossbuild, for example, Docker images for ARM on an AMD64 machine. Therefore, an additional parameter needs to be provided to the create-binary-docker script.


        cd OpenMTC
        ./create-binary-docker --arch arm sdk
        ./create-binary-docker --arch arm gateway
        

Again, all freshly generated images are stored in the machine's local Docker repository. Note that these images will hold "/arm" in their names. It is possible to export these newly created Docker images and make them available to the target machine, by import. For a description on how to save newly created Docker images, see: How to save crossbuild Docker images. For a description on how to load a saved Docker image, on the target machine, see: How to load saved Docker images.

How to inspect freshly generated Docker images

TODO

How to save crossbuild Docker images

Disclaimer: Docker provides commands like export/import and save/load. Sadly, it is easy to get confused here. The command save is used to export a Docker image, while the command load is used to import this Docker image. Whereas, the commands export/import are to container instances. Assuming that the Docker images for OpenMTC Gateway and Backend are named as openmtc/gateway-arm and openmtc/backend-arm, it is possible to store these two images in one file, by using the following:


        # Assuming this to be executed on the crossbuild host machine
        # Additionally assuming, you have enough file space in /tmp available
        cd /tmp
        docker save -o openmtc-docker-images.tar openmtc/gateway-arm  openmtc/backend-arm
        

How to load saved Docker images

After you have copied the tar file that stores the above mentioned Docker images to the destination machine, use the following command to load them into the local Docker repository of the destination machine.


        # Assuming this to be executed on the crossbuild target machine
        # Additionally assuming, the tarfile was copied to /tmp directory
        cd /tmp
        docker load -i openmtc-docker-images.tar
        

OpenMTC development setup, for field domain only

The following figure describes a simple OpenMTC development setup. All data entities within a oneM2M system are represented as resources. All resources are hierarchical ordered within the resource tree. For this simple OpenMTC development setup, it is assumed that all resources from the Application Entity (AE) will be accessible via the OpenMTC Gateway. This means that the whole setup is placed in field domain only. Via the external REST API, a user is able to adjust the resource tree by using an HTTP client.

In the figure above, it is also shown that a developer will use the OpenMTC SDK to provides her own Application Entity (AE). This user-defined application entity is able to access functionality of the OpenMTC Gateway by using the SDK's internal API. A developer that wants to develop an AE may use this simplified development setup. Therefore, the developer will need to run an OpenMTC Gateway. This can be achieved easily by using the prepare Docker images:


        docker run -d --name gateway  -p 0.0.0.0:8000:8000  -e "EXTERNAL_IP="  \
            -e "LOGGING_LEVEL=DEBUG"    openmtc/gateway-arm -vv
        
  • If you need to make the OpenMTC Gateway accessible to outside of your host machine, use <EXTERNAL_IP> to configure this.
  • Note that the Docker image name openmtc/gateway-arm may vary on your machine. Use docker images to identify the Docker image name you need to use here.
  • If you need to know more about detail of -d (detach) and the port mapping configuration -p 0.0.0.0:8000:8000, check out the documenation as provided by Docker. If you already want to start with OpenMTC development, jump to How to test your development setup?.

OpenMTC development setup, for infrastructure domain

The following figure depicts a more complex setup of OpenMTC. Here, the focus on AE development for infrastructure domain. The following figure depicts this setup.

Here, the simple setup from the last subsection is extended. An AE in the field domain acts as a producer of data. Within this example, another AE is developed that acts as data consumer in the infrastructure domain. Therefore, an OpenMTC Backend will be used by the AE in infrastructure domain, to subscribe to the data from the field domain.

For this setup the developer will need to provide,

  1. An OpenMTC Backend

        docker run -ti --name backend -p 0.0.0.0:18000:18000 -e "ONEM2M_CSE_ID=" \
         -e "ONEM2M_NOTIFICATION_DISABLED=false" openmtc/backend-arm -v
        
  • <CSE_ID> : The CSE_ID of the Backend (e.g. backend)
  1. An OpenMTC Gateway (note that this configuration is different to the one from the last example, due to the connection to the OpenMTC Backend)

        docker run -d --name gateway -p 0.0.0.0:8000:8000 -e "EXTERNAL_IP=" \
           -e "ONEM2M_HTTP_TRANSPORT_PORT=8000"    -e "ONEM2M_CSE_ID=" \
           -e "ONEM2M_REMOTE_CSE_POA="        -e "ONEM2M_REMOTE_CSE_ID="  \
           -e "ONEM2M_NOTIFICATION_DISABLED=false" -e "ONEM2M_REGISTRATION_DISABLED=false" \   
           openmtc/gateway-arm -v
        
  • IP configuration: <EXTERNAL_IP>
  • <CSE_ID> : The CSE_ID of the Gateway (e.g. gateway)
  • <REMOTE_CSE_ID> : The CSE_ID of the Backend (e.g. backend)
  • <POA> : An URL that describes the POA fo Backend (e.g. "http://localhost:18000")
  • If you need to know more about detail of -d (detach) and the port mapping configuration -p 0.0.0.0:8000:8000, check out the documentation as provided by Docker.

The oneM2M MQTT Client

In addition to the oneM2M HTTP Client, the OpenMTC application framework features an MQTT client.

About MQTT

MQTT is short for “Message Queue Telemetry Transport,” a protocol that has originally been developed by IBM as a means of transportation for data in sensor networks. In contrast to HTTP, MQTT does not work in a request-response-manor; a publish-subscribe-approach is being embraced instead. For the protocol to work, an intermediary called “Broker” is required: Its role is to accept messages from connected clients and relay them among existing subscriptions. Through this centralised structure, communication through MQTT will always require at least one additional peer in comparison to other protocols supported by the framework. Setting up a broker is imperative, but due to the wealth of available solutions well outside the scope of this document. Exhaustive testing has been conducted against Moquette, which allows interoperability to be pretty much guaranteed for version 0.8+. For a quick start (or testing), you may use an openly available public broker such as iot.eclipse.org. It goes without saying that message confidentiality on public infrastructure is nil. Hence, those brokers do not present an option in production environments. Doing so is hereby strongly discouraged. In the event of a reduced-complexity, low-maintenance set-up being desired, using a docker image were recommended over a public broker. There is no absolute requirement on docker, though.
OpenMTC MQTT Architecture

Working With The MQTT Client

The OneM2MMQTTClient class implements protocol binding in accordance to TS-0010 akin to OneM2MHTTPClient. The two classes have been designed to work interchangeably from an application standpoint; differences in behaviours should be strictly related to the respective underlying transport protocols. Actual low-level MQTT handling is performed by the paho mqtt library. Users are encouraged to open issues with that project in case of pure MQTT havoc.

Establishing Connectivity

Although the interfaces of both, OneM2MHTTPClient and OneM2MMQTTClient are identical, addressing endpoints varies drastically. Through the necessity of a broker commonly reachable by two peers, said broker has to be the endpoint instead of the peer's machines. Subsequently, an address suitable for OneM2MMQTTClient can in general not be crafted by merely substituting http:// with mqtt://. (A notable exception is a set-up in which all peers - including the broker - are located on one and the same machine.) For a simple set-up of one AE and one CSE, proceed as follows:

Broker

Either you use an external broker like iot.eclipse.org (see link for information) or you can set up a local one. An example for a docker-based broker can be found here. Just start it with the following command (assumes docker is already installed):


        $ docker run -d -p 1883:1883 renarj/mqtt:latest
        

The following example assumes you have a local broker. Otherwise exchange localhost with iot.eclipse.org.

Gateway (MN-CSE)

  1. Locate the config-gateway.json configuration file
  2. Find the plugins.openmtc_cse.MQTTTransportPlugin entry
  3. Change disabled to false:

        {
          "name": "MQTTTransportPlugin",
          "package": "openmtc_cse.plugins.transport_gevent_mqtt",
          "disabled": false,
          "config": {
            "interface": "localhost",
            "port": 1883
          }
        },
        

Hint: A gateway is not locked in a single protocol. Multiple transport plugins can be active at the same time, allowing for a CSE to be reachable through a set of protocols. ⚠️ Warning: For the sake of brevity, localhost is set as broker. Please consider the introduction on MQTT regarding the ramifications.

  1. Start the gateway through the run-gateway script On a related note, enabling the plugin in the backend (IN-CSE) is done in an almost identical way: Just read config-backend.json in step 1 and run-backend in step 4. To have the gateway registered to the backend via MQTT you have to change the Registration Plugin. Here the poa and own_poa entries like the following example:

        {
            "name": "RegistrationHandler",
            "package": "openmtc_cse.plugins.registration_handler",
            "disabled": false,
            "config": {
                "labels": [
                    "openmtc"
                ],
                "remote_cses": [
                    {
                        "cse_id": "in-cse-1",
                        "poa": [
                            "mqtt://localhost:1883"
                        ],
                        "own_poa": [
                            "mqtt://localhost:1883"
                        ],
                        "cse_base": "onem2m",
                        "cse_type": "IN_CSE"
                    }
                ],
                "interval": 3600,
                "offset": 3600
            }
        },
        

Application Entity

Programmatically, it is sufficient to create an instance of OneM2MMQTTClient with a given endpoint. In adoption of example 8a:


        from openmtc_onem2m.client.mqtt import OneM2MMQTTClient
        client = OneM2MMQTTClient("mqtt://localhost#mn-cse-1")
        

All subsequent examples should be modifiable in the same fashion in order to enable MQTT support. In general, adjusting endpoints and providing the proper client is concluding the required steps. Please note the particle of the endpoint's URL being the name of a CSE. Due to the addressing scheme in oneM2M/MQTT, a requesting entity has to know the responding entities name in advance. It should be duly noted that this is a workaround neither mandated nor sanctioned by TS-0010. In fact, the semantics of particles in MQTT-URLs are entirely undefined. This inconvenience may or may not vanish in future releases.

Using Training Applications

Also the existing training applications can be re-used which can be found under doc/training/apps/onem2m. The four applications which end with -final.py can be changed in order to use the starting script under doc/training/start-app.sh. One example would be onem2m-gui-sensors-final.py. Beware, that this AE is configured to be connected to the backend. If you want to change this, you can use mn-cse-1 instead of in-cse-1 or use the TestIPE AEs. Change the last few lines from


        host = 'http://localhost:18000'
        app = TestGUI(
            poas=['http://localhost:21345'],          # adds poas in order to receive notifications
            # SSL options
            originator_pre='//openmtc.org/in-cse-1',  # originator_pre, needs to match value in cert
            ca_certs='../../openmtc-gevent/certs/ca-chain.cert.pem',
            cert_file='certs/test-gui.cert.pem',      # cert file, pre-shipped and should match name
            key_file='certs/test-gui.key.pem'
        )
        Runner(app).run(host)
        

to


        host = 'mqtt://localhost:1883#in-cse-1'
        app = TestGUI(
            poas=['mqtt://localhost:1883'],          # adds poas in order to receive notifications
            # SSL options
            originator_pre='//openmtc.org/in-cse-1',  # originator_pre, needs to match value in cert
            ca_certs='../../openmtc-gevent/certs/ca-chain.cert.pem',
            cert_file='certs/test-gui.cert.pem',      # cert file, pre-shipped and should match name
            key_file='certs/test-gui.key.pem'
        )
        Runner(app).run(host)
        

The change in host makes the AE to communicate with the backend (IN-CSE) via the broker. The change in poas lets notifications handled by the broker as well.

Further Reading

Authentication Guide

Enable Authentication using HTTPS at the backend CSE and gateway CSE

To enable authentication the following parameters need to be changed in the configuration files of the backend CSE and gateway CSE named config-backend.json and config-gateway.json. The configuration files are located in the openmtc-open-source/openmtc-gevent directory. In the plugins section of each configuration file the HTTPTransportPlugin needs to be enabled. Therefore, make sure the disabled option of the plugin is set to false. Set the option enable_https to true in the config of the HTTPTransportPlugin to enable HTTPS. If the option require_cert is set to true, the client that requests the gateway must provide a certificate.

Example of the gateway CSE configuration:


        "plugins": {
                "openmtc_cse": [
                    {
                        "name": "HTTPTransportPlugin",
                        "package": "openmtc_cse.plugins.transport_gevent_http",
                        "disabled": false,
                        "config": {
                            "enable_https": true,
                            "interface": "::",
                            "port": 8000,
                            "require_cert": true
                        }
                    },
        

The necessary SSL parameters used for the HTTPS/SSL connection must be specified in the ssl_certs option in the onem2m section of the corresponding configuration file. This option includes the private key (key), the certificate (crt) and the certificate chain (ca). Pre-shipped keys, certificates and a chain file which can be used at the gateway CSE and the backend CSE are located in the openmtc-open-source/openmtc-gevent/certs directory.

Example of the SSL parameters configured at the gateway CSE:


        "onem2m": {
                "accept_insecure_certs": false,
                "cse_base": "onem2m",
                "cse_id": "mn-cse-1",
                "cse_type": "MN-CSE",
                "overwrite_originator": {
                    "enabled": false,
                    "originator": "/openmtc.org/mn-cse-1"
                },
                "sp_id": "openmtc.org",
                "ssl_certs": {
                    "ca": "certs/ca-chain.cert.pem",
                    "crt": "certs/mn-cse-1-client-server.cert.pem",
                    "key": "certs/mn-cse-1-client-server.key.pem"
                }
            },
        

Registering the gateway CSE to the backend CSE using HTTPS

The RegistrationHandler plugin is responsible to register the gateway CSE to the backend CSE. Therefore, the plugin needs to be enabled by setting the disabled option to false. Furthermore, when HTTPS is enabled at both CSEs the options poa and own_poa needs to be changed to https://... in the config section of the RegistrationHandler plugin.


        {
                        "name": "RegistrationHandler",
                        "package": "openmtc_cse.plugins.registration_handler",
                        "disabled": false,
                        "config": {
                            "interval": 3600,
                            "labels": [
                                "openmtc"
                            ],
                            "offset": 3600,
                            "remote_cses": [
                                {
                                    "cse_base": "onem2m",
                                    "cse_id": "in-cse-1",
                                    "cse_type": "IN_CSE",
                                    ,
                                    "own_poa": [
                                        "https://localhost:8000"
                                    ],
                                    "poa": [
                                        "https://localhost:18000"
                                    ]
                                }
                            ]
                        }
                    },
        

Authentication of AEs/IPEs

When HTTPS is enabled in the configuration of the CSEs the AEs/IPEs must provide SSL information as well to perform requests to the CSEs. Using the OpenMTC application framework AEs and IPEs derive from the provided base class openmtc_app.onem2m.XAE. When creating an instance of the AE/IPE the following additional SSL parameter can be specified:

  • ca_certs: the certificate chain file
  • cert_file: the certificate file
  • key_file: the private key file
  • originator_pre: the originator which needs to match the subjectAltName value in the certificate If all SSL parameters are specified, the AE/IPE is started by the application framework using an HTTPS client.

Example from the onem2m-gui-sensors-actuators-final.py training IPE:


        host = 'https://localhost:8000'
            app = TestIPE(
                poas=['https://localhost:21346'],          # adds poas in order to receive notifications
                # SSL options
                originator_pre='//openmtc.org/mn-cse-1',  # originator_pre, needs to match value in cert
                ca_certs='../../openmtc-gevent/certs/ca-chain.cert.pem',
                cert_file='certs/test-ipe.cert.pem',      # cert file, pre-shipped and should match name
                key_file='certs/test-ipe.key.pem'
            )
        

Request information using curl when HTTPS is enabled

In general requests are performed just the same as presented in the REST API Guide. But, when HTTPS is enabled additional SSL options need to be provided by the client to the CSE. When using curl as client add the following options:

  • --cert: the client certificate
  • --key: the private client key
  • --cacert: the certificate chain
  • -H: set Header Fields, used to set the X-M2M-Origin header mapped as the originator

Example curl request


        curl https://localhost:8000/onem2m -v --cert test-ae.cert.pem --key test-ae.key.pem --cacert ca-chain.cert.pem -H "X-M2M-Origin: //openmtc.org/mn-cse-1/CTest-AE"
        

Notes

If the option require_cert in the HTTPTransportPlugin config is set to false, the client does not need to present a certificate. Therefore, the curl option --cert and --key are not needed when sending a request to the CSE. Example:


        curl https://localhost:8000/onem2m -v --cacert ca-chain.cert.pem -H "X-M2M-Origin: //openmtc.org/mn-cse-1/CTest-AE"
        

curl performs SSL certificate verification by default, using a "bundle" of Certificate Authority (CA) public keys (CA certs). Using the --cacert option the "bundle" file which is used for verification can by specified. In the above example this option is used and the certificate presented by the server to the curl client is verified. Nevertheless, curl's verification of the server certificate can be turned off, using the -k (or --insecure) option. Example:


        curl https://localhost:8000/onem2m -v -H "X-M2M-Origin: //openmtc.org/mn-cse-1/CTest-AE" --insecure
        

Installation of the OpenMTC SDK

Requirements

  • Python (only version 2.7 is supported)

Note: Only the CPython implementation (the default interpreter) of Python has been tested. PyPy might work as well, possibly with some minor adjustments. Jython is known not to work since it lacks support for compiled extensions.

In order to install the gevent package, development headers for both python and libev as well as a C-Compiler and associated toolchain might be required. To install these along with the pip tool the following commands might be used: Debian based systems (including Ubuntu):


        $ sudo apt-get install python-pip libev-dev python-dev gcc make automake
        

Redhat based systems (including Fedora, Centos):


        $ sudo yum install python-pip libev-devel python-devel gcc make automake
        

Additionally, some required Python packages need to be installed. The following command line should suffice to install the required packages:


        $ pip2 install --user --requirement openmtc-open-source/openmtc-gevent/dependencies.txt
        

Installing

To install the OpenMTC SDK itself the following steps need to be performed: Change to the SDK's distribution directory:


        $ cd openmtc-open-source
        

Run the installer command:


        $ sudo python setup-sdk.py install
        

Testing the Installation

The following command can be used to test if the OpenMTC SDK has been correctly installed:


        $ python2 -c "import openmtc; import openmtc_app"
        

If the SDK has been installed correctly, this command will exit successfully (exit code 0) and not produce any output.

Overview REST API

Introduction

This document gives a quick overview on how the external interfaces of an OpenMTC Gateway can be used to create new resources within an OpenMTC M2M system. Based on the same external interface, it is also shown how data can be retrieved from it. In general, all functionality of a Gateway is exposed via the resource tree. This resource tree is accessible in a RESTful manner through a HTTP interface. Thus, all examples in this document can be performed with standard off-the-shelve HTTP client software (curl, postman).

HTTP Requests and Responses as Given in this Text

Within the step-by-step guide further below in this text, each HTTP request and response are shown as their actual textual representation -- unimportant details are omitted. A short (theoretical) example will help you to understand this.
Request


        GET /some-example  HTTP/1.1
        Host: localhost:8000
        

This example, describes a GET request, based on HTTP/1.1, which is send to the host localhost at port 8000 and requests the resource /some-example. Another example, outlines how a POST request will look like. Here, an HTTP/1.1-based POST request will send the below specified JSON to host localhost at port 8000 and requests to send it to resource /some-example.
Request


        POST /some-example  HTTP/1.1
        Host: localhost:8000
        Content-Type: application/vnd.onem2m-res+json
        {
          "some-data": "some-string-value"
        }
        

Example usage of HTTP clients

To be able to send the (theoretical) requests, given in the last subsection, cURL may be used, which is a command line program usable as HTTP client.

Retrieve a resource


        curl -X GET localhost:8000/some-example
        

Here, the request command GET is send to localhost at port 8000, requesting the resource "/some-example". If data was successfully retrieved, by this, it will be printed to STDOUT.

Push plain text data to a resource


        curl -X POST localhost:8000/some-example \
         -H "Content-Type: application/vnd.onem2m-res+json" \
         -d '{ "some-data": "some-string-value" }'
        

Here, plain text (JSON) data (-d) is pushed to the resource "/some-example", by using the HTTP request command POST. Note that the content type of the given data is specified via an additional HTTP header (-H). If the provided JSON was successfully uploaded, a new content instance for this resource is provided.

Push base64 encoded data to a resource

Sometimes, it is needed to encode given data -- for example a JSON -- as a base64 string. This can be done, at the command line, in the following way:


        echo '{ "some-data": "some-string-value" }' | base64
        

Which will return following base64 encoded string: eyAic29tZS1kYXRhIjogInNvbWUtc3RyaW5nLXZhbHVlIiB9Cg== Pushing the same data as from the last subsection as a base64 encoded string will work like this:


        curl -X POST localhost:8000/some-example \
         -H "Content-Type: application/vnd.onem2m-res+json" \
         -d 'eyAic29tZS1kYXRhIjogInNvbWUtc3RyaW5nLXZhbHVlIiB9Cg=='
        

If you need to do this as a single line command, just combine the two last commands in the following way:


        curl -X POST localhost:8000/some-example \
         -H "Content-Type: application/vnd.onem2m-res+json" \
         -d $(echo '{ "some-data": "some-string-value" }' | base64)
        

A step-by-step Guide for OpenMTC's Rest API

Step 1: Create a new application entity within a given OpenMTC Gateway: AE creation.

Step 2: Check the stored information about your newly created application entity: Application Resource Retrieval.

Step 3: To be able to structure information provided by your newly created application entity, you should create a new oneM2M container within the hierarchy of your application: Create an Application Resource.

Step 4: Check whether your newly created oneM2M container was created correctly: Retrieve Information of a Specific Container Resource.

Step 5: Push new data (content instance) to your newly created application container. If your new content instance is supposed to store plain text value: Create plain text value Content Instance. If your new content instance is supposed to store base64-encoded values: Create base64-encoded Content Instance.

Step 6: Finally, check whether your data (content instance) was pushed correctly: Retrieve Latest Content Instances.

Create an Application Resource

Request


        POST /onem2m
        Host: localhost:8000
        Content-Type: application/vnd.onem2m-res+json
        {
          "m2m:ae": {
            "rn": "EXAMPLE_APP_NAME",
            "api": "placeholder",
            "rr": "TRUE"
          }
        }
        

Response


        {
          "m2m:ae": {
            "ri":"ae1",
            "nl":"dummy",
            "rr":true,
            "ty":2,
            "et":"2017-03-02T16:46:13.350093+00:00",
            "lt":"2017-03-02T16:12:53.350093+00:00",
            "api":"placeholder",
            "aei":"C1",
            "pi":"cb0",
            "rn":"EXAMPLE_APP_NAME",
            "ct":"2017-03-02T16:12:53.350093+00:00"
          }
        }
        

Retrieve Information of a Specific Application Resource

Request


        GET /onem2m/EXAMPLE_APP_NAME  HTTP/1.1
        Host: localhost:8000
        

Response


        {
          "m2m:ae": {
            "ri":"ae0",
            "nl":"dummy",
            "rr":true,
            "ty":2,
            "et":"2017-03-02T16:54:10.097197+00:00",
            "ch": [{
                "typ":3,"nm":"EXAMPLE_CONTAINER_NAME",
                "val":"cnt0"
            }],
            "lt":"2017-03-02T16:20:50.097197+00:00",
            "api":"placeholder",
            "aei":"C0",
            "pi":"cb0",
            "rn":"EXAMPLE_APP_NAME",
            "ct":"2017-03-02T16:20:50.097197+00:00"
          }
        }
        

Create a Container Resource

Request


        POST /  HTTP/1.1
        Host: localhost:8000
        Content-Type: application/vnd.onem2m-res+json
        { "m2m:cnt": {
          "rn": "EXAMPLE_CONTAINER_NAME"
          }
        }
        

Response


        {
          "m2m:cnt": {
            "cr":"nobody",
            "et":"2017-03-02T16:54:19.216702+00:00",
            "ty":3,
            "lt":"2017-03-02T16:20:59.216702+00:00",
            "rn":"EXAMPLE_CONTAINER_NAME",
            "ct":"2017-03-02T16:20:59.216702+00:00",
            "ri":"cnt0",
            "cni":0,
            "cbs":0,
            "pi":"ae0",
            "st":"0"
          }
        }
        

Retrieve Information of a Specific Container Resource

Request


        GET /onem2m/EXAMPLE_APP_NAME/EXAMPLE_CONTAINER_NAME  HTTP/1.1
        Host: localhost:8000
        

Response


        {
          "m2m:cnt": {
            "cr":"nobody",
            "et":"2017-03-02T16:54:19.216702+00:00",
            "ty":3,
            "lt":"2017-03-02T16:20:59.216702+00:00",
            "rn":"EXAMPLE_CONTAINER_NAME",
            "ct":"2017-03-02T16:20:59.216702+00:00",
            "ri":"cnt0",
            "cni":0,
            "cbs":0,
            "pi":"ae0",
            "st":"0"
          }
        }
        

Create a Plain-Text Content Instance

Request


        POST /onem2m/EXAMPLE_APP_NAME/EXAMPLE_CONTAINER_NAME/  HTTP/1.1
        Host: localhost:8000
        Content-Type: application/vnd.onem2m-res+json
        {
          "m2m:cin": {
            "con": "EXAMPLE_VALUE",
            "cnf": "text/plain:0"
          }
        }
        

Response


        {
          "m2m:cin": {
            "ri":"cin1",
            "ty":4,
            "st":"0",
            "cnf":"text/plain:0",
            "lt":"2017-03-02T16:37:23.963247+00:00",
            "et":"2017-03-02T17:10:43.963247+00:00",
            "cs":13,
            "pi":"cnt0",
            "rn":"contentInstance-v2HDJeljran3jxPX",
            "con":"EXAMPLE_VALUE",
            "ct":"2017-03-02T16:37:23.963247+00:00"
          }
        }
        

Create a Base64-Encode Content Instance

For this subsection it is assumed that data represented as JSON will used to create a new content instance. Therefore, following example data:


        {
          "foo": 42, "bar": 42
        }
        

needs to be trans-coded to its base64 string:


        eyJmb28iOiA0MiwgImJhciI6IDQyfQo=
        

To be able to execute the trans-coding, be reminded of subsection Push base64 encoded data to a resource.

Request


        POST /onem2m/EXAMPLE_APP_NAME/EXAMPLE_CONTAINER_NAME/  HTTP/1.1
        Host: localhost:8000
        Content-Type: application/vnd.onem2m-res+json
        {
          "m2m:cin": {
          "con": "eyJmb28iOiA0MiwgImJhciI6IDQyfQo=",
          "cnf": "application/json:1"
          }
        }
        

Response


        {
          "m2m:cin": {
            "ri":"cin2",
            "ty":4,
            "st":"0",
            "cnf":"application/json:1",
            "lt":"2017-03-02T16:41:02.060806+00:00",
            "et":"2017-03-02T17:14:22.060806+00:00",
            "cs":32,
            "pi":"cnt0",
            "rn":"contentInstance-ccUmIDHZ2jvtUWyQ",
            "con":"eyJmb28iOiA0MiwgImJhciI6IDQyfQo=",
            "ct":"2017-03-02T16:41:02.060806+00:00"
          }
        }
        

Retrieve Latest Content Instances

Request


        GET /onem2m/EXAMPLE_APP_NAME/EXAMPLE_CONTAINER_NAME/latest  HTTP/1.1
        Host: localhost:8000
        

Response


        {
          "m2m:cin": {
            "ri":"cin2",
            "ty":4,
            "st":"0",
            "cnf":"application/json:1",
            "lt":"2017-03-02T16:41:02.060806+00:00",
            "et":"2017-03-02T17:14:22.060806+00:00",
            "cs":32,
            "pi":"cnt0",
            "rn":"contentInstance-ccUmIDHZ2jvtUWyQ",
            "con":"eyJmb28iOiA0MiwgImJhciI6IDQyfQo=",
            "ct":"2017-03-02T16:41:02.060806+00:00"
          }
        }
        

Reference: Short Resource names and Resource types

Resource names and types provides a reference of how names of resources are mapped to their short names but also provides a table that reveals the numerical representation of resource types.

Write your first OpenMTC applications

Introduction

OpenMTC is delivered with some incremental demo applications which can be consulted for further understanding or as template for other applications. The oneM2M demo applications can be found in the OpenMTC Repository on Github. The training is subdivided into examples for GUI-applications and IPE-applications. Both of these provide incremental demo applications for either sensor-actuator-applications or only sensor-applications. These are explained in the following sections.

The start-app Script

The training folder contains the start-app.sh script. This script allows to run one of the four complete demo applications:


        user@host:/git$ ./openmtc-open-source/doc/training/start-app.sh
        [1] onem2m-ipe-sensors-final.py
        [2] onem2m-ipe-sensors-actuators-final.py
        [3] onem2m-gui-sensors-final.py
        [4] onem2m-gui-sensors-actuators-final.py
        Choose the app to start:
        

Getting started

First of all, OpenMTC needs to be install on your system. If you have not yet installed OpenMTC, please do so following these instructions.

Sensor only demo applications

To run the sensor only demo application, you will need four consoles. Proceed in the following order, since both the IPE and the GUI require a running CSE. Console 1: Backend

  • start the Backend by executing the following:
  • ./openmtc-open-source/openmtc-gevent/run_backend
  • After you started all four consoles, you should get something like this. Console 2: Gateway
  • start the Gateway by executing the following:
  • ./openmtc-open-source/openmtc-gevent/run_gateway
  • After you started all four consoles, you should get something like this. Console 3: IPE
  • start the IPE by executing the following:
  • ./openmtc-open-source/doc/training/start-app.sh
  • type 1
  • you should get something like this. Console 4: GUI
  • start the GUI by executing the following:
  • ./openmtc-open-source/doc/training/start-app.sh
  • type 3
  • you should get something like this.

Sensor-Actuator demo applications

To run the sensor-actuator demo application, you will also need four consoles. Proceed in the following order, since both the IPE and the GUI require a running CSE. Console 1: Backend

  • start the Backend by executing the following:
  • ./openmtc-open-source/openmtc-gevent/run_backend
  • After you started all four consoles, you should get something like this. Console 2: Gateway
  • start the Gateway by executing the following:
  • ./openmtc-open-source/openmtc-gevent/run_gateway
  • After you started all four consoles, you should get something like this. Console 3: IPE
  • start the IPE by executing the following:
  • ./openmtc-open-source/doc/training/start-app.sh
  • type 2
  • you should get something like this. Console 4: GUI
  • start the GUI by executing the following:
  • ./openmtc-open-source/doc/training/start-app.sh
  • type 4
  • you should get something like this.

IPE demo applications

IPE stands for Interworking Proxy Application Entity. The IPE demo applications attaches (virtual) sensors and (virtual) actuators to the CSE by sending (simulated) sensors readings and receiving and processing commands meant for (virtual) actuators attached to the hardware this IPE demo app is running on. The IPE demo applications are available as sensor-actuator-applications or only as sensor-applications. Incremental IPE demo applications

GUI demo applications

GUI stands for Graphical User Interface. This is somewhat misleading, as these demo apps do not provide a real GUI. These GUI demo applications rather provide a textual user interface which receives (and eventually displays to the user) the (virtual) sensor data provided by the ipe-demo-apps. Further, they send commands to the (virtual) actuators attached to the ipe-demo-apps. The GUI demo applications are available as sensor-actuator-applications or only as sensor-applications. Incremental GUI demo applications

Appendix

Howto install Docker on Ubuntu

Docker is a software container solution used to provide operating-system-level virtualization. It is possible for all OpenMTC components to run within a Docker container. To make this possible, a script is provided to allow a user to build Docker container images. Be aware that during the build process the build machine has to have access to the Internet, since various Docker container image dependencies are pulled. For a general introduction to Docker, see: Get Started with Docker.

Install and Prepare Docker

For the build script to work, Docker needs to be installed. There are two different approaches to installing Docker on your system.

  1. Use the OS package manager to install docker.io package
  2. Use installer from Docker.com to install freshest version of Docker

Use the first method whenever your OS package manager provides a more recent of Docker. If this not the case, e.g. in Ubuntu 14.04, use the second approach to install Docker.

Installing docker.io package in Ubuntu 16.04 or Debian testing via apt


        # Install docker on Debian-like systems
        sudo apt-get -y  install docker.io
        # Prepare a user for non-root access to Docker
        # If above installation did not create a 'docker' group, you may add
        # it manually.  Afterwards, you need to restart Docker for that
        sudo groupadd docker
        sudo service docker restart
        # Add a specific user to user group 'docker'
        sudo usermod -aG docker USER_NAME
        # Be sure to logoff and login that user, to make the group change to
        # kick in
        # Check if Docker runs properly, by using various docker commands, e.g.
        docker images
        docker ps
        # Use the Docker build commands in the next section for further
        # testing, if above commands were working properly.  If in the next
        # section Docker does not work properly, see below description.
        # If Docker does not work properly yet, try to restart it
        sudo systemctl stop docker
        sudo ip link set down docker0
        sudo ip link set up docker0
        sudo systemctl start docker
        # Still, not?  Is routing configured correctly?  Maybe try:
        sudo ip r add 172.17.0.0/16 dev docker0
        

Installing freshest Docker version via Docker.com installer

Use this particularly for Ubuntu 14.04.


        # Downloads an installation script and executes it
        # Be aware that within the script `sudo` is called
        curl -sSL https://get.docker.com | sh
        # Prepare your user account to use docker command
        #
        # 1. Add the specified user to user group 'docker'
        sudo usermod -aG docker USER_NAME
        # 2. Logout and re-login to the system so that the user account changes
        #    can "kick-in"