from urllib.request import urlopen
from PIL import Image
from pygame.locals import *
from datetime import date

import json,pygame, time, sys, random

YourKey = ''

numrows = 16
ledsrow = 18
numleds = numrows * ledsrow

#
# Min and Max temperature values for each month
#

def colorRange():
    today=date.today()

    if   (today.month == 1): minTempRange = -15 ; maxTempRange = 20
    elif (today.month == 2): minTempRange = -15 ; maxTempRange = 25
    elif (today.month == 3): minTempRange = -10 ; maxTempRange = 25
    elif (today.month == 4): minTempRange = -10 ; maxTempRange = 30
    elif (today.month == 5): minTempRange = -10 ; maxTempRange = 30
    elif (today.month == 6): minTempRange = -10 ; maxTempRange = 35
    elif (today.month == 7): minTempRange = -10 ; maxTempRange = 40
    elif (today.month == 8): minTempRange = -10 ; maxTempRange = 40
    elif (today.month == 9): minTempRange = -10 ; maxTempRange = 35
    elif (today.month == 10):minTempRange = -10 ; maxTempRange = 30
    elif (today.month == 11):minTempRange = -15 ; maxTempRange = 25
    else:                    minTempRange = -15 ; maxTempRange = 20

    return minTempRange,maxTempRange

#
# RGB colors for (temperature/10)
#

def colorMap(minTempRange=-20,maxTempRange=40,maxValue=255):
    minRange   = abs(minTempRange*10)+1
    plusRange  = int((maxTempRange*10)/2)+1
    minFactor  = abs(maxValue/minRange)
    plusFactor = maxValue/plusRange

    resultRed   = []
    resultGreen = []
    resultBlue  = []

    for x in range (plusRange):
            resultRed.append   (int(maxValue))
            resultGreen.append (int(maxValue-x*plusFactor))
            resultBlue.append  (int(0))

    for x in range (plusRange):
            resultRed.append   (int(maxValue-x*plusFactor/2))
            resultGreen.append (int(0))
            resultBlue.append  (int(x*plusFactor/2))

    for x in range (minRange):
            resultRed.append   (int(x*minFactor))
            resultGreen.append (int(x*minFactor))
            resultBlue.append  (int(maxValue-x*minFactor))

    return resultRed, resultGreen, resultBlue

#
# weather Underground data
#

def weatherForecast(YourKey):
    try:
        weatherUrl = urlopen('http://api.wunderground.com/api/' + YourKey + '/forecast/q/NL/Twenthe%20Air%20Base.json')
        json_string = weatherUrl.read()
        forecast_json = json.loads(json_string.decode('utf-8'))

        with open('forecast.txt', 'w') as jsonfile:
            json.dump(forecast_json, jsonfile)
        jsonfile.close()

        temp_high0 = forecast_json['forecast']['simpleforecast']['forecastday'][0]['high']['celsius']
        temp_low0  = forecast_json['forecast']['simpleforecast']['forecastday'][0]['low']['celsius']
        temp_high1 = forecast_json['forecast']['simpleforecast']['forecastday'][1]['high']['celsius']
        temp_low1  = forecast_json['forecast']['simpleforecast']['forecastday'][1]['low']['celsius']

        weatherUrl.close

        if str(temp_high0) != "":
            temp_high0 = int(float(temp_high0)*10)
        else:
            temp_high0 = int(float(temp_high1)*10)

        if str(temp_high1) != "":
            temp_high1 = int(float(temp_high1)*10)
        else:
            temp_high1 = int(float(temp_high0)*10)

        if str(temp_low0) != "":
            temp_low0  = int(float(temp_low0)*10)
        else:
            temp_low0  = int(float(temp_low1)*10)

        if str(temp_low1) != "":
            temp_low1  = int(float(temp_low1)*10)
        else:
            temp_low0  = int(float(temp_low0)*10)

    except Exception as diag:
        temp_high0 = 400
        temp_low0 = -200
        temp_high1 = 400
        temp_low1 = -200
        print(diag.__class__.__name__,':',diag)

    return min(temp_low0, temp_low1), max(temp_high0, temp_high1)

#
# weather Underground data
#

def weatherConditions(YourKey):
    try:
        weatherUrl = urlopen('http://api.wunderground.com/api/' + YourKey + '/conditions/q/NL/Twenthe%20Air%20Base.json')
        json_string = weatherUrl.read()
        conditions_json = json.loads(json_string.decode('utf-8'))

        with open('conditions.txt', 'w') as jsonfile:
            json.dump(conditions_json, jsonfile)
        jsonfile.close()

        temp_now = conditions_json['current_observation']['temp_c']
        wind_dir = conditions_json['current_observation']['wind_degrees']
        wind_kph = conditions_json['current_observation']['wind_kph']
        real_rain = conditions_json['current_observation']['precip_1hr_metric'] # actual rain

        weatherUrl.close

        temp_now  = int(float(temp_now)*10)
        wind_kph  = float(wind_kph)
        real_rain = float(real_rain)

    except Exception as diag:
        temp_now = 0
        wind_dir = N
        wind_kph = 0
        real_rain = 0
        print(diag.__class__.__name__,':',diag)

    return temp_now, wind_kph, wind_dir, real_rain

