#!/usr/bin/python
# Downloads JPEG images from ALLNET ALL2281 WLAN Camera
# Saves netcam images if something moves

netcam_address='192.168.1.117'
user='admin'
password=''
threshold=8 # should be 2x above noise
min_size=6000 # complete darkness
step=5 # step=1 takes about one second per image
delay=0.5 # delay=0 crashes the webcam

def getMJPG(url,readLength=20000,multiple=False):
 import urllib,sys,exceptions
 try: stream=urllib.urlopen(url).read(readLength)
 except exceptions.KeyboardInterrupt: raise
 except:
  print sys.exc_info()[1]
  return getMJPG(url,readLength=readLength)
 if multiple: return stream
 header=stream.split('\r\n\r\n')[0]
 content_length=int(header.split('Length: ')[1])
 if content_length>readLength: return getMJPG(url,readLength=readLength*2)
 data_start=len(header)+4
 return stream[data_start:(data_start+content_length)]

def compare_images(jpeg1,jpeg2):
 import Image,StringIO
 i1, i2=Image.open(StringIO.StringIO(jpeg1)), Image.open(StringIO.StringIO(jpeg2))
 pix1, pix2 = i1.load(), i2.load()
 total=0
 for i in range(0,i1.size[0],step):
  for j in range(0,i1.size[1],step): 
   total+=sum(map(lambda c1,c2 : abs(c1-c2),pix1[i,j],pix2[i,j]))
 area=i1.size[0]/step*i1.size[1]/step
 return total/3/area

def wait(s):
 time.sleep(delay)
 return s

def save_file(x):
 ofn='netcam%d.jpg' % int(time.time()*100)
 open(ofn,'w').write(x)
 return '%d byte written to %s' % (len(x),ofn)

url='http://%s:%s@%s/cgi/mjpg/mjpg.cgi' % (user,password,netcam_address)
import time
last,on,zero_count=False,False,0
while True:
 jpeg=getMJPG(url)
 if len(jpeg)<min_size: 
  last=jpeg
  print wait( '%d byte of darkness' % len(jpeg) )
  continue
 if last:
  if len(jpeg)==len(last): 
   last=jpeg
   print wait( 'Size identical' )
   continue
  d=compare_images(last,jpeg)
  if d>threshold: on=True
  if d<threshold/2: zero_count+=1
  else: zero_count=0
  if zero_count==threshold: on=False # musn't be exactly threshold
 if on: print save_file(jpeg)
 elif last: print wait( 'size = %d, diff = %d' % (len(jpeg),d) )
 last=jpeg