Using D-Link WiFi cameras zone motion to trigger video embedded text alerts when Away

security
dlink
cameras
project_cameras
project_alerts

(Ryan B) #1

Over the weekend I purchased two DCS-2630L cameras to allow me to monitor all ground-level entry points in our house. I’m really impressed with the clarity of the video and features of the camera. However, upon installing, I quickly learned the downside of setting the DLink Lite application to send notifications for movement to me. The app has no ability to differentiate between movement while me and my wife are at home, or if we are away. Within a few hours, I already had alert fatigue and knew I either had to shut off the notifications, or figure out something else. There was no way I was going to leave the alerts on as both me and my wife work from home. Any given weekday would be an insane amount of “Motion Detected” alerts from the DLink app.

For those of you not aware of what I’m talking about, the DLink firmware has this feature where you can draw “motion areas” to monitor for movement:

I really did want to leverage the video monitoring of motion areas and receive notifications only when we were away from the house. Obviously, the DLink Lite app could not provide this feature for me. After a little research, I also hit a wall trying to use the D-Link Camera Manager SmartApp, Stringify, and IFTTT. So I set out to create my own homegrown solution.

SOLUTION REQUIREMENTS

I had a few basic requirements solution:

  1. It needed to use SmartThings presence detectors from my and my wife’s iPhone’s to determine if we were both away to automatically “arm” the video motion solution

  2. The solution must use the DLink Video Motion area that I drew in the cameras firmware settings as the trigger event

  3. Both my wife and I must receive a notification with a link to the video that can be accessed from anywhere on our mobile phone to determine whether the alert is a false positive, or an actual threat to home security

  4. The solution should only send video when triggered to preserve both mobile and home bandwidth. After all, the cameras I purchased record in 1080p. I did not want a perpetual string of 1080p clips being uploaded from my home unnecessarily.

SOLUTION DESIGN

I’m happy to say, as of last night, I have successfully completed my project by gluing a lot of different technologies and services together. If you want to recreate this project, here is what it requires. Please bear in mind I designed this around a Windows home environment - if you’re a Linux/Mac person there are similar tools, but you’ll have to figure that end out:

  • A local FTP server
  • Windows Firewall
  • Dropbox
  • Stringify
  • IFTTT
  • Windows PowerShell
  • Windows Task Scheduler
  • Google Voice (if you want to send text alerts to more than one person)
  • And of course, SmartThings

Please note, I designed this solution to work on a primary Windows machine on my local network. This machine is always on, and logged in. The solution can be designed to work without being logged in, but requires additional tweaks to Dropbox to run as a service instead of a local application. I didn’t want to do this because of my day job requirements and how often I use Dropbox outside of this solution.

Overview of Workflow

At a high-level, here is how the solution functions:

  1. When both my wife and I leave, determined by ST iPhone presence sensors, set a flag that the video system is set to away. This is accomplished by a flow in Stringify. Stringify watches both of our ST presence sensors, when we are both away, it creates an “away” file in a Dropbox location for my primary Windows laptop to indicate the system is “armed”.
  2. DLink is configured to FTP to send any and all motion detection videos to a designated folder on the same windows laptop. Again, since DLink has no “home” vs “away” settings, the FTP transfer occurs for all movement in the house regardless of status. In order to meet my bandwidth requirement, the video motion capture setting is configured at 720p with a low frame-rate. This video clip is only for an initial reference to determine if I should open up the DLink Lite app and view the 1080p video in real-time or not.
  3. A PowerShell script is responsible for watching the FTP folder on the Windows box. Anytime a new movie file is added, the PowerShell script checks for the “away” file in the Dropbox folder.
  4. If the system is set to away, the PowerShell script will then move the motion detection video clip to Dropbox.
  5. I have an IFTTT recipe created to watch the Dropbox location for new files. When a new file is identified, it then sends an SMS alert to Google Voice with the Dropbox URL of the video to me and my wife. Note: I would have used Stringify, but they don’t have SMS options currently, hence the IFTTT and Google Voice mashup. I didn’t want to create two recipes in IFTTT so that’s why I went with Google Voice.

