Lightweight python motion detection

Brian Flakes posted an example script in the RPI forums for how to do [lightweight python motion detection] which is useful when taking pictures with the RPI camera module.

Converted the example to work with PiCamera.

#get access to the camera
from picamera import PiCamera

import picamera.array #want to do it in memory

from PIL import Image
import requests

#import so we can invoke another script
import subprocess

#sleep so we can wait on the camera
from time import sleep

token = 'YOUR_SECURITY_TOKEN'
selector = 'group_id:SEE_THE_SELECTOR_DOCS'
threshold = 40
sensitivity = 20
firstRun = True
lastPixels = []
detected = False
showPreview = False
hidePreview = False
waitRedlight = 600
i = 0
headers = {
    "Authorization": "Bearer %s" % token,
}

# create a camera object
camera = PiCamera()

#set the image resolution
camera.resolution = (640, 480)

#rotate the camera if upside-down
#camera.rotation = 180

def Greenlight():
  payload = {
    "power": "off",
    "color": "green saturation:0.9",
    "brightness": 1.0,
    "duration": 1
  }
  try:
    response = requests.put('https://api.lifx.com/v1/lights/'+selector+'/state', data=payload, headers=headers)
  except:
    pass

def Redlight():
  payload = {
    "power": "on",
    "color": "white",
    "brightness": 1.0,
    "duration": 1
  }
  try:
    response = requests.put('https://api.lifx.com/v1/lights/'+selector+'/state', data=payload, headers=headers)
  except:
    pass

Greenlight();

while True:

  if (showPreview):
    showPreview = False
    #show preview with some transparency
    camera.start_preview(alpha=200)
    hidePreview = True

  filename = 'image'+str(i)+'.jpg'

  #save image locally
  camera.capture(filename)

  image = Image.open(filename)
  pixels = image.load()

  width, height = image.size
  #print ('width='+str(width)+' height='+str(height)+"\n");

  if (firstRun):
    firstRun = False
    lastPixels = pixels

  # Count changed pixels
  changedPixels = 0
  for x in range(width):
    for y in range(height):
      # Just check green channel as it's the highest quality channel
      pixdiff = abs(pixels[x,y][1] - lastPixels[x,y][1])
      if pixdiff > threshold:
        changedPixels += 1

  print ('changedPixels='+str(changedPixels))
  lastPixels = pixels

  if (changedPixels < 100):
    if (detected):
      detected = False
      Greenlight();
      firstRun = True
  else:
    if (detected == False):
      detected = True
      Redlight();
      sleep(waitRedlight)
      firstRun = True
      showPreview = True

  if (hidePreview):
    hidePreview = False
    #stop the preview
    camera.stop_preview()
    firstRun = True

  sleep(1)

  i = (i + 1) % 12