#!/usr/bin/python
# -*- coding: UTF-8 -*-
#insert the WeatherUnderground API-key here:
wunder_api = ""
#insert the location for the forecast here. For example "Germany/Berlin"
location = ""
#this decides when it is time to display the forecast for the next day. If you want to show always the forecast for the day, set it to 24 or to display for half a day 12:
switch_time = 24

import urllib2
import json
import sys
import time
import random
import RPi.GPIO as GPIO
from neopixel import *

# LED strip configuration:
LED_COUNT      = 12      # Number of LED pixels.
LED_PIN        = 13      # GPIO pin connected to the pixels (must support PWM!).
LED_FREQ_HZ    = 800000  # LED signal frequency in hertz (usually 800khz)
LED_DMA        = 5       # DMA channel to use for generating signal (try 5)
LED_BRIGHTNESS = 150     # Set to 0 for darkest and 255 for brightest
LED_INVERT     = False   # True to invert the signal (when using NPN transistor level shift)
LED_CHANNEL    = 1       # 0 for pins 18 and 12, and 1 for pins 19 and 13
LED_STRIP      = ws.SK6812_STRIP_RGBW	
#LED_STRIP      = ws.SK6812W_STRIP

rain = 6
cloud = 5

GPIO.setmode(GPIO.BCM)
GPIO.setup(rain, GPIO.OUT, initial=0)
GPIO.setup(cloud, GPIO.OUT, initial=0)

# Define functions which animate LEDs in various ways.
def colorWipe(strip, color, wait_ms=1):
	"""Wipe color across display a pixel at a time."""
	for i in range(strip.numPixels()):
		strip.setPixelColor(i, color)
		strip.show()
		time.sleep(wait_ms/1000.0)

def theaterChase(strip, color, wait_ms=50, iterations=10):
	"""Movie theater light style chaser animation."""
	for j in range(iterations):
		for q in range(3):
			for i in range(0, strip.numPixels(), 3):
				strip.setPixelColor(i+q, color)
			strip.show()
			time.sleep(wait_ms/1000.0)
			for i in range(0, strip.numPixels(), 3):
				strip.setPixelColor(i+q, 0)

def wheel(pos):
	"""Generate rainbow colors across 0-255 positions."""
	if pos < 85:
		return Color(pos * 3, 255 - pos * 3, 0)
	elif pos < 170:
		pos -= 85
		return Color(255 - pos * 3, 0, pos * 3)
	else:
		pos -= 170
		return Color(0, pos * 3, 255 - pos * 3)

def rainbow(strip, wait_ms=20, iterations=1):
	"""Draw rainbow that fades across all pixels at once."""
	for j in range(256*iterations):
		for i in range(strip.numPixels()):
			strip.setPixelColor(i, wheel((i+j) & 255))
		strip.show()
		time.sleep(wait_ms/1000.0)

def rainbowCycle(strip, wait_ms=20, iterations=5):
	"""Draw rainbow that uniformly distributes itself across all pixels."""
	for j in range(256*iterations):
		for i in range(strip.numPixels()):
			strip.setPixelColor(i, wheel(((i * 256 / strip.numPixels()) + j) & 255))
		strip.show()
		time.sleep(wait_ms/1000.0)

def theaterChaseRainbow(strip, wait_ms=50):
	"""Rainbow movie theater light style chaser animation."""
	for j in range(256):
		for q in range(3):
			for i in range(0, strip.numPixels(), 3):
				strip.setPixelColor(i+q, wheel((i+j) % 255))
			strip.show()
			time.sleep(wait_ms/1000.0)
			for i in range(0, strip.numPixels(), 3):
				strip.setPixelColor(i+q, 0)

def lightningStrobe(strip, color):
    	"""Wipe white across display a pixel at a time very quickly."""
	for i in range(strip.numPixels()):
		strip.setPixelColor(i, color)
		strip.show()
		time.sleep(5/1000.0)
	for i in range(strip.numPixels()):
		strip.setPixelColor(i,0)
		strip.show()
		time.sleep(20/1000.0)
	for i in range(strip.numPixels()):
	        strip.setPixelColor(i, color)
		strip.show()
		time.sleep(3/1000.0)
	for i in range(strip.numPixels()):
		strip.setPixelColor(i,0)
		strip.show()
		time.sleep(8/1000.0)		
	for i in range(strip.numPixels()):
		strip.setPixelColor(i, color)
		strip.show()
		time.sleep(5/1000.0)
	for i in range(strip.numPixels()):
		strip.setPixelColor(i,0)
		strip.show()
		time.sleep(10/1000.0)

def snowSparkle(strip, color, wait_ms=100, iterations=20):
    	"""Movie theater light style chaser animation."""
	for j in range(iterations):
		for q in range(3):
			for i in range(0, strip.numPixels(), 3):
				strip.setPixelColor(i+q, color)
			strip.show()
			time.sleep(wait_ms/1000.0)
			for i in range(0, strip.numPixels(), 3):
				strip.setPixelColor(i+q, 0)


