Skip to content

Commit

Permalink
1st publish
Browse files Browse the repository at this point in the history
  • Loading branch information
Sam Machin authored and Sam Machin committed Aug 7, 2017
1 parent 31dfbed commit 1258630
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 27 deletions.
43 changes: 36 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Requirements:

1) Start with a fresh install of raspbian for this I've used teh July 2017 version

2) Run `raspi-config`
2) Run `raspi-config` as root
change the default password
edit the hostname
enable the camera in interfaceing options
Expand All @@ -20,7 +20,7 @@ expand the filesystem in advance options
Add a line at the botom of that file
`bcm2835-v4l2```
4) Install live555 media server
4) Install live555 media server as pi user not root
```
wget http://www.live555.com/liveMedia/public/live555-latest.tar.gz
tar -xvzf live555-latest.tar.gz
Expand All @@ -40,19 +40,48 @@ make install
```
6) Copy the startup script
Place start.sh in the `homee` directory of the `pi` user (not root)
run `start.sh`
You can now verify that your camera is working properly using VLC on your computer by opening a network address of rtsp://[YOUR PI IP]:8080/h264
7) Install and configure stunnel (as root)
`apt-get install stunnel`
Place the stunnel.conf file at /etc/stunnel/stunnel.conf
8) Setup DNS entry for the Camera's private IP address on your LAN
I use AWS Route53 but any DNS host should be fine, just create a A record for the Pi's IP address and give it a hostname like camerapi.[YOURDOMAIN.COM]
Yes Putting Private IP's into public DNS is discouraged, but if this is only for your personal use then you're not going to break the internet, I use a separate domain for my camera's just to keep stuff clean.
8) Get an SSL Cert using lets encrypt from your main machine as certbot doesn't easily run on raspbian
9) Get an SSL Cert using lets encrypt from your main machine as certbot doesn't easily run on raspbian
`certbot -d [hostname] --rsa-key-size 4096 --manual --preferred-challenges dns certonly`
It will ask you to verify domain ownership by creating a special DNS record, be careful with this as if you make a mistake it can take a long time for the DNS chace to expire so you can try again!
Copy the files `privkey.pem` and `fullchain.pem` created by certbot over to the Pi in `/etc/stunnel`
10) Setup the Alexa Skill
10) Start stunnel as root
`stunnel`
10) Create a Lambda Function
Use the code in the `lambda` folder, you will need to edit the cameras.json file to contain the names and hostname of your camera(s) using the domain names you setup above, its important to keep the `:443/h264` on the end of the URLs.
11) Setup the Alexa Skill
Signin to Developer.amazon.com,
Within the Alexa Skills Kit section
Click Add a Skill
Slect the Smart Home API SKill
Give it a name like `CameraPi`
Set the Payload version to v2
There is no need for an interaction model on smart home skills
Link the skill to your Lambda Instance
11) Create Lambda Function
12) Setup Login with Amazon
Follow the guide here https://developer.amazon.com/blogs/post/Tx3CX1ETRZZ2NPC/Alexa-Account-Linking-5-Steps-to-Seamlessly-Link-Your-Alexa-Skill-with-Login-wit
You don't need to authenticate the cameras within the skill if its only for your own use the Smart Home skills require authentication.
12) Discover Devices
13) Discover Devices
"Alexa Discover Devices"
Should find your new camera.
You can then say `Alexa show Office Camera` or whatever you've named to to open the stream
`Alexa Stop` ends the video
32 changes: 13 additions & 19 deletions lambda/lambda.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,56 +15,50 @@ def lambda_handler(event, context):
return handleQuery(context, event)

def handleDiscovery(context, event):
cameras= loadcams()
message_id = event['header']['messageId']
payload = ''
header = {
"namespace": "Alexa.ConnectedHome.Discovery",
"name": "DiscoverAppliancesResponse",
"payloadVersion": "2",
"messageId": message_id

}
if event['header']['name'] == 'DiscoverAppliancesRequest':
payload = {
"discoveredAppliances": [
{
"applianceId": "001",
appliances = []
for c in cameras:
a = {
"manufacturerName": "CameraPi",
"modelName": "CameraPi",
"version": "0.9",
"friendlyName": "office camera",
"friendlyDescription": "Camera Pi in Office",
"version": "1.0",
"isReachable": True,
"actions": [
"retrieveCameraStreamUri"
],
"applianceTypes":[
"CAMERA"
],
"additionalApplianceDetails": {
"extraDetail1": "None"
}
]
}
]
}
a["applianceId"] = c
a["friendlyName"] = cameras[c]['friendlyName']
a["friendlyDescription"] = cameras[c]['friendlyDescription']
appliances.append(a)
payload = {"discoveredAppliances": appliances}
return { 'header': header, 'payload': payload }

def handleQuery(context, event):
payload = ''
cameras= loadcams()
device_id = event['payload']['appliance']['applianceId']
message_id = event['header']['messageId']

header = {
"namespace":"Alexa.ConnectedHome.Query",
"name":"RetrieveCameraStreamUriResponse",
"payloadVersion":"2",
"messageId": message_id
}

if event['header']['name'] == 'RetrieveCameraStreamUriRequest':
payload = {
"uri": {
"value":"rtsp://officecamerapi.dev-cloud.co.uk:443/h264"
"value": cameras[device_id]["uri"]
},
"imageUri": {
"value":"https://s3.sammachin.com/loading.jpg"
Expand Down
2 changes: 1 addition & 1 deletion start.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#! /bin/bash

raspivid -o - -t 0 -n -w 1280 -h 720 -fps 25 | testRaspi
raspivid -o - -t 0 -n -w 1280 -h 720 -fps 25 | testRaspi &

0 comments on commit 1258630

Please sign in to comment.