unit meteo_frame; {$mode ObjFPC}{$H+} interface uses {$ifdef windows} windows, {$endif} Classes, SysUtils, Forms, Controls, StdCtrls, ExtCtrls, Buttons, TAGraph, fphttpclient, opensslsockets, fpjson, jsonparser, graficimeteo, meteoutil, DateUtils, Dialogs; type { TMeteoView } TMeteoView = class(TFrame) Image2: TImage; Image3: TImage; Image4: TImage; Panel1: TPanel; TitoloLabel: TLabel; Evento1Label: TLabel; Evento2Label: TLabel; Evento3Label: TLabel; EventiPanel: TPanel; SpeedButton1: TSpeedButton; CondizioniMeteoLabel: TLabel; VisibilitaLabel: TLabel; Label3: TLabel; CoperturaLabel: TLabel; VentoBassoLabel: TLabel; procedure OttieniMeteoClick(Sender: TObject; giornometeo: TDateTime; https:boolean; lat,long : double; orasimulazione:byte); procedure FrameResize(Sender: TObject); procedure SpeedButton1Click(Sender: TObject); private public end; implementation {$R *.lfm} { TMeteoView } var isfirsttime:boolean=True; MeteoJSON: TJSONData; OggettoJSON: TJSONObject; meteotext:string; latitudine:real=39.2; longitudine:real=9.2; posgiornometeo:integer; //la posizione relativa del giorno meteo rispetto al giorno attuale // giornometeo:integer; procedure TMeteoView.OttieniMeteoClick(Sender: TObject; giornometeo: TDateTime; https:boolean; lat, long:double; orasimulazione:byte); var orameteo:string;//questa è l'ora del meteo che viene usata per le previsioni //è rappresentata da un numero da 1 a 24x7, 7 sono i giorni delle previsioni apimeteourl:string; nasafile: TextFile; nasalinea: string; nasastringlist:TStringList; RisorseStream: TResourceStream; elementi:string; segnaposto: byte; oggi:TDateTime; copertura, ventobasso, ventoalto, visibilita, temperatura, precipitazione:string; begin Application.ProcessMessages; oggi:= EncodeDate(YearOf(Now), MonthOf(Now), DayOf(Now)); posgiornometeo:= DateUtils.DaysBetween(oggi, giornometeo); Label3.Caption:='Ore '+inttostr(orasimulazione); if isfirsttime then begin isfirsttime:=False; apimeteourl:=stringarichiesta(https, lat, long); try meteotext:=TFPHttpClient.SimpleGet(apimeteourl); except On e:Exception do begin //in caso di errore isfirsttime sempre true isfirsttime:=True; if e.Message='Could not initialize OpenSSL library' then begin Dialogs.ShowMessage('Installa OpenSSL per usare HTTP sicuro (HTTPS) altrimenti disabilitalo dalle impostazioni.'); end; end; end; //ESocketError end; if ((oggi>giornometeo) or (posgiornometeo>6)) or isfirsttime then //sono 6 giorni e non 7 perchè posgiornometeo inizia da 0 e non 1 begin copertura:= '---'; temperatura:= '---'; ventobasso:= '---'; ventoalto:= ' ---'; visibilita:= '---'; precipitazione:= '---'; SpeedButton1.Enabled:=False; end else begin SpeedButton1.Enabled:=True; orameteo:=inttostr((posgiornometeo)*24+orasimulazione); //meteotext:='{"latitude":40.0,"longitude":9.1875,"generationtime_ms":0.9932518005371094,"utc_offset_seconds":0,"timezone":"GMT","timezone_abbreviation":"GMT","elevation":886.0,"hourly_units":{"time":"iso8601","weather_code":"wmo code","temperature_2m":"°C","wind_speed_10m":"km/h","wind_speed_180m":"km/h","visibility":"m","cloud_cover":"%"},"hourly":{"time":["2026-01-31T00:00","2026-01-31T01:00","2026-01-31T02:00","2026-01-31T03:00","2026-01-31T04:00","2026-01-31T05:00","2026-01-31T06:00","2026-01-31T07:00","2026-01-31T08:00","2026-01-31T09:00","2026-01-31T10:00","2026-01-31T11:00","2026-01-31T12:00","2026-01-31T13:00","2026-01-31T14:00","2026-01-31T15:00","2026-01-31T16:00","2026-01-31T17:00","2026-01-31T18:00","2026-01-31T19:00","2026-01-31T20:00","2026-01-31T21:00","2026-01-31T22:00","2026-01-31T23:00","2026-02-01T00:00","2026-02-01T01:00","2026-02-01T02:00","2026-02-01T03:00","2026-02-01T04:00","2026-02-01T05:00","2026-02-01T06:00","2026-02-01T07:00","2026-02-01T08:00","2026-02-01T09:00","2026-02-01T10:00","2026-02-01T11:00","2026-02-01T12:00","2026-02-01T13:00","2026-02-01T14:00","2026-02-01T15:00","2026-02-01T16:00","2026-02-01T17:00","2026-02-01T18:00","2026-02-01T19:00","2026-02-01T20:00","2026-02-01T21:00","2026-02-01T22:00","2026-02-01T23:00","2026-02-02T00:00","2026-02-02T01:00","2026-02-02T02:00","2026-02-02T03:00","2026-02-02T04:00","2026-02-02T05:00","2026-02-02T06:00","2026-02-02T07:00","2026-02-02T08:00","2026-02-02T09:00","2026-02-02T10:00","2026-02-02T11:00","2026-02-02T12:00","2026-02-02T13:00","2026-02-02T14:00","2026-02-02T15:00","2026-02-02T16:00","2026-02-02T17:00","2026-02-02T18:00","2026-02-02T19:00","2026-02-02T20:00","2026-02-02T21:00","2026-02-02T22:00","2026-02-02T23:00","2026-02-03T00:00","2026-02-03T01:00","2026-02-03T02:00","2026-02-03T03:00","2026-02-03T04:00","2026-02-03T05:00","2026-02-03T06:00","2026-02-03T07:00","2026-02-03T08:00","2026-02-03T09:00","2026-02-03T10:00","2026-02-03T11:00","2026-02-03T12:00","2026-02-03T13:00","2026-02-03T14:00","2026-02-03T15:00","2026-02-03T16:00","2026-02-03T17:00","2026-02-03T18:00","2026-02-03T19:00","2026-02-03T20:00","2026-02-03T21:00","2026-02-03T22:00","2026-02-03T23:00","2026-02-04T00:00","2026-02-04T01:00","2026-02-04T02:00","2026-02-04T03:00","2026-02-04T04:00","2026-02-04T05:00","2026-02-04T06:00","2026-02-04T07:00","2026-02-04T08:00","2026-02-04T09:00","2026-02-04T10:00","2026-02-04T11:00","2026-02-04T12:00","2026-02-04T13:00","2026-02-04T14:00","2026-02-04T15:00","2026-02-04T16:00","2026-02-04T17:00","2026-02-04T18:00","2026-02-04T19:00","2026-02-04T20:00","2026-02-04T21:00","2026-02-04T22:00","2026-02-04T23:00","2026-02-05T00:00","2026-02-05T01:00","2026-02-05T02:00","2026-02-05T03:00","2026-02-05T04:00","2026-02-05T05:00","2026-02-05T06:00","2026-02-05T07:00","2026-02-05T08:00","2026-02-05T09:00","2026-02-05T10:00","2026-02-05T11:00","2026-02-05T12:00","2026-02-05T13:00","2026-02-05T14:00","2026-02-05T15:00","2026-02-05T16:00","2026-02-05T17:00","2026-02-05T18:00","2026-02-05T19:00","2026-02-05T20:00","2026-02-05T21:00","2026-02-05T22:00","2026-02-05T23:00","2026-02-06T00:00","2026-02-06T01:00","2026-02-06T02:00","2026-02-06T03:00","2026-02-06T04:00","2026-02-06T05:00","2026-02-06T06:00","2026-02-06T07:00","2026-02-06T08:00","2026-02-06T09:00","2026-02-06T10:00","2026-02-06T11:00","2026-02-06T12:00","2026-02-06T13:00","2026-02-06T14:00","2026-02-06T15:00","2026-02-06T16:00","2026-02-06T17:00","2026-02-06T18:00","2026-02-06T19:00","2026-02-06T20:00","2026-02-06T21:00","2026-02-06T22:00","2026-02-06T23:00"],"weather_code":[3,3,3,3,3,3,3,3,61,61,61,63,61,61,61,3,3,3,61,61,61,61,61,3,61,61,3,3,3,3,3,3,2,2,2,2,2,2,2,2,3,3,2,3,2,3,3,3,3,3,3,3,3,3,3,45,2,2,3,3,3,3,3,3,61,61,3,2,3,3,3,3,3,3,3,3,80,61,61,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,3,3,3,3,3,3,61,61,61,61,61,61,3,3,3,3,3,3,2,2,2,3,3,3,3,3,3,61,61,61,63,63,63,95,95,95,95,95,95,80,80,80,3,3,3,80,80,80,80,80,80,95,95,95,80,80,80,1,1],"temperature_2m":[3.6,3.5,3.3,2.6,2.8,3.4,4.6,5.1,4.9,4.5,4.4,4.0,4.9,5.4,5.7,5.8,5.4,4.7,4.3,4.2,4.3,4.5,4.6,4.5,4.3,4.2,3.9,3.7,3.6,3.6,3.5,3.6,4.1,4.6,5.3,6.0,6.6,6.8,6.5,6.0,5.0,4.1,3.7,3.5,3.4,3.6,3.5,3.4,3.2,2.9,2.9,3.2,3.5,3.9,4.2,4.0,4.9,6.7,7.9,8.3,8.8,9.0,9.0,8.8,8.3,7.9,8.0,8.0,8.1,8.2,8.2,8.5,8.7,8.7,8.2,8.2,7.6,7.0,6.5,6.0,6.4,6.7,7.1,7.7,7.8,7.7,7.5,7.2,6.8,6.4,5.9,5.5,5.1,4.8,4.7,4.6,4.5,4.3,4.2,4.0,3.8,3.6,3.7,4.2,5.0,5.7,6.4,7.1,7.4,7.3,6.9,6.4,5.8,5.1,4.5,4.3,4.2,4.2,4.1,4.0,4.1,4.5,5.1,5.4,5.8,6.1,6.6,7.6,8.3,9.0,9.7,10.4,10.8,11.0,10.9,10.7,10.3,9.8,9.6,9.9,10.4,11.0,11.6,12.2,12.5,12.4,12.1,11.7,11.2,10.7,10.4,10.5,10.8,11.1,11.5,12.0,12.2,12.1,11.7,11.3,10.9,10.3,9.9,9.6,9.4,9.3,9.1,9.1],"wind_speed_10m":[2.9,0.0,3.3,6.2,7.6,8.6,10.9,11.9,12.4,11.2,8.7,7.8,6.9,5.0,3.4,5.7,5.4,6.8,8.7,9.0,9.4,10.7,11.0,9.9,9.6,8.8,7.8,8.0,8.7,9.8,9.6,8.2,8.9,11.1,12.5,17.8,21.6,21.7,21.4,20.7,17.6,11.1,10.0,9.4,8.9,8.1,6.8,5.1,2.1,1.1,0.7,3.4,1.1,1.5,3.7,3.5,5.2,5.0,7.2,8.3,8.4,7.1,7.9,6.5,7.6,7.8,9.3,9.4,9.7,10.9,10.5,11.8,10.5,8.7,7.0,7.5,10.7,9.7,3.3,4.5,6.0,8.3,11.5,16.1,16.0,14.5,11.5,8.1,4.9,2.2,2.7,3.7,4.4,4.5,4.6,4.3,4.0,3.4,2.5,2.3,2.5,2.9,3.3,3.3,3.7,4.6,7.0,9.9,11.9,13.0,13.3,12.0,7.8,2.5,3.1,4.1,4.5,4.7,4.8,5.5,5.5,2.6,1.6,4.4,3.6,2.4,2.9,2.4,2.7,2.9,5.0,8.4,10.4,9.9,8.2,7.0,7.3,9.7,11.8,12.3,11.7,10.9,14.9,24.9,32.9,33.8,30.6,27.9,26.1,24.3,23.3,22.7,23.0,23.1,23.1,23.1,23.0,22.1,20.8,20.0,19.9,19.8,19.4,18.8,18.3,17.0,14.0,10.2],"wind_speed_180m":[14.8,10.5,4.8,4.3,11.8,16.1,23.4,24.9,26.5,22.7,18.6,18.9,17.9,12.4,11.7,18.2,21.1,18.1,20.1,20.5,23.0,25.9,25.7,22.1,21.6,19.1,17.3,17.9,19.5,23.2,21.3,20.0,20.5,22.6,23.8,30.6,39.5,39.1,39.4,39.1,34.4,25.8,23.5,22.2,22.6,21.7,17.8,14.6,10.2,9.5,8.3,11.0,11.7,11.8,13.8,7.9,7.6,7.6,9.4,11.2,12.4,9.8,11.9,11.0,13.5,15.3,18.9,18.6,20.4,22.7,22.6,25.6,22.1,19.0,20.6,23.7,25.2,21.3,8.3,13.2,14.8,18.0,25.6,32.0,31.1,27.8,21.4,15.3,10.2,6.3,4.0,3.8,4.5,5.1,5.8,6.5,6.6,5.4,4.3,3.8,4.1,5.7,6.9,7.0,6.6,6.7,9.4,14.0,17.9,19.9,20.5,19.4,15.6,10.2,7.4,8.4,10.3,10.9,9.4,6.8,4.6,6.0,14.3,19.5,15.6,9.8,6.6,7.2,5.0,4.4,7.4,12.0,15.0,15.0,14.1,12.9,14.5,20.6,24.5,24.2,23.8,25.6,35.6,55.0,70.0,72.7,68.9,64.4,61.8,58.8,55.8,53.3,51.0,48.8,46.9,45.1,43.6,42.9,42.3,42.7,44.3,46.6,47.7,47.5,47.1,45.4,39.4,32.0],"visibility":[10140.00,8560.00,10340.00,10440.00,31700.00,59540.00,72020.00,73620.00,16040.00,25060.00,7260.00,9440.00,38820.00,45160.00,45200.00,45100.00,44560.00,32140.00,30300.00,30340.00,25100.00,21480.00,21900.00,24440.00,25760.00,26040.00,22920.00,21020.00,16160.00,18780.00,18720.00,13380.00,14960.00,19260.00,27360.00,38640.00,51760.00,48940.00,44160.00,43960.00,33500.00,15940.00,13920.00,14720.00,12380.00,12780.00,10900.00,11540.00,9280.00,6980.00,9040.00,11760.00,10960.00,8860.00,4980.00,3500.00,5520.00,28720.00,43500.00,37280.00,31000.00,27840.00,24280.00,22760.00,17140.00,16960.00,18880.00,23940.00,32060.00,36540.00,41620.00,47640.00,52360.00,52260.00,40700.00,28760.00,5080.00,1960.00,2280.00,1520.00,8980.00,16280.00,11940.00,13240.00,13480.00,11920.00,10340.00,8780.00,8800.00,8820.00,8840.00,8720.00,8600.00,8480.00,11420.00,14360.00,17300.00,20560.00,23820.00,27080.00,21820.00,16540.00,11280.00,14280.00,17280.00,20280.00,26780.00,33280.00,39780.00,37500.00,35240.00,32960.00,24400.00,15840.00,7280.00,8300.00,9340.00,10360.00,11060.00,11740.00,12440.00,9780.00,7140.00,4480.00,4865.00,4570.00,3885.00,1240.00,680.00,120.00,100.00,60.00,40.00,220.00,380.00,560.00,800.00,1040.00,1280.00,880.00,480.00,80.00,60.00,60.00,40.00,40.00,40.00,40.00,1180.00,2300.00,3440.00,2320.00,1200.00,80.00,80.00,80.00,80.00,700.00,1340.00,1960.00,1780.00,1600.00,1420.00,9000.00,16560.00,24140.00,24140.00,24140.00],"cloud_cover":[100,94,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,93,100,100,100,90,79,72,58,62,70,70,80,85,100,100,90,81,85,92,90,100,97,92,100,99,97,99,91,80,76,60,86,90,94,99,99,100,100,98,90,80,99,100,100,100,100,100,100,100,100,100,100,100,100,100,90,88,92,92,92,92,94,96,98,99,99,100,100,100,100,100,100,100,100,100,100,100,100,100,90,81,71,81,90,100,100,100,100,100,100,100,100,100,100,99,97,96,96,96,96,85,81,78,84,91,97,98,99,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,94,87,81,87,92,98,99,99,100,99,98,97,78,59]}}'; MeteoJSON:=fpJSON.GetJSON(meteotext); OggettoJSON := MeteoJSON as TJSONObject; //questo è stato fatto per rendere i dati meglio estraibili copertura:= floattostr(round(OggettoJSON.FindPath('hourly.cloud_cover['+orameteo+']').AsFloat))+'%'; temperatura:= floattostr(round(OggettoJSON.FindPath('hourly.temperature_2m['+orameteo+']').AsFloat))+'°'; ventobasso:= floattostr(round(OggettoJSON.FindPath('hourly.wind_speed_10m['+orameteo+']').AsFloat)); ventoalto:= floattostr(round(OggettoJSON.FindPath('hourly.wind_speed_180m['+orameteo+']').AsFloat))+'km/h'; visibilita:= floattostr(round(OggettoJSON.FindPath('hourly.visibility['+orameteo+']').AsFloat/1000))+'km'; precipitazione:= meteoutil.calcolaprecipitazione(OggettoJSON, strtoint(orameteo)); end; CondizioniMeteoLabel.Caption:=precipitazione+' '+ temperatura; CoperturaLabel.Caption:= copertura; VentoBassoLabel.Caption:= ventobasso+'-'+ventoalto; VisibilitaLabel.Caption:=visibilita; // TODO: cercare di togliere la maggiorparte delle cose dal try questo migliora la velocità del codice try RisorseStream:= TResourceStream.Create(HInstance,inttostr(yearof(giornometeo))+'_NASA', RT_RCDATA); nasastringlist:=TStringList.Create; SetLength(nasalinea, RisorseStream.Size); RisorseStream.Read(nasalinea[1], RisorseStream.Size);; nasastringlist.AddDelimitedText(nasalinea, #10, True); Evento1Label.Caption:=''; Evento2Label.Caption:=''; Evento3Label.Caption:=''; //resetta i campi per gli eventi // Open the file for reading segnaposto:=0; for elementi in nasastringlist do begin if elementi='' then break; if EncodeDate(yearof(giornometeo), strtoint(copy(elementi, 1,2)), strtoint(copy(elementi,5,2))) >= giornometeo then begin case segnaposto of 0: Evento1Label.Caption:=meteoutil.FormattaAstroLinea(elementi); 1: Evento2Label.Caption:=meteoutil.FormattaAstroLinea(elementi); 2: begin Evento3Label.Caption:=meteoutil.FormattaAstroLinea(elementi); break; end; end; segnaposto:=segnaposto+1; end; end; except on E:EResNotFound do begin Evento1Label.Caption:='Dati Non disponibili'; Evento2Label.Caption:=''; Evento3Label.Caption:=''; end; end; end; procedure TMeteoView.FrameResize(Sender: TObject); begin // if Panel1.Parent.Width> 850 then Panel1.Width:=(Panel1.Parent.Width div 10)*8 //else Panel1.Width:=Panel1.Parent.Width; end; procedure TMeteoView.SpeedButton1Click(Sender: TObject); begin graficimeteo.Form3.meteotext:=meteotext; //passo la variabile del frame meteotext al form. La variabile si chiama anche nel form meteotext graficimeteo.Form3.meteoposgiorno:=posgiornometeo; //passo la variabile posizione del giorno anche stavolta al form graficimeteo.Form3.Show; end; end.