diff --git a/Gopkg.lock b/Gopkg.lock deleted file mode 100644 index 9c88386..0000000 --- a/Gopkg.lock +++ /dev/null @@ -1,70 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[[projects]] - digest = "1:60eb9871a742cda01a348cfc5c5829697e1eecd1c210a35212882f6b377e9fcc" - name = "github.com/aws/aws-sdk-go" - packages = [ - "aws", - "aws/awserr", - "aws/awsutil", - "aws/client", - "aws/client/metadata", - "aws/corehandlers", - "aws/credentials", - "aws/credentials/ec2rolecreds", - "aws/credentials/endpointcreds", - "aws/credentials/stscreds", - "aws/csm", - "aws/defaults", - "aws/ec2metadata", - "aws/endpoints", - "aws/request", - "aws/session", - "aws/signer/v4", - "internal/ini", - "internal/s3err", - "internal/sdkio", - "internal/sdkrand", - "internal/sdkuri", - "internal/shareddefaults", - "private/protocol", - "private/protocol/eventstream", - "private/protocol/eventstream/eventstreamapi", - "private/protocol/query", - "private/protocol/query/queryutil", - "private/protocol/rest", - "private/protocol/restxml", - "private/protocol/xml/xmlutil", - "service/s3", - "service/sts", - ] - pruneopts = "UT" - revision = "47607acdb3657d60debbfa33f328dc9801fb3cfd" - version = "v1.15.74" - -[[projects]] - digest = "1:e22af8c7518e1eab6f2eab2b7d7558927f816262586cd6ed9f349c97a6c285c4" - name = "github.com/jmespath/go-jmespath" - packages = ["."] - pruneopts = "UT" - revision = "0b12d6b5" - -[[projects]] - digest = "1:a3b8912deeef29007fab9a13a9f21b9e9b59c621a2ed61e2fe7b37320a71fbd5" - name = "github.com/satori/go.uuid" - packages = ["."] - pruneopts = "UT" - revision = "b2ce2384e17bbe0c6d34077efa39dbab3e09123b" - -[solve-meta] - analyzer-name = "dep" - analyzer-version = 1 - input-imports = [ - "github.com/aws/aws-sdk-go/aws", - "github.com/aws/aws-sdk-go/aws/session", - "github.com/aws/aws-sdk-go/service/s3", - "github.com/satori/go.uuid", - ] - solver-name = "gps-cdcl" - solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml deleted file mode 100644 index dea5635..0000000 --- a/Gopkg.toml +++ /dev/null @@ -1,38 +0,0 @@ -# Gopkg.toml example -# -# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html -# for detailed Gopkg.toml documentation. -# -# required = ["github.com/user/thing/cmd/thing"] -# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] -# -# [[constraint]] -# name = "github.com/user/project" -# version = "1.0.0" -# -# [[constraint]] -# name = "github.com/user/project2" -# branch = "dev" -# source = "github.com/myfork/project2" -# -# [[override]] -# name = "github.com/x/y" -# version = "2.4.0" -# -# [prune] -# non-go = false -# go-tests = true -# unused-packages = true - - -[[constraint]] - name = "github.com/aws/aws-sdk-go" - version = "1.15.74" - -[[constraint]] - name = "github.com/satori/go.uuid" - revision = "b2ce2384e17bbe0c6d34077efa39dbab3e09123b" - -[prune] - go-tests = true - unused-packages = true diff --git a/Makefile b/Makefile index 7888d8b..1e62816 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,6 @@ +GOARGS=GOOS=linux GOARCH=arm CGO_ENABLED=0 .PHONY: build build: - GOOS=linux GOARCH=arm CGO_ENABLED=0 go build -o ./root/usr/local/bin/cctv_upload ./cmd/cctv_upload - -.PHONY: install -install: - go get -u github.com/golang/dep/cmd/dep - dep ensure -v + @cd ./uploader \ + && $(GOARGS) go build -o ../root/usr/local/bin/uploader . diff --git a/README.md b/README.md index 13a29e2..f0c2a03 100644 --- a/README.md +++ b/README.md @@ -40,26 +40,15 @@ be helpful for that. A USB webcam is used for this project. Any USB camera should do, I'm using a [Logitech C920 Webcam](https://www.amazon.com/gp/product/B006JH8T3S). -## Golang - -You'll need a working Go environment on your local machine to build the code. - -* Go v1.11 -* [dep](https://github.com/golang/dep) - # Device Setup ## Install dependencies - ``` -sudo apt-get update +ssh pi@raspberrypi.local -# usb camera support -sudo apt-get install fswebcam - -# Install motion -sudo apt-get install motion +# usb camera support and motion +sudo apt-get update -y && sudo apt-get install -y fswebcam motion ``` Test the camera with `fswebcam` @@ -77,8 +66,8 @@ Captured frame in 0.00 seconds. --- Processing captured image... Writing JPEG image to 'image.jpg'. ``` -Now we know our webcam is at `/dev/video0`. If you look at `image.jpg` you'll see the picture it took. +Now we know our webcam is at `/dev/video0`. If you look at `image.jpg` you'll see the picture it took. ## Configure motion @@ -125,7 +114,7 @@ to AWS S3 and notifying a Slack channel. "Version": "2012-10-17", "Statement": [ { - "Sid": "cctv_upload", + "Sid": "securitycamera", "Effect": "Allow", "Action": [ "s3:PutObject", @@ -144,36 +133,38 @@ to AWS S3 and notifying a Slack channel. # Uploading images -Edit the `on_picture_save` script with your AWS and Slack secrets: -``` -# ./root/usr/local/bin/on_picture_save +When motion is detected a new image is created and the `on_picture_save` script is invoked. This calls the `uploader` which uploads the image to S3. Download the [latest release](https://github.com/bndw/security-camera/releases/latest) of the uploader and save it in `./root/usr/local/bin/uploader`. -SLACK_WEBHOOK_URL=https://hooks.slack.com/services/your/slack/webhook -S3_BUCKET_NAME=my-bucket-name -S3_BUCKET_REGION=us-west-2 -AWS_ACCESS_KEY=xxx -AWS_SECRET_KEY=xxxxx +Or, build from source if you have Go 1.13 or later: +``` +make build ``` -Build the [cctv_upload](./cmd/cctv_upload) program that ties the system together. -It's called by the `on_picture_save` script when a new image is created. -The program uploads the image to S3 and then sends a webhook to Slack with the image url. - +Next, upload both programs to the pi ``` -make install -make build +scp ./root/usr/local/bin/* pi@raspberrypi.local:/tmp/ ``` -Upload both programs to the pi +SSH to the pi to complete configuration ``` -rsync -avz root/usr/local/bin/ pi@your_ip:/tmp +ssh pi@raspberrypi.local -cp /tmp/cctv_upload /usr/local/bin/ -cp /tmp/on_picture_save /usr/local/bin/ +# Copy the scripts into the PATH +sudo mv /tmp/{uploader,on_picture_save} /usr/local/bin/ ``` -Finally, open the motion config again and configure it to call the `on_picture_save` script everytime it creates an image. +Edit `/usr/local/bin/on_picture_save` and add your AWS and Slack secrets: +``` +# /usr/local/bin/on_picture_save +SLACK_WEBHOOK_URL=https://hooks.slack.com/services/your/slack/webhook +S3_BUCKET_NAME=my-bucket-name +S3_BUCKET_REGION=us-west-2 +AWS_ACCESS_KEY=xxx +AWS_SECRET_KEY=xxxxx +``` + +Open the motion config again and configure it to call the `on_picture_save` script everytime it creates an image. ``` # /etc/motion/motion.conf on_picture_save /usr/local/bin/on_picture_save %f @@ -183,3 +174,5 @@ Restart motion ``` systemctl restart motion ``` + +You should be good to go. Check out the motion detection settings in `/etc/motion/motion.conf` for customizing thresholds, etc. diff --git a/root/usr/local/bin/on_picture_save b/root/usr/local/bin/on_picture_save index 8d33470..65e0185 100755 --- a/root/usr/local/bin/on_picture_save +++ b/root/usr/local/bin/on_picture_save @@ -18,11 +18,10 @@ AWS_SECRET_KEY=xxxxx # End configuration IMAGE=$1 -CCTV_UPLOAD=/usr/local/bin/cctv_upload SLACK_WEBHOOK_URL="$SLACK_WEBHOOK_URL" \ S3_BUCKET_NAME="$S3_BUCKET_NAME" \ S3_BUCKET_REGION="$S3_BUCKET_REGION" \ AWS_ACCESS_KEY_ID="$AWS_ACCESS_KEY" \ AWS_SECRET_ACCESS_KEY="$AWS_SECRET_KEY" \ -$CCTV_UPLOAD" "$IMAGE" +/usr/local/bin/uploader "$IMAGE" diff --git a/cmd/cctv_upload/config.go b/uploader/config.go similarity index 100% rename from cmd/cctv_upload/config.go rename to uploader/config.go diff --git a/uploader/go.mod b/uploader/go.mod new file mode 100644 index 0000000..272e019 --- /dev/null +++ b/uploader/go.mod @@ -0,0 +1,8 @@ +module github.com/bndw/security-camera/uploader + +go 1.13 + +require ( + github.com/aws/aws-sdk-go v1.30.29 + github.com/google/uuid v1.1.1 +) diff --git a/uploader/go.sum b/uploader/go.sum new file mode 100644 index 0000000..6045ef7 --- /dev/null +++ b/uploader/go.sum @@ -0,0 +1,25 @@ +github.com/aws/aws-sdk-go v1.30.29 h1:NXNqBS9hjOCpDL8SyCyl38gZX3LLLunKOJc5E7vJ8P0= +github.com/aws/aws-sdk-go v1.30.29/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc= +github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/cmd/cctv_upload/main.go b/uploader/main.go similarity index 100% rename from cmd/cctv_upload/main.go rename to uploader/main.go diff --git a/cmd/cctv_upload/s3.go b/uploader/s3.go similarity index 92% rename from cmd/cctv_upload/s3.go rename to uploader/s3.go index c9ef91c..0e0087e 100644 --- a/cmd/cctv_upload/s3.go +++ b/uploader/s3.go @@ -9,7 +9,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/s3" - "github.com/satori/go.uuid" + "github.com/google/uuid" ) func UploadToS3(region, bucket, filepath string) (string, error) { @@ -19,7 +19,7 @@ func UploadToS3(region, bucket, filepath string) (string, error) { } // Change the filename to a UUID - newFilename := fmt.Sprintf("%s.jpg", uuid.Must(uuid.NewV4())) + newFilename := fmt.Sprintf("%s.jpg", uuid.New()) // Upload it err = s3Put(s, bucket, filepath, newFilename) @@ -27,7 +27,6 @@ func UploadToS3(region, bucket, filepath string) (string, error) { return "", err } - // Return the URL return fileURL(region, bucket, newFilename), nil } diff --git a/cmd/cctv_upload/slack.go b/uploader/slack.go similarity index 100% rename from cmd/cctv_upload/slack.go rename to uploader/slack.go