Install and Configure Local FTP Server and Windows Firewall

First, you will need to configure an FTP server on your primary PC. I strongly suggest using FileZilla FTP server for this. http://www.howtogeek.com/140352/how-to-host-an-ftp-server-on-windows-with-filezilla/

Windows 10 does have the ability to natively host its own FTP server, but I can definitely say is is a HUGE PITA. For whatever reason, it simply does not play nice with Windows Firewall. I wasted an entire afternoon figuring this out before giving FileZilla a whirl. I was able to successfully install and configure FileZilla in about 20 minutes.

Don’t forget to create an FTP user and password. You will use this account when you configure the DLink FTP functionality.

Two recommendations to make this work easier for you

  1. Configure the FileZilla FTP server to allow passive connections and define the passive port ranges. I used the range 44444-65535
  2. Configure the FTP server to use a primary listening port other than 20 or 21. Windows Firewall just hates those ports. I used port 13337.

Make sure you create the rules in Windows Firewall to allow inbound connections on your local network on the above port and port ranges.

Configure DLink Motion Areas You Want to Monitor and DLink FTP functionality

First, you’ll want to login to your DLink’s advanced functionality section and define your motion detection settings.

You can find these settings under “Motion Detection” in their Firmware v 1.03

My cameras have both video and PIR sensors. I went ahead and turned off PIR because it’s way too sensitive and basically monitors to large of an area for movement.

I then drew the areas I’m interested in monitoring via video monitoring when my wife and I are away. These are basically all the ground-level entry points that a home intrusion could occur.

I also set the sensitivity to ~45% to mitigate too many false positives:

Front of house camera:

Back of house camera:

Next, configure each camera to FTP to your FTP server - use passive mode. Make sure to use the port and FTP user you configured in the previous step. These settings can be added on the “Video Clip” tab in the DLink Firmware:

The DLink firmware allows you to use different video profiles. For FTP you’ll note I used profile 1, which is a low-res 720p video configuration to meet my low bandwidth requirement.

As a back-up, I’m also using a high-res 1080p recording to the local Micro-SD card.

I think I’ll probably switch the FTP files back to high-res once I’m sure I’m not receiving to many false positives.

Once you have all this set-up, run around your house like an idiot waving in front of all the motion areas you configured. Come back to your PC after your little stroll and make sure there are new MP4 files in your configured FTP folder on the PC.

Use Stringify to Create a Home/Away indicator on the Local PC

I wasn’t aware of any ST integration with FTP or Dropbox, so I opted to use the Stringify app for this step. I’m sure there are multiple ways to skin this cat. This is the path I took. I’m also a fan of Stringify’s ability to quickly leverage multiple triggers with conditional arguments - something IFTTT sorely lacks. So I was opting for ease-of-use and quick convenience here.

As a side note, you could probably use Google Drive or some other tool if you don’t have Dropbox. Again, this was just a tool I already had at my disposal.

I created two flows in Stringify that leverages our smartphones as ST presence detectors. One flow will create a Dropbox file “away” when we both have left. The other is a similar flow, instead writing a Dropbox file “home” when either one of us arrives. Both of these flows write away/home files to the same Dropbox directory:

Away Flow:

Home Flow:

You’ll notice I also tied the flows to a button in Stringify. This was so that I could simulate home and away without have to throw our iphone’s in a remote control car and driving them a half mile up the street. :slight_smile:

Test the flows by using the button. To make sure the home and away file get written to the correct Dropbox folder. I opted for the Dropbox folder so I could spot test remotely with the Dropbox app and it was the easiest way to allow Stringify to write a file to my local PC.

Tie It All Together With PowerShell

This is where it got tricky for me and I spent the bulk of my time on this project. For one, I’m not a PowerShell guru and secondly, Windows PowerShell and Task Scheduler can be tricky to get right with permissions. You will more than likely get bogged down here even if you follow my directions exactly. Hopefully by sharing what I learned, I will save you some time on this step.

