Raspberry Pi WebCam with 3G (Solarcam): Difference between revisions
Jump to navigation
Jump to search
Line 29: | Line 29: | ||
==== Script: Take picture every minute ==== | ==== Script: Take picture every minute ==== | ||
Add this to crontab: | Add this to crontab: | ||
* * * * * /home/pi/Development/webcam/takePicture.sh > /dev/null 2>&1 | # DS18B20 | ||
*/15 * * * * /home/pi/Development/temperature/readTemperature.sh > /dev/null 2>&1 | |||
# | |||
# PiCam - Take Snapshot(s) | |||
*/15 * * * * /home/pi/Development/webcam/takePicture.sh > /dev/null 2>&1 | |||
===== takePicture.sh ===== | ===== takePicture.sh ===== | ||
#!/bin/bash | #!/bin/bash |
Revision as of 00:35, 25 April 2018
The Idea
- Use solar panel to harvest energy
- Store the energy in a left over car battery
- Power a Pi, camera and
3G-StickMobile HotSpot[1] - Make a nice webcam out of it :)
Shopping List
- A Pi with camera :)
- A mobile Hotspot (I used a Huawei E1750C). Because getting an UMTS-Stick getting to work with an Pi sucks. Additionally you can easily join the WiFi network for maintenance)
- SIM Card
- (used) Car battery, in my case an 74Ah battery with one dead cell
- Solar panel (12V, 30W eBay around 40€) NOTE: Might be to small!
- Solar charger (f.e. "10A 12V/24V PWM solar panel regler solarpanel" @ ebay for around 15€)
- more to come…
How To
Update your Pi to the latest Linux version
See https://www.datenreise.de/raspberry-pi-raspbian-linux-wheezy-jessie-upgrade/
Scripts
Scripts running on the Pi
knock.sh
#!/bin/bash # knock on -heavens- servers door...(bad joke. sorry) for x in 2323 4242; do nmap -Pn --host_timeout 201 --max-retries 0 -p $x my_fqdn; done
Script: Take picture every minute
Add this to crontab:
# DS18B20 */15 * * * * /home/pi/Development/temperature/readTemperature.sh > /dev/null 2>&1 # # PiCam - Take Snapshot(s) */15 * * * * /home/pi/Development/webcam/takePicture.sh > /dev/null 2>&1
takePicture.sh
#!/bin/bash #set -x # # http://www.wurst-wasser.net/wiki/index.php/Raspberry_Pi_WebCam_with_3G # # Globals # GFOLDERTARGET="/var/www/html/webcam-archive" GFILELOCK="${GFOLDERTARGET}/takePicture.lck" GFILELOCKAGEMAX="60" GTIMESTAMP="`date +'%Y-%m-%d_%H-%M-%S'`" GTIMESTAMPDATE="`date +'%Y-%m-%d'`" # Human readable GTIMESTAMPTIME="`date +'%H:%M:%S'`" # Human readable GTIMESTAMPMINUTES="`date +'%M'`" GTIMESTAMPHOURS="`date +'%H'`" #GTIMESTAMPHOURS="16" #GTIMESTAMPMINUTES="00" GFILETARGET="${GFOLDERTARGET}/${GTIMESTAMP}.jpg" GFILELASTSNAP="/var/www/html/webcam/lastsnap.jpg" GUPLOADEVERYTIME=0 GBASENAME="${0}" function log { logger "${GBASENAME}: $1" echo $1 } if [ "${1}" = "-f" ]; then log "Forcing upload." GUPLOADEVERYTIME=1 fi # # # # Main # # # Check locking if [ -f "${GFILELOCK}" ]; then LOCKFILEAGE="`stat --format=\"%Z\" \"${GFILELOCK}\"`" NOW="`date +'%s'`" AGE="`expr ${NOW} - ${LOCKFILEAGE}`" if [ "${AGE}" -gt "${GFILELOCKAGEMAX}" ]; then log "Lockfile is ${AGE} seconds old, removing it." rm "${GFILELOCK}" else log "Lockfile is ${AGE} seconds old, exiting." exit 1 fi fi # # # Lock echo $$ > "${GFILELOCK}" # # timeout should not be 0, since images will be to dark and are noisy #raspistill --nopreview -t 1 -w 1024 -h 768 -o - # # Since my cam is mounted wrong, I prefer to flip it :) (and flop it) #raspistill --nopreview -t 2 -w 1024 -h 768 -o - | convert - -flip -flop - #raspistill --nopreview -w 1024 -h 768 -o - | convert - -flip -flop - raspistill --nopreview -w 1024 -h 768 -o - | convert - -flip -flop - > "${GFOLDERTARGET}/lastsnap.tmp" # # Bild verkleinern... mogrify -quality "80%" -interlace Plane "${GFOLDERTARGET}/lastsnap.tmp" #mogrify -stroke white -pointsize 10 -gravity SouthEast -draw "text 0,0 '${GTIMESTAMPHR}'" "${GFOLDERTARGET}/lastsnap.tmp" #mogrify -stroke white -pointsize 10 -gravity SouthWest -draw "text 0,0 '${GTIMESTAMPDATE}'" "${GFOLDERTARGET}/lastsnap.tmp" #mogrify -stroke white -pointsize 10 -gravity SouthEast -draw "text 0,0 '${GTIMESTAMPTIME}'" "${GFOLDERTARGET}/lastsnap.tmp" mogrify -stroke black -pointsize 10 -gravity NorthWest -draw "text 0,0 '${GTIMESTAMPDATE}'" "${GFOLDERTARGET}/lastsnap.tmp" mogrify -stroke black -pointsize 10 -gravity NorthEast -draw "text 0,0 '${GTIMESTAMPTIME}'" "${GFOLDERTARGET}/lastsnap.tmp" # # Save the taken picture to the archive, give the file a nice timestamped name mv "${GFOLDERTARGET}/lastsnap.tmp" "${GFILETARGET}" # # Copy the latest image to the "current view" - folder cp "${GFILETARGET}" "${GFILELASTSNAP}" # #raspistill -t 0 -w 1024 -h 768 -o - # # Make a upload to our webserver if [ "${GTIMESTAMPHOURS}" -ge 0 -a "${GTIMESTAMPHOURS}" -le 23 -o "${GUPLOADEVERYTIME}" -eq 1 ]; then # Between 0 and 0 o'clock if [ "${GTIMESTAMPMINUTES}" -eq 0 -o "${GTIMESTAMPMINUTES}" -eq 15 -o "${GTIMESTAMPMINUTES}" -eq 30 -o "${GTIMESTAMPMINUTES}" -eq 45 -o "${GUPLOADEVERYTIME}" -eq 1 ]; then log "Uploading picture..." ~/Development/webcam/knock.sh # scp "${GFILETARGET}" dt:tmp/ sftp dt:tmp/ <<< "put ${GFILETARGET}" fi fi # # Cleanup: Delete all files older than n*24 hours find "${GFOLDERTARGET}" -ctime +1 -delete # # Unlock rm "${GFILELOCK}" # # Exit exit 0
Scripts running on the web server
cronjobs
# m h dom mon dow command 02,17,32,47 * * * * ~/bin/movePictures.sh >> /dev/null 2>&1 # # Create a daily time-lapse 50 23 * * * ~/bin/mergeAllPicturesInOneAnimatedGIF.sh >> /dev/null 2>&1
Scripts
movePictures.sh
(called by crond)
#!/bin/bash #set -x # movePictures.sh # Author: Heiko # Purpose: Move files into place (Webserver), set lastsnap and delete old files... # Globals GFOLDERWWW="/var/www/html/solarcam" GFOLDERWWWIMAGES="${GFOLDERWWW}/webcam-archive" GFILEWWWLASTSNAP="${GFOLDERWWW}/webcam/lastsnap.jpg" GFILEWWWLASTGRAPH="${GFOLDERWWW}/webcam/lastgraph.svg" GHOME="/home/solarcam" # Move the image in place mv "${GHOME}/tmp/"*.jpg "${GFOLDERWWWIMAGES}/" mv "${GHOME}/tmp/"*.svg "${GFOLDERWWWIMAGES}/" # Make the newest "lastsnap" FILENEWEST="`ls -Art \"${GFOLDERWWWIMAGES}\" | grep jpg | tail -1`" cp -p "${GFOLDERWWWIMAGES}/${FILENEWEST}" "${GFILEWWWLASTSNAP}" FILENEWEST="`ls -Art \"${GFOLDERWWWIMAGES}\" | grep svg | tail -1`" cp -p "${GFOLDERWWWIMAGES}/${FILENEWEST}" "${GFILEWWWLASTGRAPH}" # Cleanup: Delete all files older than n*24hrs find "${GFOLDERWWWIMAGES}" -ctime +30 -delete # EOF
mergeAllPicturesInOneAnimatedGIF.sh
(called by crond)
#!/bin/bash set -x # # Script: mergeAllPicturesInOneAnimatedGIF.sh # Author: Heiko Kretschmer # Purpose: Merge all .jpg into one animated .gif # # History: # 2014-03-30, 09:52, h: Creation. Note. default ticks in -delay is n/100 of a second # 2018-03-31, 08:11, h: Moved to dt. Make daily GIF. # # Globals # GFOLDERSOURCE="/var/www/html/solarcam/webcam-archive" GSUFFIXSOURCE="jpg" GTIMESTAMP="`date +'%Y-%m-%d'`" #GTIMESTAMP="2018-03-29" #echo "${GTIMESTAMP}" #exit 0 GFILETARGET="/var/www/html/solarcam/webcam-archive/${GTIMESTAMP}.gif" # (Un)Main # convert -limit area 0 -delay 25 -loop 1 "${GFOLDERSOURCE}/${GTIMESTAMP}*.${GSUFFIXSOURCE}" "${GFILETARGET}"
index.php
(place in your web server directory)
<?php ?> <!doctype html public "-//W3C//DTD HTML 4.0 //EN"> <html> <head> <title>Webcam History</title> <META HTTP-EQUIV="refresh" CONTENT="3600"> </head> <body style="background-color:#EEEEEE"> <H1>Webcam Live Image</H1> <img src="./webcam/lastsnap.jpg" /> <img src="./webcam/lastgraph.svg" /> <H1>Webcam History</H1> <?php $imagepath = "./webcam-archive"; $images = scandir($imagepath); $images = array_reverse($images); // newest on top foreach($images as $curimg) { if (substr($curimg, 0, 1)!="." && filesize("$imagepath/$curimg")>10000 && ( strstr($curimg, ".swf") || strstr($curimg, ".avi") || strstr($curimg, ".mpg") || strstr($curimg, ".jpg") || strstr($curimg, ".gif") ) ) { /* Link to Viewing-Page */ $curimgencoded=urlencode($curimg); echo "<a href='./imageviewer.php?filename=$curimgencoded' alt='Show $curimg' />$curimg<br>\n"; /* Direct Link to Image File */ if (0) { #echo "<H2>$curimg</H2>\n"; #echo "<img src='$imagepath/$curimg' alt='$curimg' /><br>$curimg<br>\n"; echo "<a href='$imagepath/$curimg' alt='$curimg' />$curimg<br>\n"; #echo "<hr>\n"; } } }; ?> <hr> <br/> <a href='./index.php'>Back!</a> </body> </html>
imageviewer.php
(place in your web server directory)
<?php ?> <!doctype html public "-//W3C//DTD HTML 4.0 //EN"> <html> <head> <title>Webcam History</title> <META HTTP-EQUIV="refresh" CONTENT="60"> </head> <body style="background-color:#EEEEEE"> <?php /* Chosen Image */ $filename=htmlspecialchars($_GET["filename"]); echo("<H1>Webcam Archive Image: $filename</H1>\n"); //echo("<H2>Showing " . $filename . "</H2><br/>\n"); $imagepath = "./webcam-archive"; /* Alle Bilder im Archiv finden (Non-Bilder wegfiltern) */ $images = scandir($imagepath); // Alle Bilder im Ordner #echo("images:\n"); #print_r($images); #echo("---\n"); $imagesfiltered=array(); foreach($images as $curimg) // filter alles weg, was kein Bild ist! { #echo("Checking: $curimg<br/>\n"); if (substr($curimg, 0, 1)!="." && filesize("$imagepath/$curimg")>10000 && ( strstr($curimg, ".swf") || strstr($curimg, ".avi") || strstr($curimg, ".mpg") || strstr($curimg, ".jpg") ) ) { array_push($imagesfiltered, $curimg); } } #echo("imagesfiltered:\n"); #print_r($imagesfiltered); #echo("---\n"); /* Finde das vorherige und das nachfolgende Bild */ $idx=array_search($filename, $imagesfiltered); #echo("idx: $idx<br/>\n"); /* Previous Image-Link erzeugen */ $previouslink=""; if ($idx>0) { $previousimage=$imagesfiltered[$idx-1]; $previousimageencoded=urlencode($previousimage); $previouslink="<a href='./imageviewer.php?filename=$previousimageencoded' alt='Show previous image'>< Previous Image <</a>\n"; } /* Next Image-Link erzeugen */ $nextlink=""; if ($idx<count($imagesfiltered)-1) { $nextimage=$imagesfiltered[$idx+1]; $nextimageencoded=urlencode($nextimage); $nextlink="<a href='./imageviewer.php?filename=$nextimageencoded' alt='Show next image'>> Next Image ></a>\n"; } /* Obere Navigation */ echo("<p align='center'>\n"); //echo("$previouslink"); //if (strlen($previouslink) > 1) { echo($previouslink); } if (strlen($previouslink) > 1 ) { echo($previouslink); } echo(" "); // http://de.wikihow.com/Leerzeichen-in-HTML-einfügen if (strlen($nextlink) > 1) { echo($nextlink); } echo("</p>\n"); /* Das Bild */ echo("<p align='center'>\n"); echo("<img src='" . $imagepath . "/" . $filename . "' alt='$filename' />\n"); echo("</p>\n"); /* Untere Navigation */ echo("<p align='center'>\n"); if (strlen($previouslink) > 1 ) { echo($previouslink); } echo(" "); // http://de.wikihow.com/Leerzeichen-in-HTML-einfügen if (strlen($nextlink) > 1) { echo($nextlink); } echo("</p>\n"); if (0) foreach($images as $curimg) { if (substr($curimg, 0, 1)!="." && filesize("$imagepath/$curimg")>10000 && ( strstr($curimg, ".swf") || strstr($curimg, ".avi") || strstr($curimg, ".mpg") || strstr($curimg, ".jpg") ) ) { #echo "<H2>$curimg</H2>\n"; #echo "<img src='$imagepath/$curimg' alt='$curimg' /><br>$curimg<br>\n"; echo "<a href='$imagepath/$curimg' alt='$curimg' />$curimg<br>\n"; #echo "<hr>\n"; } }; ?> <hr> <br/> <a href='./index.php'>Back!</a> </body> </html>
Tips
- Remember that this Pi is in the wild and easily stolen or all the data read
- Don't use your usual passwords for this project
- Don't store keys on the Pi
- Let your master server fetch the data (so no private keys are stored on the Pi) or use a chroot environment
- Create a special user to access the data from remote, or even better, get it per HTTP and use .htaccess for privacy (and less 3G-traffic ;) )
- If your WiFi connection breaks regularly, see Raspberry Pi WiFi issue (Solarcam)
?
- Links
- ↑ Since setting up the 3G-Stick was a pain in...