Code Monkey home page Code Monkey logo

gsn's Introduction

GSN Global Sensor Networks Build Status

GSN is a software middleware designed to facilitate the deployment and programming of sensor networks.

Online Documentation

You can find the latest GSN documentation, including a deployment, installation, and programming guide, on the project wiki. This README file only contains basic setup instructions depending on your goal:

Running and deploying GSN

Quick demo with Vagrant

On any computer that can run VirtualBox (or any other supported virtual machine provider), install Vagrant, get the GSN git repository or just the file Vagrantfile and type vagrant up in your terminal (being in the same folder). Once the provisioning is done, open your browser at http://localhost:8000/ to see the GSN UI. You can login with the username root@localhost and password changeme.

Debian package

To make it even easier to test on Linux or deploy at large scale, we provide debian packages (see releases). It includes a systemd script to start the GSN server modules automatically at boot and manage it like any other service. Configuration files are in /etc/gsn-core/, /etc/gsn-services/ and /etc/gsn-webui/, the virtual sensors in /etc/gsn-core/virtual-sensors/ and the logs can be found at /var/log/gsn-core/, /var/log/gsn-services/ and /var/log/gsn-webui/. Starting and stopping GSN is performed with service gsn-core start/stop, service gsn-services start/stop and service gsn-webui start/stop. By default, the GSN web interface is then accessible at http://localhost and the API at http://localhost:9000, but you can change the ports in the configuration files.

Universal package

We provide a universal package for each release of the code. This package is the best way to easily try GSN features on non-Linux platforms.

The installer binaries for the latest release can be found at: https://github.com/LSIR/gsn/releases

Once GSN is installed, you can start it, executing the batch file gsn-start.bat (Windows) or shell script gsn-start.sh (Linux).

Loading your first virtual sensor

To load a virtual sensor into GSN, you need to move its description file (.xml) into the virtual-sensors directory. This directory contains a set of samples that can be used.

You can start by loading the MultiFormatTemperatureHandler virtual sensor (virtual-sensors/samples/multiFormatSample.xml). This virtual sensor generates random values without the need of an actual physical sensor.

Developing new wrappers or Virtual Sensors

If you only need to write your own wrapper for a specific sensor communication protocol or processing class, you don't need to have the full building chain as in the next section. Just start an empty Java or Scala project and include a dependency to gsn-core (for example with maven):

<dependency>
    <groupId>ch.epfl.gsn</groupId>
    <artifactId>gsn-core</artifactId>
    <version>2.0.0</version>
</dependency>

Then you can package your code as a jar and put it in the lib folder of the installer (after you followed the steps of the previous section) and you are ready to load you own wrapper or virtual sensor. In the case of a new wrapper you will also need to register it on the wrapper.properties file on your GSN installation.

Building from sources

