Raspberry Pi WebCam with 3G (Solarcam): Difference between revisions

From Wurst-Wasser.net
Jump to navigation Jump to search
Line 67: Line 67:


====== mergeAllPicturesInOneAnimatedGIF.sh ======
====== mergeAllPicturesInOneAnimatedGIF.sh ======
(called by crond)
  #!/bin/bash
  #!/bin/bash
  set -x
  set -x

Revision as of 23:28, 24 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-Stick Mobile 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

Script: Take picture every minute

Add this to crontab:

* * * * *	/home/pi/Development/webcam/takePicture.sh > /dev/null 2>&1

Add a file named takePicture.sh to ~/Development/webcam/ with this contents:

TBD TBD TBD

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
<?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
<?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)

?


  1. Since setting up the 3G-Stick was a pain in...