
## Kaivetaan FMI:n tuntidataa rajapinnasta koko Suomelle!

from fmiopendata.wfs import download_stored_query
import datetime 
from datatable import (dt, f, by, ifelse, update, sort,
                       count, min, max, mean, sum, rowsum)
import os

# Tähän aloitusaika!
ogstartdate = datetime.datetime.strptime("01/01/2015", "%m/%d/%Y")

# tähän päivien määrä kerralla - max 31 
days_at_once = 31

# Tähän paikka datalle
os. chdir("E:/data/")

# Tehdään alikansio jos semmosta ei oo

if os.path.exists("./fmidata/") == False:
      os.makedirs("./fmidata/")      

date_1 = ogstartdate

# Tähän lopetusaika! Tai siis vikan 31 päivän ikkunan aloitusaika!
# Nimittäin nyt pyöritetään ihan helvetisti dataa 31 päivän ikkunoissa vuodesta 2005 vuoteen 2023 joka helvetin sääasemalta!
# Tää rajapinta rajaa sen siihen. Päivädataa sai vuosi kerrallaan, mut toisaalta 365 riviä per sijainti vrt 744 riviä jo nyt.
while date_1 < datetime.datetime.strptime("01/01/2024", "%m/%d/%Y"):
            




            # Tallennetaan ne neljään listaan jotka on listassa, väliaikaisesti siis!
            # Tehdään nää joka loopilla erikseen ettei muisti täyty. En kyllä tiedä täyttyisikö muutenkaan, mutta turvallisempaa näin.
            # Dataa aggregoidaan myöhemmin päivätasolle, joten ihan näppärää ettei tuntitason data pysy muistissa pidempään kuin sitä tarttee. 
            # Vähän lisää säästöä saisi kun tän tyhjäisi heti kun siitä on tehty datatable, mut ei tää niin tarkkaa ole.
            tempdata = [[],[],[],[]]

            # Aikaikkuna!
            now = date_1
            to = date_1 + datetime.timedelta(days=days_at_once-1, hours=23, minutes=59, seconds=59)
            
            # Aika kulkee, kellot laukkaa
            # Monta raukkaa hauta haukkaa           
            date_1 = date_1 + datetime.timedelta(days=days_at_once)

            current_time = datetime.datetime.now() 
            print("The time is %s. I am currently fondling %s to %s..." % (current_time, now, to))

            # Skipataan jos löytyy jo!
            if os.path.exists('./fmidata/fmi_%s.csv' % (now.strftime('%Y-%m-%d'))):
                    print("./fmidata/fmi_%s.csv already exists, so we can skip it!" % (now.strftime('%Y-%m-%d')))
                    continue
            

            # Tehdään pyyntö!

            start_time = now.strftime('%Y-%m-%dT00:00:00Z')
            end_time = to.strftime('%Y-%m-%dT23:59:59Z')

            # Tässä nyt looppi joka yrittää uudestaan ja uudestaan kutsua jos se timeouttaa tms.
            # Rupes nimittäin timeouttaamaan.
            done = False
            while(done == False):
                  try:
                        model_data = download_stored_query("fmi::observations::weather::hourly::multipointcoverage",
                                                            args=["starttime=" + start_time,
                                                                  "endtime=" + end_time,
                                                                  "bbox=19.0832098, 59.4541578, 31.5160921567, 70.1641930203", #Tää rajaa koordinaateilla tiedot koko Suomeen ja Affenanmaahan. Ei siellä enempää tosin olekaan joten vois laittaa vaikka koko maailman. Jotain pitää kuitenkin laittaa joten näin.
                                                                  "parameters=TA_PT1H_AVG,PRA_PT1H_ACC"]) # Halutut muuttujat. Voisi jättää laittamatta ja ottaa kaiken.
                        done = True
                  except:
                         print("Failed :( Now retrying...")
                         
            data = model_data.data

            # Loopataan dict-in-dict-in-dict-indict helvettiä! 
            # Ensimmäinen dict: Ajat.
            for date in data.keys():
                  #Toinen dict: Sijainnit
                  for loc in data[date]:
                        # Loput dictit: itse muuttujat. Laitetaan siihen aikaisempaan listalistaan tiedot että saadaan tunti-sääasema-tason dataa.
                        tempdata[0].append(date)
                        tempdata[1].append(loc)  
                        tempdata[2].append(data[date][loc]['Air temperature']['value'])
                        tempdata[3].append(data[date][loc]['Precipitation amount']['value'])



            
            # Tehdään datatable noista. Ois kyllä onnistunut myös tekemällä rivejä tossa ylempänä jolloin ei tarttis näitä list-in-listejä, mut ihan sama, en jaksanut opetella vielä miten se Pythonin datatablessa tapahtuu.
            d = dt.Frame(date = tempdata[0], loc = tempdata[1], temp = tempdata[2], rain = tempdata[3])

            # Jaetaan päivämäärä-kellonaika osiin!
            d['hour'] = d[:,dt.time.hour(f.date)]
            d['date'] = d[:,dt.time.ymd(dt.time.year(f.date), dt.time.month(f.date), dt.time.day(f.date))]

            # Aggregoidaan!
            d2 = d[:, {"avgtemp": mean(f.temp), 
                  "maxtemp": max(f.temp),
                  "mintemp": min(f.temp),
                  "rain": sum(f.rain),
                  "rain_hours": count(f.rain)}, by('date', 'loc')]
            


            # Väliaikatallennus
            d2.to_csv('./fmidata/fmi_%s.csv' % (now.strftime('%Y-%m-%d')), sep=';')

            # Vakuutetaan että kaikki on ok!
            print("Done!")


# Yhdistetään.
print("Combining...")


# Tänne tulee lopullinen data
megad = dt.Frame()


dead = False
while(not dead):
      tmpdata = None
      try:
            tmpdata = dt.fread('./fmidata/fmi_%s.csv' % (ogstartdate.strftime('%Y-%m-%d')))
      except:
            print('The file ./fmidata/fmi_%s.csv does not exist. Combination done!' % (ogstartdate.strftime('%Y-%m-%d')))
            break 
      
      
      ogstartdate = ogstartdate + datetime.timedelta(days=days_at_once)
      megad = dt.rbind(megad, tmpdata)



megad.to_csv("./fmidata_full.csv", sep=";")