AmbientBridge Wiki - TVLuke/DynamixBridge GitHub Wiki
The AmbientBridge is an Android application that provides high level contextual data, generated on Android devices using the context framework Ambient Dynamix, via Internet Protocols to the other devices. It transforms the phone, and other ambient sensors which can be connected to the phone, into IoT (Internet of Things) devices, allowing access to the data from otherwise unreachable devices. The AmbientBridge supports CoaP and HTTP and will, in future releases also provide an atom-RSS Feed.
Contextual data is generated using the Ambient Dynamix-Framework, which provides this data in the form of context events. Context events are generated by plug-ins written by domain experts that can be installed into the framework on demand during runtime. Such plug-ins can provide information on the contextual state of a users surroundings or his activity to applications on the mobile phone. There are currently a host of plug-ins available, providing data on light-level, noise, recognizing spoken words or music playing in the background. Plug-ins may also control ambient actuators. You can find the official list of plug-ins on the Ambient Dynamix website. Dynamix-Plug-ins can, among other things, turn a phone into a sensor platform, providing data to installed applications or websites opened in the mobile browser. However, all this contextual data could only be used locally (in Apps and Websites) on the phone. The AmbientBridge offers a generic way to expose user-selected data-types, acquired via Ambient Dynamix, via Internet protocols with little or no configuration. The AmbientBridge does not send the data to specific receivers but runs a set of servers, making the data available. Thus the system is not depended on certain services on the web remaining active. In addition the AmbientBridge uses standards and protocols already supported by most devices, allowing for access to data with minimal effort.
The AmbientBridge is connects to Ambient Dynamix and collects data on available context types. It uses an additional repository to gather meta data on these context types such as human readable names, descriptions, and meta-data on the represented context data. The application allows to expose each context type individually selecting the used plug-ins. The data is available inside of the local network the phone is connected to via the protocols HTTP and CoaP. The AmbientBridge handles context updates, switching of networks and context requests in the background, requiring no user interaction.
Ambient Dynamix has to be installed before installing the AmbientBridge. When started the AmbientBridge will automatically start a HTTP and a CoaP server, and display the current local IP at the top of the main screen. The AmbientBridge will register to start on boot, the user is notified to the AmbientBridge running by a permanent notification. It will query Ambient Dynamix on start for available context-data types and present a list of these on the main screen.
The AmbientBridge will not provide any data type without prior user action. A Red, Orange or Yellow circle next to a data type shows, that the data is not provided. The AmbientBridge will always provide a overview service and the CoaP Well Known resource.
- A red circle denotes that the context is neither supported nor has it been requested
- An orange circle denotes that a context request has been made to Ambient Dynamix for this data type but no answer feedback from Ambient Dynamix has arrived
- A yellow circle denotes that Ambient Dynamix supports the context type but it is not yet made public
- A green circle denotes that the context data-type is being provided via CoaP or HTTP
To provide a data type, click on the data type in the list and activate it on the following screen.
The AmbientBridge automatically generates a resource called /service/dynamix/contexttypes
on all protocols it supports. In this resource a list of all available context types is given, including a small description of the context type.
If the context type is already provided by the AmbientBridge the URI for all supported protocols is given.
calling GET on coap://[yourIP]:[thePort]/service/dynamix/contexttypes(or http://[yourIP]:[thePort]/service/dynamix/contexttypes) returns a list of all available context types.
The dafault Port for HTTP is 8081, coap is by default on 8082. Resource Names
Resources are named by using the ids of the context types from Ambient Dynamix, this provides a clear matching (the . from the type is replaced by a / for the URL). So the data-type org.ambientdynamix.contextplugins.context.environment.currenttime would be found under the URI coap://ip:port/org/ambientdynamix/contextplugins/context/environment/currenttime (for http just replace "coap" with "http")
Requesting Context
A simple context request is made with a GET on the resource of a data type. This will return the current context is the data type is exposed.
Configured Context Request
Ambient Dynamix allows for Context Requests to be configured using Android Bundles. A configures request is used to gather context with certain parameters, for example specifying the devices to be used or the configuration data for the plug-in (passwords, usernames, URLs...). To request a configured context type the configuration information has to be submitted to the AmbientBridge to be further transmitted via Ambient Dynamix to the Plug-in. These parameters are submitted in the Body of POST Requests via CoaP or HTTP. Atom will not support configured context.
Requesting Configured Context is done via POST using a json encoded String.
For example the Ambient Light could be adjusted to red using the ArtNet Light Controller Plugin or with the Philips Hue Plug-in with the String
{
"token": "abcdefg",
"String":
{
"action_type": "setcolor",
"r_channel:"255",
"g_channel":"0",
"b_channel":"0",
}
}
The first pair in the json String ist a token, this is a voluntary element. Currently, the AmbientBridge does not use any verification and does not implement any protocolling so the token is ignored.
The DynamixBrdige allows for String, char, int, long, float, double, byte, boolean and short as well as Arrays of these json Arrays.
Requesting Context Subscription via the AmbientBridge
While it is possible to request the current status of a plug-in or observe context events as described above it is also possible to request the Bridge to provide new context types. For this purpose the /service/dynamix/contexttype
can be used, using PUT.
The semantics are as follows:
{
String:
{
"action_type": "subscribe",
"context_type": "org.ambientdynamix.contextplugins.context.info.environment.currentsong",
},
}
will send a request to subscribe to the currentsong context type and make the data public. To unsubscribe the request body would be:
{
String:
{
"action_type": "unsubscribe",
"context_type": "org.ambientdynamix.contextplugins.context.info.environment.currentsong",
},
}
The user of the phone to which a request to subscribe was made will get a notification. He can decide to subscribe, generating an new resource, or he can decide not to subscribe.
Context Data
When requesting context data from an Ambient Dynamix plug-in the data is returned in a textual representation that is extracted from the POJO that has been generated from the context plug-in. Plug-in designer can format this data by defining a response.
If no response in a standard format (plain text, xml, json, n3...) is available the AmbientBridge will try to create the representation on its own.
The Return may be formated using XML, using a structure lik this:
<contextevent>
<contextType>
<id>[Id of the context type]</id>
<createdAt>[long timestamp]</createdAt>
<expires>[true|false]</expires>
<expiresAt>[long timestamp]</expiresAt>
<source>
<plugin>
<pluginId>[plugin id]</pluginId>
<pluginName>[plugin name]</pluginName>
</plugin>
</source>
</contextType>
<contextData>
[The structure inside contextData depends on the specific context type]
</contextData>
</contextevent>
As an example the (Ping Plugin)[https://github.com/TVLuke/DynamixPingPlugin] which returns a String given as configuration data.
If the request looks like this:
{
String:
{
"action_type": "ping",
"id": "test",
},
}
The returned context data is formatted as follows:
<contextEvent>
<contextType>
<id>org.ambientdynamix.contextplugins.context.info.sample.ping</id>
<createdAt>1393416130207</createdAt>
<expires>false</expires>
<expiresAt>32950324930207</expiresAt>
<source>
<plugin>
<pluginId>org.ambientdynamix.contextplugins.pingplugin</pluginId>
<pluginName>Ping Plugin</pluginName>
</plugin>
</source>
</contextType>
<contextData>
<ping>test</ping>
</contextData>
</contextEvent>
Some Plugins alow for a representation as XML encoded RDF 1.0 Data. This representation is used prefereably to the other XML encoding if the plug-in offers it. It folows the foloing structure:
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:j.0="http://dynamix.org/semmodel/[SPECIFIC NAMESPACE]"
xmlns:j.1="http://dynamix.org/semmodel/0.1/" >
<rdf:Description rdf:about="http://dynamix.org/semmodel/0.1/DynamixPlugin/[NAMESPACE SPECIFIC TO THE PLUGIN]">
<j.1:hasName>[PLUGIN NAME]</j.1:hasName>
<rdf:type>http://dynamix.org/semmodel/0.1/DynamixPlugin</rdf:type>
<j.1:hasID>[PLUGIN ID]</j.1:hasID>
</rdf:Description>
<rdf:Description rdf:about="http://purl.org/device_ff348dc199555fff">
<rdf:type>http://purl.org/device/screenstatus</rdf:type>
<j.0:status>true</j.0:status>
</rdf:Description>
<rdf:Description rdf:about="http://dynamix.org/semmodel/0.1/ContextEvent/[EVENT ID]">
<j.1:hasData rdf:resource="http://purl.org/device_ff348dc199555fff"/>
<j.1:createdByPlugin rdf:resource="http://dynamix.org/semmodel/0.1/DynamixPlugin/[PLUGIN ID]"/>
<rdf:type>http://dynamix.org/semmodel/0.1/ContextEvent</rdf:type>
<j.1:ExpiresAt>[TIMESTAMP]</j.1:ExpiresAt>
<j.1:Expired>false</j.1:Expired>
<j.1:CreatedAt>[TIMESTAMP]</j.1:CreatedAt>
<j.1:hasContextType>[CONTEXT TYPE]</j.1:hasContextType>
</rdf:Description>
</rdf:RDF>
Here an example using the (Last.FM Plugin)[https://github.com/TVLuke/DynamixLastfmPlugin] which returtns data from a users Last.fm account.
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:j.0="http://dynamix.org/semmodel/org.ambientdynamix.contextplugins.context.info.environment.currentsong/0.1/"
xmlns:j.1="http://dynamix.org/semmodel/0.1/" >
<rdf:Description rdf:about="http://dynamix.org/semmodel/0.1/DynamixPlugin/org.ambientdynamix.contextplugins.lastfm">
<j.1:hasName>Last.fm Plugin</j.1:hasName>
<rdf:type>http://dynamix.org/semmodel/0.1/DynamixPlugin</rdf:type>
<j.1:hasID>org.ambientdynamix.contextplugins.lastfm</j.1:hasID>
</rdf:Description>
<rdf:Description rdf:about="http://www.lastfm.de/music/Megaloh/_/Loser">
<rdf:type>http://purl.org/ontology/mo/track</rdf:type>
<j.0:hasArtist>Megaloh</j.0:hasArtist>
<j.0:hasTitle>Loser</j.0:hasTitle>
<j.0:hasDuration>202000</j.0:hasDuration>
</rdf:Description>
<rdf:Description rdf:about="http://dynamix.org/semmodel/0.1/ContextEvent/org.ambientdynamix.contextplugins.context.info.environment.currentsong_1393420187775">
<j.1:hasData rdf:resource="http://www.lastfm.de/music/Megaloh/_/Loser"/>
<j.1:createdByPlugin rdf:resource="http://dynamix.org/semmodel/0.1/DynamixPlugin/org.ambientdynamix.contextplugins.lastfm"/>
<rdf:type>http://dynamix.org/semmodel/0.1/ContextEvent</rdf:type>
<j.1:ExpiresAt>1393420367775</j.1:ExpiresAt>
<j.1:Expired>false</j.1:Expired>
<j.1:CreatedAt>1393420187775</j.1:CreatedAt>
<j.1:hasContextType>org.ambientdynamix.contextplugins.context.info.environment.currentsong</j.1:hasContextType>
</rdf:Description>
</rdf:RDF>
Another Example for a Plugin returning semantic data is the (Screen Status Plugin)[https://github.com/TVLuke/DynamixScreenStatusPlugin], which tells the requersting patrty if a deviuces screen is on or off:
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:j.0="http://dynamix.org/semmodel/org.ambientdynamix.contextplugins.context.info.device.screen/0.1/"
xmlns:j.1="http://dynamix.org/semmodel/0.1/" >
<rdf:Description rdf:about="http://dynamix.org/semmodel/0.1/DynamixPlugin/org.ambientdynamix.contextplugins.screenstatus">
<j.1:hasName>Screen Status Plugin</j.1:hasName>
<rdf:type>http://dynamix.org/semmodel/0.1/DynamixPlugin</rdf:type>
<j.1:hasID>org.ambientdynamix.contextplugins.screenstatus</j.1:hasID>
</rdf:Description>
<rdf:Description rdf:about="http://purl.org/device_ff348dc199555fff">
<rdf:type>http://purl.org/device/screenstatus</rdf:type>
<j.0:status>true</j.0:status>
</rdf:Description>
<rdf:Description rdf:about="http://dynamix.org/semmodel/0.1/ContextEvent/org.ambientdynamix.contextplugins.context.info.device.screenstatus_1393416451779">
<j.1:hasData rdf:resource="http://purl.org/device_ff348dc199555fff"/>
<j.1:createdByPlugin rdf:resource="http://dynamix.org/semmodel/0.1/DynamixPlugin/org.ambientdynamix.contextplugins.screenstatus"/>
<rdf:type>http://dynamix.org/semmodel/0.1/ContextEvent</rdf:type>
<j.1:ExpiresAt>1393416453779</j.1:ExpiresAt>
<j.1:Expired>false</j.1:Expired>
<j.1:CreatedAt>1393416451779</j.1:CreatedAt>
<j.1:hasContextType>org.ambientdynamix.contextplugins.context.info.device.screenstatus</j.1:hasContextType>
</rdf:Description>
</rdf:RDF>
The specific syntax of some of this structure is up to the developer of the plugin who has to define the namespace and how to generate a semantic representation for the context returned by the plug-in.
Switching between networks
When switching between networks the system powers down all CoaP and HTTP servers and, after acquiring the new IP, powers them back up.
When outside a W-LAN (wifi) network, telecom-providers use NAT, which makes the "local" IP of a device unreachable for other devices. We are currently exploring solutions to that in another project, if found they will be included here.
Compression of Data Some Sensors may send data many times per second. Since the data is usually encoded in plain text, xml or json the bandwith may increase above a level that is reasonable. The AmbientBridge does not yet support any compression but there are plans to implement compression methods such as zip or alow to only transmit the diff between to events.
Several different methods exist to discover a resource in a network. Android 4.1+ implements Network Service Discover (NSD) and Wifi-Direct. The underlying protokoll of the NSD ist DNS-SD, a Discovery protocoll for which a multitude of libraries exists. It can be implemented on most devices capable of networking (if sufficiant storrage is avliable).
AmbientApplications can discover the AmbientBridge using DNS-Service Dicovery and interact with it then. An Example Java implementaion can be found here.
The CoaP implementation uses the nCoap Library by Oliver Kleine.
To test with CoaP you need a Firefox Browser and the "Copper-Cu"Addon, which enables the Browser to talk CoaP. After installing the Add-on and restarting Firefox, enter coap://[yourlocalIP]. When the Copper-Window has opened, press dicovery. You will now see the service/dynamix/contexttypes resource which is created by default.
Supported Media Types
When requesting data via CoaP one can choose from a host of media-types. If data is returned depends on whether or not this data type is supported by the implementation of the context data-type. Almost all support plain text, some support xml, few support json.
Note that it does not just depend on the data type but also which (of potentially many) plug-ins is currently providing the data type.
Observing changes in Context
All ContextTypes are implemented using so called observable CoaP-Resources which means, that one can observe these for changes. To test, select a resource that has been made available through the AmbientBridge and see how the changes appear on screen.
The implementation of the HTTP server uses RestExpress.
There are several add-ons for browsers to test HTTP/Rest APIs, I've been using the Rest Client FireFox Addon. Configuring the Rest Client Addon for Testing You start the rest client add-on by typing chrome://restclient/content/restclient.html into the address-bar.
To get started adding custom headers to your request to determine the format of the answer. if you want plain text you cannot use a header. otherwise the Name is "format" and the value either "xml" or "json".
Supported Media Types
When requesting data via HTTP one can choose from a host of media-types. If data is returned depends on whether or not this data type is supported by the implementation of the context data-type. Almost all support plain text, some support xml, few support json.
Note that it does not just depend on the data type but also which (of potential many) plug-ins is currently providing the data type.
Currently not supported at all, hopefully in future versions.
Lightswitch Demo The Lightswitch Demo is a small demo that shows how the AmbientBridge can be used via HTTP. It uses the Simple Artnet Plugin/Hue Plug-in. The Simple program is started using
java -jar SimpleLightSwitch.jar [yourIp]
It the connects to the phone and, if available, requests the artnet context type to be supported, if the type is supported it will push random colors every second.
The code can be found here.
Web Ambilight Chrome Extension
The Web Ambilight Chrome Extension can be installed in a chrome browser, it allows to connect to a mobile phone running the DynamixBridge in the local network and will set the light in the room to the background color of the website currently displayed using Ambient Dynamix and the Artnet Plug-in or the Hue Plug-in (or any other plug-in exposing the right context types).
Here is a little video of the extension in use. The code can be found here.
Some additional plug-ins to the ones supported by the Dynamix repository are
- Ping Plugin
- Sensordrone Plugin
- Current Time Active Plugin
- Current Time Passive Plugin
- ScreenStatus Plugin
- Running Applications Plugin
- Last.fm Plugin
- Device Information Plugin
- Philips Hue Plugin
- Whiteboard Storage Plugin
- FOAFPlugin
- UBA Station Plugin (Development discontinued)
- Withings Scale (Outdated)
I have a table of plugin-ins and their status (as last known to me) (here)[https://github.com/TVLuke/DynamixBridge/wiki/Plugin-Table]
You can use the repository under https://raw.github.com/TVLuke/DynamixRepository/master/repo.xml as an external Repository to add these not yet officially supported plug-ins.
DynamixBridge is also using the context-type Description file under https://raw.github.com/TVLuke/DynamixRepository/master/context.xml. This File provides additional data on Context types such as descriptions, web-references, user-friendly names more.
At this point the context description file is maintained by me, I hope to move it into the Ambient Dynamix repository infrastructure at some point.
##Performance A quick performance Test using the Ping Plugin has shown the following performance metrics:
- The Plugin will use about 2 miliseconds to create a ping
- Dynamix seems to add between 20 and 25 miliseconds delay
- The DynamixBridge (locally) seems to create a delay of about 75 milliseconds
- Inside a local network accessing the DynamixBridge via CoaP seems to be on average more then 0.1 seconds delay (but this depends a lot on network traffic)
All these times are under ideal conditions and have not been tested heavily yet.
Details on these experiments to follow.
The DynamixBridge can be used as a proxy to include sensors that do not "speak" CoaP into the Smart Service Proxy (SSP) by exposing a CoaP resource with the data provided by the plugins. To connect to the SSP a CoaP-Client is briefly started which connects to the SSP and facilitates the connection of the DynamixBridge's CoaP Server to the SSP.
The Smart Service Proxy gets "Semantic resources" which means it needs RDF as the sensor output. It is envisioned that, when the Plug-in does not provide RDF itself, the XML or JSON data is rewritten into RDF by the Bridge to provide this format.
Since the SSP does not support any discovery in the network (it should... but whatever) the user of the DynamixBridge has to enter the IP manualy.
The SSP does not
The inclusion of the SSP is envisioned as soon as a permanent running SSP exists.
DynamixBridge is an android-Maven project.
- Version 0.1 released in August
- Version 0.2 released December 2013. Features Posibility of Semantic Data (RDF Data) Created from the data of Plugins that support semantic Representations of Data.
- Currently only English is supported