Pushing recordings from DLink DCS-5222L to the Cloud

The DLink DCS-5222L is a brilliant piece of kit. However, it provides limited functionality to push your videos and snapshots to the cloud. Below I describe how I have setup my DCS-5222L to push to the Cloud without intervention.

One solution which I initially used was to install Surveillance Station on my Synology NAS and hook up the DLink so the recordings were copied onto the NAS. However, as my NAS is in the same place as the camera, what if someone comes in, steals the camera, and the NAS? Even with the recordings being synced to an Amazon S3 storage bucket which was done by a scheduled job on the NAS this still meant by the time someone had come in and made off with the NAS and the DLink I would be left with no recordings. So, the solution below was born.

The items involved are quite simple and free (to a point). The steps are described below;

1. Set up an Amazon Web Services (AWS) EC2 Windows Server 2012r2 instance (this is free if you use the basic tier and comes with 30Gb storage!)

2. Set up FileZilla FTP Server running on the instance (follow the instructions here at LifeHacker and further instructions here at How-To Geek).

3. Ensure you open the ports on the Windows Firewall for FTP and also within AWS under Security Groups, within the Security Group your Windows Server is in.

4. Test the FTP server connection from a local machine using the static IP given to you by AWS (or hostname if you set this us, obviously) and ensure you can FTP a file to the EC2 machine. I had issues around running FTP in passive mode, using the troubleshooting steps on the FileZilla wiki here I managed to fix these. I also had/have issues around permissions, I am unable to have my home directory for the FTP account anywhere other then the root of my C: drive, not an issue for me but might be for others.

5. Change the RDP and FTP ports on this box for (slightly) enhanced security – ensure you change the firewall rules before you do this so you don’t block your own RDP connection! To chage the RDP port for Windows Server 2012r2 follow the instructions here. The FTP port should be changed within FileZilla under Edit > Settings and then change “Listen on thse ports”, then click ‘OK’.

6.  Now you are ready to make the changes to the DLink Camera. Login to the camera and access the Setup page. Under Video Clip enter the FTP details of the server you just setup and test the connection. The camera will create a folder on the FTP server if successful and there will be a message telling you if you were successful or not towards the top of the page. You can do the same under the Snapshot section too.

7. Finally, so as to not over fill my EC2 instance I have written myself a small Java application which checks if the CCTV backup is over 5Gb in size and if it is will delete the oldest files until it is back under 5Gb again. This is run hourly as a scheduled windows task. You will find code snippets in my other posts that will help with achieving this if required.

Happy Cloud backup! Now whenever a motion is detected by my DLink DCS-5222L not only does it save the recordings to the Micro SD on board but also pushes the video via FTP to a Cloud based AWS EC2 instance which I can remotely access.

Java – Generating a list of files ordered newest to oldest

I recently had a situation where I needed an ordered list of file names by newest to oldest so I thought I would share the code. This uses the last modified date as in my case that worked and as java.io doesn’t provide the created date only last modified.

First a method which returns an ArrayList of all files within a given directory.

public static ArrayList listFiles(String directoryName) {
		File directory = new File(directoryName);

		ArrayList filenames = new ArrayList();

		// get all the files from a directory
		File[] fList = directory.listFiles();
  		if (fList != null) {
       			for (File file : fList) {
           				if (file.isFile()) {
                					filenames.add(file.getAbsolutePath());
           				} else if (file.isDirectory()) {
                					filenames.addAll(listFiles(file.getAbsolutePath()));
           				}
        			}
		}
		return filenames;
	}

We will then call the above method when building the ordered list of files. As below;

public static Map<String, Long> orderedListOfFiles(String directoryName) {
		Map<String, Long> fileMap = new HashMap<String, Long>();

		// get all the files from a directory
		ArrayList filePaths = listFiles(directoryName);
		for (String path: filePaths) {
     			File file = new File(path);
     			fileMap.put(path, file.lastModified());
		}
		
		List<Map.Entry<String, Long>> list = new LinkedList<Map.Entry<String, Long>>(fileMap.entrySet());
		
		Collections.sort(list, new Comparator<Map.Entry<String, Long>>() {

				public int compare(Map.Entry<String, Long> m1, Map.Entry<String, Long> m2) {
					if (m1.getValue() > m2.getValue())
	            		return -1;
	                return 1;
				}

	        });
		 
		  Map<String, Long> result = new LinkedHashMap<String, Long>();
	        for (Map.Entry<String, Long> entry : list) {
	            result.put(entry.getKey(), entry.getValue());
	        }
		
		return result;
	}

To switch oldest to newest simply modify the compare method implemented inside the Comparator class.

Java Database Connectivity – MySQL, Oracle and SQLite

I have played around with database connectivity with Java for MySQL, Oracle and SQLite. I thought I would share some simple connection setup code with the world.

You will need to download and add the appropriate JARs to your project and or your class path, as well as having a database to connect to, unless you are using SQLite in which case the database is local.

MySQL

First up is MySQL connectivity. This first snippet will check you have loaded the JDBC driver correctly.

 

