import badge, easywifi, ugfx, gc, easydraw, deepsleep, time, math, machine
import urequests as requests

global appname
appname = "Rainfall"

global lat,lon,sleepReset

sleepReset = machine.reset_cause() == machine.DEEPSLEEP_RESET

ugfx.clear(ugfx.WHITE)
if sleepReset:
    ugfx.string_box(0,0,ugfx.width(),15, "Loading...", "Roboto_Regular12", ugfx.BLACK, ugfx.justifyLeft)
    ugfx.flush(ugfx.LUT_FASTEST)   
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)

# proxy because urequests doesn't support chunked transfer encoding
# original url: https://gps.buienradar.nl/getrr.php?lat=[latitude]&lon=[longitude]
data = requests.get("https://nefas.me/rain/?lat=" + lat + "&lon=" + lon)
content = data.text
data.close()
gc.collect()

measurements = content.splitlines()

# 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
ugfx.line(0, maxBarHeight + 1, ugfx.width(), maxBarHeight + 1, ugfx.BLACK)

global rain
rain = False

for i in range(0,8):
    (curMeasurement, curTime) = measurements[i * 2].split('|')
    (nextMeasurement, nextTime) = measurements[i * 2 + 1].split('|')
    curMeasurement = int(curMeasurement)
    nextMeasurement = int(nextMeasurement)
    if nextMeasurement > curMeasurement: # display highest of two measurements within 10 minute interval
        curMeasurement = nextMeasurement
        
    if curMeasurement > 0:
        rain = True

    curMeasurement = 10 ** ((curMeasurement - 109) / 32) # convert to mm/h
    # print("%s: %f" % (curTime, curMeasurement))

    # Scaling, range: 0 to 30 mm/h
    # height = int(round(maxBarHeight * curMeasurement / 30.0))
    height = int(round(maxBarHeight * math.log10(curMeasurement + 1) / math.log10(31))) # simple logarithmic scale
    if height > maxBarHeight:
        height = maxBarHeight

    ugfx.fill_rounded_box(i * 37 + 2, maxBarHeight - height, 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 = 0
    else: 
        yPos = maxBarHeight - height - 15

    ugfx.fill_rounded_box(i * 37, yPos, 37, 15, 1, ugfx.WHITE)
    roundedString = "%d.%d" % (int(round(curMeasurement, 1)), int(10*round(curMeasurement,1)))
    ugfx.string_box(i * 37, yPos, 37, 15, roundedString, "Roboto_Regular12", ugfx.BLACK, ugfx.justifyCenter)

    # If precipitation exceeds 30mm/h, display a gap in the bar
    if curMeasurement > 30.0:
        ugfx.thickline(i * 37 + 2, 15, (i + 1) * 37 - 2, 25, ugfx.WHITE, 3, False)
        
if not rain:
	ugfx.string_box(0, int(maxBarHeight/2) - 11, ugfx.width(), 22, "No rain expected \o/", "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)

badge.eink_busy_wait()
ugfx.flush(ugfx.LUT_FULL)
badge.eink_busy_wait()

deepsleep.start_sleeping(600000) # Sleep for 10 minutes