#
# weather Underground data
#

def weatherHourly(YourKey):
    try:
        weatherUrl = urlopen('http://api.wunderground.com/api/' + YourKey + '/hourly/q/NL/Twenthe%20Air%20Base.json')
        json_string = weatherUrl.read()
        hourly_json = json.loads(json_string.decode('utf-8'))

        with open('hourly.txt', 'w') as jsonfile:
            json.dump(hourly_json, jsonfile)
        jsonfile.close()

        hour_rain = hourly_json['hourly_forecast'][0]['qpf']['metric'] # Quantitative Precipitation Forecasts
        hour_snow = hourly_json['hourly_forecast'][0]['snow']['metric']

        weatherUrl.close()

    except Exception as diag:
        hour_rain = 0
        hour_snow = 0
        print(diag.__class__.__name__,':',diag)

    return hour_rain, hour_snow

#
# LEDs
#

class WS2812:
    def __init__(self,color,screen):
        self.c = color
        self.screen = screen
        self.draw()

    def draw(self):
        for x in range (numrows):
            for y in range (ledsrow):
                led = pygame.draw.rect (screen,self.c[x*ledsrow+y],(32+x*24,16+ledsrow*24-y*24,24-8,24-8))
        pygame.display.update ()

    def color(self,color):
        self.c = color
        self.draw ()

#
# Main
#

minTempRange = -20
maxTempRange = 40

maxBrightBackground = 200
maxBrightForeground = 255

colorMapRed,colorMapGreen,colorMapBlue = colorMap(minTempRange,maxTempRange,maxBrightBackground)

# image = Image.new( 'RGB', (len(colorMapRed),100), "white")
# pixels = image.load()
# for x in range (len(colorMapRed)):
#     for y in range (100):
#         pixels[x,y] = (colorMapRed[x], colorMapGreen[x], colorMapBlue[x])
# image.save("weatherLampMap.png")

pygame.init()
screen = pygame.display.set_mode ((64+numrows*24,32+64+ledsrow*24),0,32)
screen.fill ((255,255,255))
pygame.display.set_caption ('NeoPixel Matrix')

colorarray = []

for i in range (numleds):
    colorarray.append (i)
    colorarray[i] = (colorMapRed[0],colorMapGreen[0],colorMapBlue[0])

led = WS2812 (colorarray,screen)
led.color (colorarray)
time.sleep(1)

#
# Display all temperature colors (demo)
#

for t in range (-20,40):
    for i in range (numleds):
        color = colorMapRed[t*10],colorMapGreen[t*10],colorMapBlue[t*10]
        colorarray[i] = color
    led.color (colorarray)
#   pygame.image.save(screen, "screenshot"+str(t)+".png")

    time.sleep(.1)

#
# Thermometer demo
#

minTempRange,maxTempRange = colorRange()

colorBackgroundRed,colorBackgroundGreen,colorBackgroundBlue = colorMap(minTempRange,maxTempRange,maxBrightBackground) # colors for matrix
colorForegroundRed,colorForegroundGreen,colorForegroundBlue = colorMap(minTempRange,maxTempRange,maxBrightForeground) # colors for temperature

image = Image.new( 'RGB', (len(colorBackgroundRed),100), "white")
pixels = image.load()
for x in range (len(colorBackgroundRed)):
    for y in range (100):
        pixels[x,y] = (colorBackgroundRed[x], colorBackgroundGreen[x], colorBackgroundBlue[x])
image.save("weatherLampMap.png")

#
# Get Data
#

temp_low,temp_high = weatherForecast(YourKey)
#print (temp_low)
#print (temp_high)

temp_now, wind_dir, wind_kph, real_rain = weatherConditions(YourKey);
print (temp_now)
# print (wind_dir)
# print (wind_kph)
# print (real_rain)

hour_rain, hour_snow = weatherHourly(YourKey)
# print (hour_rain)
# print (hour_snow)

#
# Background for matrix
#

backgroundarray = []
for i in range (numleds):
    backgroundarray.append (i)

for t in range (18):
    cindx = int (temp_low + (temp_high-temp_low)*t/18)
    color = colorBackgroundRed[cindx],colorBackgroundGreen[cindx],colorBackgroundBlue[cindx]

    for r in range (16):
        backgroundarray[t+r*18]=color

led.color (backgroundarray)

time.sleep(1)

