This Python 3 module implements a library to access and manage resources on a oneM2M CSE.
- Installation and Prerequisites
- Supported Features & Limitations
This Python3 module implements a library to access and manage resources on a oneM2M CSE.
oneM2M is a global partnership project that specifies a common service layer, called CSE, for M2M and the Internet of Things. In general, devices, services, applications, and data are organized in a resources tree, which is transported and synchronized through a network of nodes. This resource tree can be access via CRUD operations.
The application interface to the oneM2M's CSE is called Mca. This Python3 module implements an easy way to access a CSE via this interface.
For further information about oneM2M and its specifications see http://www.onem2m.org resp. http://www.onem2m.org/technical/published-documents
onem2mlib has been tested with the following oneM2M implementations:
- Eclipse om2m (feature0 branch)
More implementations should follow.
This module requires Python3.
Copy the onem2mlib directory to your project.
In addition you need to install the following modules:
Install with pip3:
pip3 install lxml
Install with pip3:
pip3 install lxml
Depending on the OS and target environment you might need to install some additional libraries:
apt-get install libxml2-dev libxslt1-dev
All this might take a very long time on a small system (such as a Raspberry Pi). Alternative you may install the library with the help of a package manager:
sudo apt-get install python3-lxml
Read the full module documentation.
Have a look at the examples in the examples directory on how to use the onem2mlib module.
The following sections provide some examples.
First, create a session and then retrieve a <CSEBase> resource from a CSE. The session holds, for example, the authentication information to access the CSE.
session = Session('http://host.com:8282', 'admin:admin'). # create a session cse = CSEBase(session, 'mn-cse') # get the <CSEBase> resource
To use XML encoding, specify the encoding explicitly for a session.
from onem2mlib.constants import * session = Session('http://host.com:8282', 'admin:admin', Encoding_XML). # create a session with XML encoding cse = CSEBase(session, 'mn-cse') # get the <CSEBase> resource
To access resources on a CSE it is not necessary to retrieve the <CSEBase> resource from the CSE (for example, when one has only limited access to resources on the CSE). But one must have at least create a CSEBase instance that represents the CSE and holds the session information as shown above. This CSEBase instance can be used as usual in subsequent calls.
The following example creates a CSEBase instance without actually retrieving the <CSEBase> resource. The resourceName attribute must be known and set explicitly in the constructor. The instantly=False argument must also be set; it prevents the retrieval of the actual resource (which, as explained above, might fail when there is only limited access to the CSE).
session = Session('http://host.com:8282', 'admin:admin'). # create a session cse = CSEBase(session, 'mn-cse', resourceName='mn-name', instantly=False) # create a CSEBase object, without retrieving it
The first example creates a new <AE> resource or, if an <AE> resource with the same name already exists in the CSE, that <AE> is returned. This method to get/create a resource is usually sufficient in most cases.
ae = AE(cse, resourceName='aeName')
The second example is similar to the first, but offers the possibility to modify the resource object before sending it to the CSE. In general, the get() method creates a new or retrieves an existing resource.
ae = AE(cse, resourceName='aeName', instantly=False) # set more attributes here ae.get()
The last example also creates a new <AE> resource in the CSE, but does it explicitly. It fails (ie. returns False) in case a resource with the same name already exists.
ae = AE(cse, resourceName='aeName', instantly=False) # set more attributes here ae.createInCSE()
Add a container to an <AE> resource.
container = Container(ae, resourceName='myContainer')
And print them.
And add a <contentInstances> to each of them.
for cnt in ae.containers(): print(cnt) # Create and add a new <contentInstance> in one step ContentInstance(cnt, content='Some value')
There is also a shortcut for adding a new <contentInstance> to a <container>. So, the last line in this example could also be written like this:
And print it.
cin = container.latestContentInstance() if cin is not None: print(cin)
There is a short-cut in case you are only interested in the content.
Delete an <AE> resource and all its sub-resource from a CSE.
Add a subscription to a resource and receive notifications when the resource changes.
import onem2mlib.notifications as NOT def myCallback(resource): # Called for notifications, with the updated resource as the argument. ... # do something with the updated resource # In the main program: NOT.setupNotifications(myCallback) # Initialize the notification sub-module # The callback is the callback function above ... cnt = Container(ae) # Create a container cnt.subscribe() # Subscribe to changes of this resource cnt.addContent('Some value') # Add a new contentInstance # This implicitly triggers a call to 'myCallback' when the value us changed in the CSE
There could also be individual callbacks for each resource. Provide another function in the subscribe() method call.
def anotherCallback(resource): # Define a new callback function ... cnt.subscribe(anotherCallback) # Subscribe to changes of this resource, and provide a different callback function
Instead of a real callback function one can also specify a lambda function.
cnt.subscribe(lambda resource: print(resource)) # Subscribe to changes of this resource # Provide a lambda function to handle the callback
Remove a subscription by calling the unsubscribe() method:
cnt.unsubscribe() # Notifications for this resource will stop
The <remoteCSE> resource represents a remote CSE to which a "local" CSE is connected. A remote CSE with the resource name in-name can be retrieved like this:
remoteCSE = cse.findRemoteCSE('in-name')
The <remotsCSE> resource can be used to work with the remote CSE either directly or indirectly. Direct access means that all queries are directly send to the remote CSE, while with indirect access all queries go through the "local" CSE, which then internally routes these requests to the remote CSE.
In both cases one needs to get a cse instance.
# <CSE> resource for direct access directRemoteCSE = remoteCSE.cseFromRemoteCSE() # <CSE> resource for indirect access indirectRemoteCSE = remoteCSE.cseFromLocalCSE()
Both resources, directRemoteCSE and indirectRemoteCSE, can be used like a normal <CSE> resource as described above. The following example shows the use of both <CSE> resources.
# indirectly retrieve a list of <AE>'s from the remote CSE listOfAEs = indirectRemoteCSE.aes() # directly create a new <AE> resource on the remote CSE newRemoteAE = directRemoteCSE.addAE('remoteAE')
See also ROADMAP for open issues and planned enhancements.
The following resource types are supported in this version.
- Discovery: Currently, only label and resourceType are supported in filter criteria.
- Encodings: JSON (the default), XML.
- Notifications: A program can subscribe to resource changes, provide callback methods, and receive notifications from a CSE.
onem2mlib is released under the BSD 3-Clause License. See LICENSE for the full license text.