First download the code from the git repository (using --depth 1 makes it a lot smaller if you don't need the 10 years history):

git clone --depth 1 [email protected]:LSIR/gsn.git

The GSN modules have the following requirements for building from the sources:

  • gsn-core and gsn-extra
    • sbt 0.13+
    • Java JDK 1.7
  • gsn-tools and gsn-services
    • sbt 0.13+
    • Java JDK 1.7
    • Scala 2.11
  • gsn-webui

Then you can run the following tasks in sbt:

  • clean: remove generated files
  • compile: compiles the modules
  • package: build jar packages
  • project [core|extra|tools|services|webui]: select a specific projet

In the project core you can use re-start to launch gsn-core for development and debian:packageBin to build the debian package.

In the project services you can use run to start the web api in development mode and debian:packageBin to build the debian package.

In the project webui you can use startDjango to start the web interface in development mode and packageDjango to build the debian package.

Never use the development mode commands to run a production server !!

gsn's People

Contributors

ablionge avatar ebiiii avatar jpcik avatar kjorg50 avatar nevenag avatar nkryvych avatar sarni avatar sundriver avatar tmaret avatar zaheersm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gsn's Issues

deploying new sensor

how can I deploy a new virtual sensor into gsn ? How can I get the values ? Can someone please post the commands required for this ?

GSN wrapper for JSON data?

Let's say I wanted to use a third-party API as a data source, for example, Weather Underground. This API accepts GET requests and produces JSON in return (for the most part). Is there a way I could define a virtual sensor that can connect to an API and accept JSON data? I suppose this might be similar to the CSV Wrapper. Would the HTTP GET wrapper be appropriate for this?

Thanks!

Multi-output virtual sensors

Virtual sensors may generate several output streams, from one single wrapper. (for example when the wrapper serves as endpoint for multiple sensors). But currently only a single stream is defined as output of a VS.

my suggestion is to define the different output streams in the VS xml files by giving a "name" attribute to each element. Then the addressing would typically be virtualsensor_name/outputstream_name.

Some function will also need to be added an extra parameter like containerImpl.publishData or VirtualSensorDataListener.consume for example.

Feel free to comment if you find a nicer way to implement it...

ZeroMQ exceptions

I'm trying to set up the ZeroMQ and I have both memoryDataVS.xml and zeromq.xml in my virtual-sernsors directory; enabled zeroMQ in the conf/gsn.xml and setup the local version of zeromq.xml file according to https://github.com/LSIR/gsn/wiki/ZeroMQWrapper What I get after running ant gsn is:

 [java] ERROR [2014-11-17 22:32:02,983] [VSensorLoader-Thread0] (VSensorLoader.java:172)     - Unable to load VSensor zeromq, retrying later...
 [java] java.lang.NullPointerException
 [java]     at gsn.storage.StorageManager.executeCreateTable(StorageManager.java:457)
 [java]     at gsn.VSensorLoader.createWrapper(VSensorLoader.java:422)
 [java]     at gsn.VSensorLoader.prepareStreamSource(VSensorLoader.java:436)
 [java]     at gsn.VSensorLoader.createInputStreams(VSensorLoader.java:392)
 [java]     at gsn.VSensorLoader.loadPlugin(VSensorLoader.java:203)
 [java]     at gsn.VSensorLoader.loadPlugin(VSensorLoader.java:170)
 [java]     at gsn.VSensorLoader.run(VSensorLoader.java:118)
 [java]     at java.lang.Thread.run(Thread.java:745)
 [java] java.lang.NullPointerException

Any Ideas why? NullPointerException happens when creating the table because the structure is null, The structure is set this way:
structure = kryo.readObjectOrNull(new Input(new ByteArrayInputStream(rec)),DataField[].class);

Is there some additional setting not mentioned in the documentation? Thank you!

Tiny-GSN Functionalities

Hello,
What are the functionalities available in Tiny-GSN? Can it push data to XGSN? Can it sense data semantically? Read me file does not give all these details. Thanks.

support for unsigned values

when acquiring values from certain sensors it can be meaningful to process them as unsigned and store them this way to save space. Some tricks can be used to map for example unsigned int to long, and use them instead.
Java, before version 8, doesn't support unsigned numbers. But upgrading to java 8 would also need some work.

Auto-refresh doesn't work

Hi,
I've tried many times, but it doesn't work. When I click on the right-bar to add a VSensor (eg. multiFormatSample), it displays the data correctly. However if I press "F5" to reload the home page, the sensor data becomes 'null', and when the "auto-refresh" is set, the page refresh every x seconds normally but the sensor data never change ( always = null) .

Environment:
Win7(64bit); jdk1.6.0_45; apache-ant-1.9.4 chrome+IE
also tried
XP(32bit); jdk1.6.0_45; apache-ant-1.9.4 chrome+IE

Can anyone help me ? Thanks in advance!

How to enable debuging in GSN server ?

I installed the GSN server using the gsn_1.1.8_all.deb file. In the /var/log/gsn.log i get some informations about how the server works but no DEBUG. Is there any way to enable debuging ?

Tnx a lot in advanced

Make dependency between virtual sensors explicit

Currently the graph dependency is built in the gsn.beans.Modifications class, based on hard-coded wrappers and parameters of those. Adding new communication methods (like zeromq) needs then to modify this.
A workaround was implemented in the virtual sensor loader, by loading files in the lexical order if not contradicting the graph from Modifications.
But to make it explicit, one could add field in the vs xml file and then the dependency graph could be built from that. Of course then the ordering is let to the user, who can then make mistakes...
The virtual sensors loader can also be resilient enough to re-try loading vs that failed until all are launched, independently of the order.

book of GSN update and mistake

Some of the new features can be added there and at the same time correcting this error which was reported today:

" The 'data stream processing and time model' described in pages 9-14 of the Book of GSN states that the listing 2.2 on page 11 is for the 'police station' example and 2.3 for the 'insurance' example.
However from the text itself I get an impression that 2.2 is for insurance and 2.3 for police station examples."

Multiple scales in web interface

Either multiple scales or arithmetic operations in web
interface query operations to allow parameters to be plotted on the same scale. (nick)

Make remote wrapper more stable and resilient to failure

Current version of the remote wrapper has some difficulties recovering when connection is lost.
A system based on Message Queues should be implemented, using existing and tested solutions, such as RabbitMQ, ZeroMQ,... (cf. http://queues.io/)
This can also be linked to the solution to the internal mesages queues.

Reliability of Values

Can we measure reliability of temperature values given by a sensor in GSN ? What is the possible way ?

Chart VS history-size does not count null values

I had noticed something a bit strange about the way that ChartVS portrays data that includes null values.

In the screenshot, you will see that the plot for V178 which is pretty much complete starts at a bit after midnight while the other two plots which have many null values (node batteries nearly flat) go back to the previous midnight.

The configuration of the VS is attached (cis_temp_chart.xml).

The source of the data is another VS that saves the temperature values from each of the six nodes in the network. (The gsn.cis_room_temp data is exported in the xls).

I set 216 so that the chart showed 36 hours of data (10 minute intervals). The node batteries are getting low and I am now seeing a lot of null values for some nodes. (I had set in cis_room_temp as well thinking that I needed to retain the data for the chart VS but now realise that probably isn’t necessary.

I haven’t looked at how the charting routine works but it seem it does not count the null values in the data it retains so that the data for nodes V145 and V144 is retained back until it has 216 non null values. Note that the time scale is more compressed before the start of the V178 data.

Would it be possible to make the chart processing class set a time range for history-size instead of a number of records?
--- Imported from https://sourceforge.net/apps/trac/gsn/ticket/86
File: https://sourceforge.net/apps/trac/gsn/attachment/ticket/86/CIS%20Room%20Temperatures.xlsx

Wrappers subscribing to data streams?

I was just curious if it was possible for wrappers to subscribe to data streams for outbound messaging? For example, if I created a wrapper for my device, is it possible for the wrapper to subscribe to a data stream that has published commands for the device?

NOSQL support for GSN

Hi,

Postgres 9.4 has recently added support for jsonb datatype which stores entire json data as a blob and supports querying (using enhanced SQL)on nested data fields in the JSON object. I was thinking on adding such a SQL query to virtual sensor to filter out required fields. If we have to achieve this, I believe we have to modify major part of storage layer of GSN. Do you think this is feasible. Any thoughts on this will be helpful.

Thanks.

Key-value store backend?

Currently the interface to the different databases backend is through the StorageManager. It was built assuming SQL databases (mySQL, postgresQL,...), offering functions that takes SQL queries as input and JDBC drivers are doing the connection to the databases.
But if we want to introduce NoSQL backends, like HBASE, or even memcached, the process of understanding the SQL query and performing it is done at the JDBC driver level (like Apache Phoenix project). Having such adapters would work out almost of the box, but when looking at the whole streaming process would introduce a huge and useless overhead.
Indeed, a lot of functions are just building SQL queries to be able to interact with the DB, but if we know that the DB is just a K-V store, and that the query will just need to be parsed in the next function call, why still using SQL internally?
SQL is very handy for using in the VS configuration files and should be kept here, but it should be parsed much sooner and replaced by an abstraction that can be efficiently passed to SQL and NoSQL backends.

This is just a suggestion and it is not clear for me yet at which level this should be implemented (JDBC, StorageManager, SlidingTimeWindows, VSConfig) ?

Question about timestamps

Hello, I am having a little trouble setting up a timestamp field to be correctly parsed from a CSV file. My description file looks like this

<virtual-sensor name="green_button_energy" priority="10" publish-to-lsm="true">
    <processing-class>
        <class-name>gsn.vsensor.BridgeVirtualSensor</class-name>
        <output-structure>
            <field name="period_start" type="string" />
            <field name="period_end" type="string" />
            <field name="usage_KWh" type="double" />
        </output-structure>
    </processing-class>
    <description>SCE Green Button Energy Data</description>
    <life-cycle pool-size="10"/>
    <addressing>
        <predicate key="geographical">Test</predicate>
        <predicate key="LATITUDE">100.0</predicate>
        <predicate key="LONGITUDE"> -100.0</predicate>
    </addressing>
    <storage history-size="24h" />
    <streams>
        <stream name="input1">
            <source alias="source1" sampling-rate="1" storage-size="1">
                <address wrapper="csv">
                    <predicate key="file">data/green_button_energy.csv</predicate>
                    <predicate key="fields">period_start, period_end, usage_KWh, Quality</predicate>
                    <predicate key="formats">timestamp(y-M-d H:m:s),timestamp(y-M-d H:m:s),numeric, string</predicate>
                    <predicate key="bad-values">NaN,6999,-6999,null</predicate>
                    <predicate key="timezone">Etc/GMT-8</predicate>
                    <predicate key="sampling">1000</predicate>
                    <predicate key="check-point-directory">csv-check-points</predicate>
                    <predicate key="skip-first-lines">1</predicate>
                    <predicate key="separator">,</predicate>
                </address>
                <query>select * from wrapper
                </query>
            </source>
            <query>select period_start, period_end, usage_KWh from source1</query>
        </stream>
    </streams>
</virtual-sensor>

But when I start my GSN server I get this error:

[java] java.lang.RuntimeException: The streamElement produced by :green_button_energy Virtual Sensor is not compatible with the defined streamElement.
[java] The expected stream element structure (specified in /my/path/gsn/virtual-sensors/green_button_energy.xml is [period_start (Varchar) , period_end (Varchar) , usage_kwh (Double) , ] but the actual stream element received from the green_button_energy has the [PERIOD_START(BigInt),PERIOD_END(BigInt),USAGE_KWH(Double), ] thus the stream element dropped !!!

I can see that it is complaining about the mismatch of types where I defined the formats of the wrapper and where I defined the output structure. It seems like when I define the wrapper with
<predicate key="formats">timestamp(y-M-d H:m:s),...</predicate> it actually stores this as type bigint in the database.

My question is, how can define the timestamps such that in the output structure I can also see it in the "y-M-d HH:mm:ss" format? What "type" should I use in the line <field name="period_end" type="string" />?

stream element duplicates

I have spotted sporadic stream element duplicates in our GSN database. The only value which differs within a duplicate, are the TIMED entries. They differ in a few milliseconds. All other values are exactly the same and are distinctive duplicates. The VSs in which I have spotted these duplicates are using the local wrapper connected to one other VS and the scriptlet processor with a simple time conversion groovy script.

Do you have ever met the same problem or have any clue what could cause this duplicates?

Time Unit in GSN

What is the unit of time measured by sensors in GSN ? I get something like this ?
screenshot from 2016-03-27 16 30 24

Storing to database

How can we store the geographical location of a sensor into database ? Is GSN using a php connection ? Can someone help me ?

Unable to log out under https

It is not possible to log out of the web interface under a secure connection. Users have to switch to a http connection to log out.

Supporting spaces in adressing

make a small change to the GML Handler
(https://gsn.svn.sourceforge.net/svnroot/gsn/trunk/src/gsn/http/GMLHandler.java)
In order to prevent future sensor misconfigurations where people can put spaces in the
content of the latitude and longitude elements,

suggested solution by user :

to the code reading these values. You can do for example:

for (KeyValue df : sensorConfig.getAddressing()) {
if
(StringEscapeUtils.escapeXml(df.getKey().toString().toLowerCase()).contentEquals("latitude"))
lat = (new
String(StringEscapeUtils.escapeXml(df.getValue().toString()))).trim();
if
(StringEscapeUtils.escapeXml(df.getKey().toString().toLowerCase()).contentEquals("longitude"))
lon = (new
String(StringEscapeUtils.escapeXml(df.getValue().toString()))).trim();
}

or whatever you think is more appropriate to remove the leading and
trailing spaces from the values of those coordinates.

And because I can also assume that people might put non-numeric
characters inside the coordinates by mistake (for example the letter
"o" instead of "0"), you can do this also:

for (KeyValue df : sensorConfig.getAddressing()) {
if
(StringEscapeUtils.escapeXml(df.getKey().toString().toLowerCase()).contentEquals("latitude"))
lat = (new
String(StringEscapeUtils.escapeXml(df.getValue().toString()))).trim();
if (lat != null && (!(lat.matches("-?\d+(.\d+)?"))))
lat = null;
if
(StringEscapeUtils.escapeXml(df.getKey().toString().toLowerCase()).contentEquals("longitude"))
lon = (new
String(StringEscapeUtils.escapeXml(df.getValue().toString()))).trim();
if (lon != null && (!(lon.matches("-?\d+(.\d+)?"))))
lon = null;
}

Please check the logic, because I didn't compile nor tested the above
code. I have used the pattern "-?\d+(.\d+)?" because latitude and
longitude can also be negative in other parts of the world outside
Europe, hence the optional "-".

Issue in push remote timing

In the current implementation when a push request arrives, it gets registered and the data transmission starts immediately. If the client virtual sensor is not completely loaded the received remote data is going to be lost.
(Reported by mriahi on sourceforge)

Location

How can I get the location value into the database in GSN ?

support for epoch timestamps?

Hello,

I am trying to write a virtual sensor using the CSV Wrapper, and one of the fields of my data is a timestamp in epoch format. I see that in CSVHandler.java you use the forPattern(String pattern) function to parse a date format given in the virtual sensor description XML file. For example:

<predicate key="formats">numeric,timestamp("yyyy-MM-dd HH:mm:ss.SSS"),...</predicate>

However, the problem is that I don't know what pattern to use to allow for the input of an epoch time number such as 1318316400. Is it possible to use the epoch timestamp as a parameter to the DateTime() constructor, as in this answer?

Basically, how can I use epoch time as an input for timestamps in GSN?

Thanks

Database Modification

Is it possible to modify database and then deploy sensors ? I got several errors occured when I tried to modify database and run the sensors again, even when I had default value of the sensors initialized to NULL.
problem

Multiple value Sensor Deployment

How can we implement a multiple value sensing sensor in GSN other than the example ones given in the GSN. I would like to deploy a sensor that measures pressure as well as temperature.

Exception while unloading a virtual sensor using local or remote wrappers

I find now that when stopping GSN (ant stop), there is an error if any
virtual sensor using local wrapper or either of the remote wrappers.

I can load memoryDataVS.xml and freeDiskSpace-NeedsJDK6.xml and the stop
script executes without error.

However if any of:

  • diskSpacePlotVS-NeedsJDK6.xml (wrapper="remote-rest">),
  • memoryPlotVS.xml (wrapper="local">),
  • remote_rest_test.xml (wrapper="remote-rest">) or
  • remote_push_test.xml (wrapper="remote">)
    Are loaded when the stop script is executed, then errors are generated.
    There is some difference in the errors as can be seen in the attached log
    file which was recorded while I started and stopped GSN with different VS's
    loaded.

I guess that errors when stopping are not critical but they may be
symptomatic of something more serious.

Imported from here: https://sourceforge.net/apps/trac/gsn/ticket/44
Files are on SourceForge Issue tracker: https://sourceforge.net/apps/trac/gsn/ticket/44

Web UI latitude/longitude issue

I noticed that if I create a CSV virtual sensor and use the field names "latitude" and "longitude," then on the web page the actual <addressing> values for latitude and longitude get shown next to the data values. For example, when the virtual sensor is first loaded
screenshot 2015-05-27 17 13 47

But after the first auto-refresh occurs it shows this
screenshot 2015-05-27 17 14 54

I used 0.0, 0.0 as my latitude/longitude in the <addressing> section of the virtual sensor. All of the data is recorded in the database properly, so it's just an issue in the view. Is there a simple solution for this? Thanks!

GSN Build issue

Hi All,

I have been trying to build GSN from the source code and every time it fails with the below error. I am facing this issue since 10 days. It used to work fine before that. It will be helpful if someone can help me resolve this issue.

Steps to reproduce the issue:

  1. On a fresh box/VM, Install java, ant and other packages required for GSN.
  2. git clone https://github.com/LSIR/gsn.git
  3. cd gsn
  4. ant
  5. ant gsn

Build log:

[artifact:dependencies] org.apache.geronimo.specs:geronimo-stax-api_1.0_spec:jar:1.0.1
[artifact:dependencies]
[artifact:dependencies] from the specified remote repositories:
[artifact:dependencies] apache.snapshots (http://repository.apache.org/snapshots),
[artifact:dependencies] central (http://repo1.maven.org/maven2),
[artifact:dependencies] TypesafeRepository (http://repo.typesafe.com/typesafe/releases/),
[artifact:dependencies] LSIR (http://osper.epfl.ch:8081/artifactory/gsn-release/)
[artifact:dependencies]
[artifact:dependencies] Path to dependency:
[artifact:dependencies] 1) gsn:gsn:jar:1.1.5
[artifact:dependencies] 2) org.apache.axis2:axis2-adb:jar:1.5.5
[artifact:dependencies] 3) org.apache.axis2:axis2-kernel:jar:1.5.5
[artifact:dependencies] 4) org.apache.ws.commons.axiom:axiom-api:jar:1.2.11
[artifact:dependencies]
[artifact:dependencies]
[artifact:dependencies] Not a v4.0.0 POM. for project org.apache.geronimo.genesis.config:config at /root/.m2/repository/org/apache/geronimo/genesis/config/config/1.1/config-1.1.pom

BUILD FAILED
/home/ec2-user/gsn/build.xml:480: Unable to resolve artifact: Unable to get dependency information: Unable to read the metadata file for artifact 'org.apache.geronimo.specs:geronimo-stax-api_1.0_spec:jar': Cannot find parent: org.apache.geronimo.genesis.config:config for project: null:project-config:pom:1.1 for project null:project-config:pom:1.1
org.apache.geronimo.specs:geronimo-stax-api_1.0_spec:jar:1.0.1

from the specified remote repositories:
apache.snapshots (http://repository.apache.org/snapshots),
central (http://repo1.maven.org/maven2),
TypesafeRepository (http://repo.typesafe.com/typesafe/releases/),
LSIR (http://osper.epfl.ch:8081/artifactory/gsn-release/)

Path to dependency:
1) gsn:gsn:jar:1.1.5
2) org.apache.axis2:axis2-adb:jar:1.5.5
3) org.apache.axis2:axis2-kernel:jar:1.5.5
4) org.apache.ws.commons.axiom:axiom-api:jar:1.2.11

Total time: 1 second

.

Thanks,
Varun

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.