I created two PowerShell scripts.

  • The first script is responsible for watching the home/away status folder in dropbox. When the status changes, it removes the last status file. The reason I had to create this script is that the Stringify / Dropbox integration doesn’t have an “overwrite” function - so I had to allow the system the ability to create the file with the most recent time stamp on it. Otherwise, the next script would have incorrect information about whether we were actually home or away.
  • The second script monitors the FTP folder location for new video. When it finds new video, it checks or home/away status. If we are away, it will then move the video clip to yet another Dropbox location so the clip can be accessible from anywhere on our iPhones.

Here is the first script for monitoring and managing the home/away status location:

$HomeStatus = 'C:\Users\Ryan\Dropbox\Stringify' #define the path to the location of home/away file
$mFilter = '*.*' #don't filter the filetype

#the below command will clean up the folder the first time this script runs to ensure only the latest status is in the directory
gci $HomeStatus -Recurse | sort LastWriteTime -desc | select -Skip 1 | Remove-Item -Force 

$WatchProps = @{
    Path = $HomeStatus
    Filter = $mFilter
    NotifyFilter = [IO.NotifyFilters]"FileName"
    IncludeSubdirectories = $False   
}

#define the folder watcher parameters
$Watcher = New-Object System.IO.FileSystemWatcher -Property $WatchProps

#register the folder watcher
$isCreated = Register-ObjectEvent $Watcher Created -SourceIdentifier HomeStatus -Action{
    $name = $Event.SourceEventArgs.Name
    $changeType = $Event.SourceEventArgs.ChangeType
    $timeStamp = $Event.TimeGenerated
    gci $HomeStatus -Recurse | sort LastWriteTime -desc | select -Skip 1 | Remove-Item -Force #when a new status is saved, delete the old status
}

Here is the second script that is responsible for monitoring the FTP folder and moving the videos to the dropbox folder if we are away. I wrote a 30 second delay in the script to allow the local network FTP to successfully occur between the DLink camera and the FTP server otherwise the script moves a partially uploaded file and the video gets corrupted.

I also had to write some logic into the script to accommodate for the DLink FTP directory creation schema to only monitor the current day. This comes into play when we create the scheduled task in Window’s Task Scheduler in the next step.

Just for your edification, DLink writes video files to the FTP server in the following format:

X:<yyyymmdd><hh><UserDefinedPrefix_yyyymmdd_hhmmss>D.mp4

So not only do we have to make sure we are looking at the correct days folder location, but will also need to recurse it’s sub-directories because each hour gets its own folder.

#LEAVE THIS. Unregisters previous day event watcher. Removing this will screw up the logic of if the event was created today.
if (Get-EventSubscriber -SourceIdentifier CamAction){ 
    Unregister-Event -SourceIdentifier CamAction 
    Write-Host "RESTARTED"
}


$date = Get-Date -Format yyyyMMd #get date in the same format that DLink writes to FTP location
$HomeStatus = 'C:\Users\Ryan\Dropbox\Stringify' #path to current status of home
$VideoDestination = 'C:\Users\Ryan\Dropbox\Alert' #Dropbox path to move videos to
$Script:CamFolder = "C:\cams\$date" #path to todays video folder.  $Script: is used to broaden the scope of variable for use in folder watcher
$mFilter = '*.mp4' #I'm only interested in MP4.  Change this to your preferred file type or format

#hash array of additional properties for the watcher
$WatchProps = @{
    Path = $CamFolder
    Filter = $mFilter
    NotifyFilter = [IO.NotifyFilters]"FileName"
    IncludeSubdirectories = $True #enable recursion into subdirectories
}

#define the folder watcher parameters
$Watcher = New-Object System.IO.FileSystemWatcher -Property $WatchProps

