diff options
Diffstat (limited to 'waterspout_radar/_radar.py')
-rw-r--r-- | waterspout_radar/_radar.py | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/waterspout_radar/_radar.py b/waterspout_radar/_radar.py new file mode 100644 index 0000000..629ec55 --- /dev/null +++ b/waterspout_radar/_radar.py @@ -0,0 +1,52 @@ +import dataclasses +import datetime +import typing + +import szilagyi +from geopy import geocoders +from metpy import calc +from metpy import units as metunits +from windy import point_forecast, Windy + +_L = point_forecast.Level + + +@dataclasses.dataclass +class Prediction: + time: datetime.datetime + swi: float + + +def calculate(config) -> typing.List[Prediction]: + units = metunits.units + windy = Windy(units) + + def _calculate(latitude, longitude): + forecasts = windy.point_forecast( + config.key, + latitude, longitude, + point_forecast.Model.ICONEU, + ("temp", "dewpoint", "wind", "pressure"), + tuple(_L)) + for cast in forecasts: + dt = abs(cast.at("temp", _L.H850) - cast.at("temp", _L.SURFACE)) + pressure, _ = calc.lcl( + cast.at("pressure", _L.SURFACE), + cast.at("temp", _L.SURFACE), + cast.at("dewpoint", _L.SURFACE)) + lcl = calc.pressure_to_height_std(pressure) + pressure, _ = calc.el(cast["pressure"], cast["temp"], cast["dewpoint"]) + el = calc.pressure_to_height_std(pressure) + ccd = (el - lcl).to(units.ft) + try: + swi = szilagyi.calculate_swi(dt, ccd) + except ValueError: + swi = -10 + yield Prediction(time=cast.timestamp, swi=swi) + + predictions = [] + locator = geocoders.Nominatim(user_agent="waterspout-radar") + for location in config.locations: + found = locator.geocode(location) + predictions.extend(_calculate(found.latitude, found.longitude)) + return predictions |