#Pull in the weather information from the API				
myweather = json.load(urllib2.urlopen('http://api.wunderground.com/api/' + wunder_api + '/forecast/q/' + location + '.json'))
myweather_sum = myweather['forecast']['simpleforecast']['forecastday']
conditions = {"cloudy" : "cloudy", "nt_cloudy" : "cloudy", "fog" : "cloudy", "nt_fog" : "cloudy", "hazy" : "cloudy", "nt_hazy" : "cloudy", "mostlycloudy" : "cloudy", "nt_mostlycloudy" : "cloudy", "partlycloudy" : "cloudy", "nt_partlycloudy" : "cloudy", "clear" : "sunny", "nt_clear" : "sunny", "sunny" : "sunny", "nt_sunny" : "sunny", "mostlysunny" : "sunny", "nt_mostlysunny" : "sunny", "partlysunny" : "sunny", "nt_partlysunny" : "sunny", "chanceflurries" : "snowy", "nt_chanceflurries" : "snowy", "flurries" : "snowy", "nt_flurries" : "snowy", "chancesnow" : "snowy", "nt_chancesnow" : "snowy", "snow" : "snowy", "nt_snow" : "snowy", "chancerain" : "rainy", "nt_chancerain" : "rainy", "chancesleet" : "rainy", "nt_chancesleet" : "rainy", "sleet" : "rainy", "nt_sleet" : "rainy", "rain" : "rainy", "nt_rain" : "rainy", "tstorms" : "stormy", "nt_tstorms" : "stormy", "chancetstorms" : "stormy", "nt_chancetstorms" : "stormy"}
# conditions (=programs) can be: cloudy, sunny, snowy, rainy, stormy

#These are the different animations for the Weather Conditions:
def rain():
    GPIO.output(5, 1)
    colorWipe(strip, Color(94, 181, 172))  # Purpleish color wipe  
    time.sleep(5000)
    colorWipe(strip, Color(103, 101, 133))  # Purpleish color wipe 
    time.sleep(5000)
    colorWipe(strip, Color(0,0,0), 1) # Blackout neopixels
    GPIO.cleanup() # cleanup all GPIO

def cloud():
    GPIO.output(6, 1)
    theaterChase(strip, Color(150, 150, 150), 50)  # white theater chase
    time.sleep(random.randint(0.5,30))
    colorWipe(strip, Color(0,0,0), 1) # Blackout neopixels
    GPIO.cleanup() # cleanup all GPIO

def sun():
    colorWipe(strip, Color(255, 217, 3))  # Yello color wipe
    time.sleep(random.randint(0.5,30))
    colorWipe(strip, Color(0,0,0), 1) # Blackout neopixels
    GPIO.cleanup() # cleanup all GPIO

def snow():
    GPIO.output(6, 1)
    snowSparkle(strip, Color(255, 255, 255), wait_ms(10))  # white theater chase
    time.sleep(random.randint(0.5,30))
    colorWipe(strip, Color(0,0,0), 1) # Blackout neopixels
    GPIO.cleanup() # cleanup all GPIO
        

def flash():
    GPIO.output(6, 1)
    lightningStrobe(strip, Color(255, 255, 255))  # White lightningStrobe
    time.sleep(random.randint(0.5,30))
    colorWipe(strip, Color(0,0,0), 1) # Blackout neopixels
    GPIO.cleanup() # cleanup all GPIO
    

# Main program logic follows:

#this executes the main loop. E.g. it is looking for the conditions and decides for the animation that should be displayed:
def main_loop():
    while 1:
        # Create NeoPixel object with appropriate configuration.
        strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL, LED_STRIP)
        # Intialize the library (must be called once before other functions).
        strip.begin()
        print ('Press Ctrl-C to quit.')
            try:
                for period in myweather_sum:
                    if period['period'] == ampm:
                        orig_conditions = period['icon']
                prog = conditions[orig_conditions]
            except:
                time.sleep(10)
    #      for period in myweather_sum:
    #       if period['period'] == ampm:
    #          orig_conditions = period['icon']
    #      prog = conditions[orig_conditions]

            if  prog=="rainy":
                rain()
            elif prog=="cloudy":
                cloud()
            elif prog=="sunny":
                sun()
            elif prog=="snowy":
                snow()
            elif prog=="stormy":
                flash()
            else:
                while True:
                    colorWipe(strip, Color(255, 0, 0))  # Red wipe
                    time.sleep(100)
				
if __name__ == '__main__':
    try:
        main_loop()
    except KeyboardInterrupt:
        GPIO.cleanup()
        print >> sys.stderr, '\nExiting by user request.\n'
        sys.exit(0)