import java.sql.*;
public class MySqlLoadDriver {
  public static void main(String [] args) {
    Connection con = null;
    try {

      // Load the MySQL JDBC driver
      Class.forName("com.mysql.jdbc.Driver") ;
      System.out.println("MySQL JDBC driver loaded ok.");

    } catch (Exception e) {
      System.err.println("Exception: "+e.getMessage());
    }
  }
}

 

The following snippet will set up a connection to the database. Where the host in the example is set to localhost so you may change this to point to your database address or tunnel in to your database using a client like Putty. Also change username and password to your database username and password.

 

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class SimpleConnection;
{

     static public void main(String args[])
     {

      Connection con = null;

      try {

         Class.forName("com.mysql.jdbc.Driver") ;
         System.out.println("MySQL JDBC driver loaded ok.");
         con = DriverManager.getConnection(
         "jdbc:mysql://127.0.0.1:3306/","username", "password");
         System.out.println("Connected with host:port/database.");
         con.close();

     } catch (Exception e) {
              System.err.println("Exception: "+e.getMessage());
     }

    }

}

 

Oracle

Oracle has a two types of connection I have played with Oracle Call Interface and Oracle’s JDBC Thin driver uses Java sockets to connect directly to Oracle. It provides its own TCP/IP version of Oracle’s SQL*Net protocol. Because it is 100% Java, this driver is platform independent and can also run from a Web Browser. Depending on which one you want to use comment out or delete the other line. In the example I am using the OJDBC Thin Driver not the Oracle Call Interface.

 

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class OracleSimpleConnection {

     static public void main(String args[])

     {
         Connection con = null;

         try
         {
               Class.forName ("oracle.jdbc.OracleDriver");
               System.out.println("Oracle JDBC driver loaded ok.");
               con = DriverManager.getConnection(

                   //"jdbc:oracle:oci7:@//localhost:1521/ORCL","username", "password");
                   "jdbc:oracle:thin:@//192.168.104.11:1521/ORCL","username", "password");
               System.out.println("Success!!");
               System.out.println("Connected with host:port/database.");
               con.close();
          }
          catch (Exception e)
          {
               System.err.println("Exception: "+e.getMessage());
          }
       }
}

 

SQLite

Finally the creation and testing of an SQLite Database, adding in a few things with a simple query.

 

import java.sql.*;

public class SQLiteTest {

public static void main(String[] args) throws Exception {

    Class.forName("org.sqlite.JDBC");

    Connection conn = DriverManager.getConnection("jdbc:sqlite:test.db");
    Statement stat = conn.createStatement();
    stat.executeUpdate("drop table if exists people;");
    stat.executeUpdate("create table people (name, occupation);");
    PreparedStatement prep = conn.prepareStatement("insert into people values (?, ?);");
    prep.setString(1, "Gandhi");
    prep.setString(2, "politics");
    prep.addBatch();
    prep.setString(1, "Turing");
    prep.setString(2, "computers");
    prep.addBatch();
    prep.setString(1, "Wittgenstein");
    prep.setString(2, "smartypants");
    prep.addBatch();
    conn.setAutoCommit(false);
    prep.executeBatch();
    conn.setAutoCommit(true);
    ResultSet rs = stat.executeQuery("select * from people;");

    while (rs.next()) {
          System.out.println("name = " + rs.getString("name"));
          System.out.println("job = " + rs.getString("occupation"));
    }

    rs.close();
    conn.close();

  }

}

 

Useful Links;

http://www.sqlite.org/

http://www.zentus.com/sqlitejdbc/

http://www.oracle-internals.com/?p=18

http://www.orafaq.com/wiki/JDBC#Thin_driver

How to install the Oracle JDBC into your local Maven repository

This will work to install any jar or package into your local Maven repository, just change the relevant sections in the command line entry.

To get the Oracle Driver go toand then to the JDBC Drivers page which at the time of writing is here:

Ensure you have Maven properly setup on your machine.

Navigate to the folder containing the jar in a command line prompt.

Enter the following;
mvn install:install-file -Dfile=ojdbc5.jar -DgroupId=com.oracle -DartifactId=ojdbc5 -Dversion=11.2.0.3 -Dpackaging=jar -DgeneratePom=true

Where:
-Dfile is the path to file
-DgroupId is the group ID
-DartifactId is the artefact ID
-Dversion is the version of the package
-Dpackaging is the package type i.e. jar
– DgeneratePom will automatically generate the pom.xml entry

Note: If you are using Powershell you will need to escape the – with a back tick so -Dfile=ojdbc5.jar becomes `-Dfile=ojdbc5.jar`
If you are adding Sun JARs is there is a helpful article on naming conventions to use here.

Useful links;
http://maven.apache.org/guides/mini/guide-3rd-party-jars-local.html
http://stackoverflow.com/questions/442230/how-to-manually-install-an-artifact-in-maven-2
http://stackoverflow.com/questions/1074869/find-jdbc-driver-in-maven-repository