import badge, easywifi, ugfx, gc, easydraw, deepsleep, time, math, machine
import urequests as requests

global appname
appname = "Rainfall"

global lat,lon,sleepReset

sleepReset = False
try:
    import system
    sleepReset = system.isWakeup()
except:
    sleepReset = machine.reset_cause() == machine.DEEPSLEEP_RESET

ugfx.set_lut(ugfx.LUT_FASTER)
ugfx.clear(ugfx.WHITE)
if sleepReset:
    ugfx.string_box(0,0,ugfx.width(),ugfx.height(), "Refreshing...", "Roboto_Regular22", ugfx.BLACK, ugfx.justifyCenter)
    ugfx.flush()   
else:
	ugfx.flush(ugfx.LUT_FULL)
	badge.eink_busy_wait()
	easydraw.msg("Welcome!", appname, True)

easywifi.enable(not sleepReset)
if easywifi.state==False:
    if not sleepReset:
        easydraw.msg("Unable to connect to network!","FAILURE")
        easydraw.msg("Waiting 5 seconds to try again!")
        badge.eink_busy_wait()
    import machine
    machine.deepsleep(5000)

if not sleepReset:
    easydraw.msg("Checking for updates...")

try:
    import woezel
    woezel.install('Rain')
    if not sleepReset:
        easydraw.msg("Updated! Restarting...")
        badge.eink_busy_wait()
    deepsleep.reboot()
except:
    if not sleepReset:
        easydraw.msg("No updates available.")

if (badge.nvs_get_str("regenval", "lat", "") == "") or (badge.nvs_get_str("regenval", "lon", "") == ""):
    if not sleepReset:
        easydraw.msg("No location set!", appname)
        easydraw.msg("Using lat/lon of Eindhoven", appname)
        easydraw.msg("Change: badge.nvs_get_str('regenval', 'lat', '[latitude]')", appname)
        easydraw.msg("and badge.nvs_get_str('regenval', 'lon', '[longitude]')", appname)
        time.sleep(5)

lat = badge.nvs_get_str("regenval", "lat", "51.4416")
lon = badge.nvs_get_str("regenval", "lon", "5.4697")

if not sleepReset:
    easydraw.msg("Fetching data...", appname)

# Buienalarm: if you're reading this, please continue to let me use your undocumented API :)
data = requests.get("https://cdn-secure.buienalarm.nl/api/3.4/forecast.php?lat=" + lat + "&lon=" + lon + "&region=nl&unit=mm/u")
content = data.text
data.close()
gc.collect()

import ujson
try:
    result = ujson.loads(content)
except:
    if not sleepReset:
        easydraw.msg("Invalid response or could not parse json","FAILURE")
        easydraw.msg("Waiting 30 seconds to try again!")
        badge.eink_busy_wait()
    import machine
    machine.deepsleep(30000)
    
gc.collect()

if result['success'] != True:
    if not sleepReset:
        easydraw.msg("API returns unsuccesful","FAILURE")
        easydraw.msg("Please verify that lat/lon are correct")
        easydraw.msg("Waiting 30 seconds to try again!")
        badge.eink_busy_wait()
    import machine
    machine.deepsleep(30000)    



# 8 bars, 32 pixels wide each with 5 pixel spacing
# Roboto_Regular12: about 31px wide and 12px high for each time
# ugfx.width() x ugfx.height(): 296 x 128

# ugfx.set_default_font("Roboto_Regular12");
ugfx.clear(ugfx.WHITE)
# if not sleepReset:
#    ugfx.flush(ugfx.LUT_FULL)

maxBarHeight = ugfx.height() - 17 - 15
ugfx.line(0, maxBarHeight + 1 + 15, ugfx.width(), maxBarHeight + 1 + 15, ugfx.BLACK)

global rain
rain = False

for i in range(0,8):
    curFullTime = time.localtime(result['start'] + 2 * i * result['delta'])
    curTime = "%02d:%02d" % (curFullTime[3], curFullTime[4])
    curMeasurement = result['precip'][i * 2]
    nextMeasurement= result['precip'][i * 2 + 1]

    if nextMeasurement > curMeasurement: # display highest of two measurements within 10 minute interval
        curMeasurement = nextMeasurement
    if curMeasurement > 0:
        rain = True

    # Scaling, range: 0 to result['levels']['heavy'] mm/h
    height = int(round(maxBarHeight * math.log10(curMeasurement + 1) / math.log10(result['levels']['heavy'] * 2 + 1))) # simple logarithmic scale
    if height > maxBarHeight:
        height = maxBarHeight

    ugfx.fill_rounded_box(i * 37 + 2, maxBarHeight - height + 15, 32, height, 2, ugfx.BLACK)
    ugfx.string_box(i * 37, maxBarHeight + (ugfx.height() - maxBarHeight - 15), 37, 15, curTime, "Roboto_Regular12", ugfx.BLACK, ugfx.justifyCenter)

    if height > maxBarHeight - 15:
        yPos = 15
    else: 
        yPos = maxBarHeight - height

    ugfx.fill_rounded_box(i * 37, yPos, 37, 15, 1, ugfx.WHITE)
    roundedString = "%d.%d" % (int(round(curMeasurement, 1)), int(10*round(curMeasurement % 1,1)))
    ugfx.string_box(i * 37, yPos, 37, 15, roundedString, "Roboto_Regular12", ugfx.BLACK, ugfx.justifyCenter)

    # If precipitation exceeds maximum, display a gap in the bar
    if curMeasurement > result['levels']['heavy'] * 2:
        ugfx.thickline(i * 37 + 2, 40, (i + 1) * 37 - 2, 50, ugfx.WHITE, 3, False)
        
if not rain:
	ugfx.string_box(0, int(maxBarHeight/2) - 11, ugfx.width(), 26, "No rain expected", "Roboto_Regular22", ugfx.BLACK, ugfx.justifyCenter)


width = ugfx.get_string_width("mm/h", "Roboto_Regular12")
ugfx.fill_rounded_box(ugfx.width() - width - 24, 0, width + 5, 15, 3, ugfx.BLACK)
ugfx.string_box(ugfx.width() - width - 24, 0, width + 5, 15, "mm/h", "Roboto_Regular12", ugfx.WHITE, ugfx.justifyCenter)

tempString = "%d   C" % (result['temp'])
width = ugfx.get_string_width(tempString, "Roboto_Regular18")
oWidth = ugfx.get_string_width("%d " % (result['temp']), "Roboto_Regular18")
ugfx.string(1, 0, tempString, "Roboto_Regular18", ugfx.BLACK)
ugfx.string(oWidth-1, -3, "o", "Roboto_Regular18", ugfx.BLACK)

badge.eink_busy_wait()
ugfx.flush(ugfx.GREYSCALE)
badge.eink_busy_wait()

deepsleep.start_sleeping(600000) # Sleep for 10 minutes