#
# loop 18 lines
#

color = (128,128,128)

for r in range (18):
    foregroundarray=list(backgroundarray) # copy

    for i in range (16):
        foregroundarray[i*18+r]=color

    led.color (foregroundarray)
    time.sleep(.5)

#
# loop from mintemp to maxtemp
#

for t in range (temp_low, temp_high):
    foregroundarray=list(backgroundarray)

    r = int (18.0/float(temp_high-temp_low)*(t-temp_low))

    print (temp_low,temp_high,t,r)

    for i in range (16):
        if (i%2 == t%2):
            foregroundarray[i*18+r]=(128,128,128)
        else:
            foregroundarray[i*18+r]=colorForegroundRed[t],colorForegroundGreen[t],colorForegroundBlue[t]
    led.color (foregroundarray)
    time.sleep(.5)

#
# loop temperature range
#

r = int (18.0/float(temp_high-temp_low)*(temp_now-temp_low))

foregroundarray=list(backgroundarray)
for i in range (16):
    if    (i%4 == 0):
        foregroundarray[i*18+r]=colorForegroundRed[temp_now],colorForegroundGreen[temp_now],colorForegroundBlue[temp_now]
    elif (i%4 == 1):
        foregroundarray[i*18+r]=colorForegroundRed[temp_now]/2,colorForegroundGreen[temp_now]/2,colorForegroundBlue[temp_now]/2
    elif (i%4 == 2):
        foregroundarray[i*18+r]=colorForegroundRed[temp_now]/3,colorForegroundGreen[temp_now]/3,colorForegroundBlue[temp_now]/3
    elif (i%4 == 3):
        foregroundarray[i*18+r]=colorForegroundRed[temp_now]/4,colorForegroundGreen[temp_now]/4,colorForegroundBlue[temp_now]/4
led.color (foregroundarray)
pygame.image.save(screen, "screenshot0.png")

time.sleep(1)

foregroundarray=list(backgroundarray)
for i in range (16):
    if    (i%4 == 3):
        foregroundarray[i*18+r]=colorForegroundRed[temp_now],colorForegroundGreen[temp_now],colorForegroundBlue[temp_now]
    elif (i%4 == 0):
        foregroundarray[i*18+r]=colorForegroundRed[temp_now]/2,colorForegroundGreen[temp_now]/2,colorForegroundBlue[temp_now]/2
    elif (i%4 == 1):
        foregroundarray[i*18+r]=colorForegroundRed[temp_now]/3,colorForegroundGreen[temp_now]/3,colorForegroundBlue[temp_now]/3
    elif (i%4 == 2):
        foregroundarray[i*18+r]=colorForegroundRed[temp_now]/4,colorForegroundGreen[temp_now]/4,colorForegroundBlue[temp_now]/4
led.color (foregroundarray)
pygame.image.save(screen, "screenshot1.png")

time.sleep(1)

foregroundarray=list(backgroundarray)
for i in range (16):
    if    (i%4 == 2):
        foregroundarray[i*18+r]=colorForegroundRed[temp_now],colorForegroundGreen[temp_now],colorForegroundBlue[temp_now]
    elif (i%4 == 3):
        foregroundarray[i*18+r]=colorForegroundRed[temp_now]/2,colorForegroundGreen[temp_now]/2,colorForegroundBlue[temp_now]/2
    elif (i%4 == 0):
        foregroundarray[i*18+r]=colorForegroundRed[temp_now]/3,colorForegroundGreen[temp_now]/3,colorForegroundBlue[temp_now]/3
    elif (i%4 == 1):
        foregroundarray[i*18+r]=colorForegroundRed[temp_now]/4,colorForegroundGreen[temp_now]/4,colorForegroundBlue[temp_now]/4
led.color (foregroundarray)
pygame.image.save(screen, "screenshot2.png")

time.sleep(1)

foregroundarray=list(backgroundarray)
for i in range (16):
    if    (i%4 == 1):
        foregroundarray[i*18+r]=colorForegroundRed[temp_now],colorForegroundGreen[temp_now],colorForegroundBlue[temp_now]
    elif (i%4 == 2):
        foregroundarray[i*18+r]=colorForegroundRed[temp_now]/2,colorForegroundGreen[temp_now]/2,colorForegroundBlue[temp_now]/2
    elif (i%4 == 3):
        foregroundarray[i*18+r]=colorForegroundRed[temp_now]/3,colorForegroundGreen[temp_now]/3,colorForegroundBlue[temp_now]/3
    elif (i%4 == 0):
        foregroundarray[i*18+r]=colorForegroundRed[temp_now]/4,colorForegroundGreen[temp_now]/4,colorForegroundBlue[temp_now]/4
led.color (foregroundarray)
pygame.image.save(screen, "screenshot3.png")

time.sleep(1)