#register the folder watcher
$isCreated = Register-ObjectEvent $Watcher Created -SourceIdentifier CamAction -Action{
    $path = $Event.SourceEventArgs.FullPath
    $name = $Event.SourceEventArgs.Name
    $changeType = $Event.SourceEventArgs.ChangeType
    $timeStamp = $Event.TimeGenerated
    $AreWeHome = gci $HomeStatus -Recurse | sort LastWriteTime -desc | select -First 1
    if ($AreWeHome.Name -eq 'away'){
        Start-Sleep -Seconds 30 #give some time for the DLink FTP transfer to complete on the local network
        Move-Item $path -Destination $VideoDestination -Force #move the video to Dropbox destination
    }
}

Now to create a task in Window’s Task Scheduler to make sure both scripts run at start-up and that the video monitor script restarts at midnight to update the correct folder to which for that day’s events.

After a lot of hair-pulling, I found the easiest way to create these tasks is manually.

We will need to create two tasks. One to make sure our home/away script runs at start-up. The next tasks ensures that the video monitoring script runs at start-up AND restarts each night shortly after midnight.

Open up task scheduler and use the file tree to get to PowerShell Scheduled Jobs: Task Scheduler Library -> Microsoft -> Windows -> PowerShell -> ScheduledJobs

Click “Create Basic Task…”

Give it a name. My first one I named CamHomeStatus

For the trigger, this one only needs “When the computer starts”

Action = “Start a program”

Go ahead and then select where ever you saved your powershell script (remember to use the .ps1 extension).

On the next screen, tick the “Open the Properties dialog for this task when I click Finish”.

Click Finish.

Now we have to tweak the task to make sure the silly thing starts for us. If you leave it as is, I promise it will not work.

First, you need to switch the task to run as “SYSTEM”, this will it to start whether or not your user is logged in. Also tick the “Run with highest privileges” and select “Windows 10” (or your relevant OS) in the Configure for dropdown:

Next, select the Actions tab.

Select the only action there and hit Edit. We will make two changes:

  1. Change the Program/script field to point at the FULL PATH to Powershell. For me this was: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

  2. VERY IMPORTANT!! In Add arguments (optional) you will add the following: -NoExit -NoProfile -ExecutionPolicy Bypass -File C:<your path to>\HomeStatus.ps1

The -NoExit flag allows the script to stay open. If you don’t use this flag, the script will quickly execute and stop watching the folder. The -NoProfile and -ExecutionPolicy Bypass prevent permissions and config conflicts.

Last go to the Settings tab and configure as follows:

Hit “OK”. You’re done creating the first scheduled task.

Repeat the process above for the video file monitor. You’ll want to add an addition trigger under the Triggers tab so that the task will restart 1 minute past midnight to update itself to watch the correct FTP folder for video:

That’s it for the task scheduler. Reboot your computer and check back with Task Scheduler and make sure the task’s status reports as “Running”. If it isn’t, you’ll need to troubleshoot on your own. Task Scheduler issues seem to always boil down to user and system permissions, so I’d start there.

Configure Text Alerts

I used IFTTT and created a recipe. Anytime the script above add a video into a Dropbox folder that the recipe watches, it will send an SMS with a link to the accessible video. Here’s the snippit I used in the SMS portion of the IFTTT recipe:

MOTION ALERT @ HOME occurred while away. Check video: {{FileUrl}}

As I mentioned earlier, I have the SMS being sent to my Google Voice account because Google Voice provides the ability to send SMS to multiple phones and/or email address. I didn’t want to create multipl IFTTT recipes for my phone and then my wife’s phone.

Final Result

It works! Last night, my wife and I stepped out for a movie. Towards the end of the movie we got a text alert:

I clicked the link, and sure enough a car had pulled into our cul-de-sac and the movement tripped this system.

Here’s the video: http://ift.tt/2byY7bL

Conclusion

There are probably a lot of different ways to create this solution. This was simply my approach and I wanted to share with the community. It was a lot of fun and I feel very satisfied with the results!


(Ryan B) #2

I’m bumping this for anyone interested. It got caught in the Askimet for a week and was buried several pages back once it was approved from the filter.