Current section
Files
Jump to
Current section
Files
src/sunny@api@forecast.erl
-module(sunny@api@forecast).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([params/1, set_temperature_unit/2, set_wind_speed_unit/2, set_precipitation_unit/2, set_cell_selection/2, set_timezone/2, set_forecast_days/2, set_past_days/2, set_forecast_hours/2, set_forecast_minutely_15/2, set_past_hours/2, set_past_minutely_15/2, set_start_date/2, set_end_date/2, set_start_hour/2, set_end_hour/2, set_start_minutely_15/2, set_end_minutely_15/2, set_hourly/2, set_daily/2, set_minutely/2, set_current/2, set_all_hourly/2, set_all_daily/2, set_all_minutely/2, set_all_current/2, get_request/2, get_result/1]).
-export_type([temperature_unit/0, wind_speed_unit/0, precipitation_unit/0, cell_selection/0, forecast_result/0, forecast_params/0]).
-type temperature_unit() :: celsius | fahrenheit.
-type wind_speed_unit() :: kilometers_per_hour |
meters_per_second |
miles_per_hour |
knots.
-type precipitation_unit() :: millimeters | inches.
-type cell_selection() :: land | sea | nearest.
-type forecast_result() :: {forecast_result,
sunny@position:position(),
float(),
integer(),
binary(),
binary(),
sunny@api@forecast@data:time_ranged_data(sunny@api@forecast@instant:instant_variable()),
sunny@api@forecast@data:time_ranged_data(sunny@api@forecast@daily:daily_variable()),
sunny@api@forecast@data:time_ranged_data(sunny@api@forecast@instant:instant_variable()),
gleam@option:option(sunny@api@forecast@data:current_data(sunny@api@forecast@instant:instant_variable()))}.
-type forecast_params() :: {forecast_params,
sunny@position:position(),
list(sunny@api@forecast@instant:instant_variable()),
list(sunny@api@forecast@daily:daily_variable()),
list(sunny@api@forecast@instant:instant_variable()),
list(sunny@api@forecast@instant:instant_variable()),
temperature_unit(),
wind_speed_unit(),
precipitation_unit(),
binary(),
integer(),
integer(),
gleam@option:option(integer()),
gleam@option:option(integer()),
gleam@option:option(integer()),
gleam@option:option(integer()),
gleam@option:option(birl:time()),
gleam@option:option(birl:time()),
gleam@option:option(birl:time()),
gleam@option:option(birl:time()),
gleam@option:option(birl:time()),
gleam@option:option(birl:time()),
cell_selection()}.
-spec temp_unit_to_string(temperature_unit()) -> binary().
temp_unit_to_string(U) ->
case U of
celsius ->
<<"celsius"/utf8>>;
fahrenheit ->
<<"fahrenheit"/utf8>>
end.
-spec wind_unit_to_string(wind_speed_unit()) -> binary().
wind_unit_to_string(U) ->
case U of
kilometers_per_hour ->
<<"kmh"/utf8>>;
meters_per_second ->
<<"ms"/utf8>>;
miles_per_hour ->
<<"mph"/utf8>>;
knots ->
<<"kn"/utf8>>
end.
-spec precipitation_unit_to_string(precipitation_unit()) -> binary().
precipitation_unit_to_string(U) ->
case U of
millimeters ->
<<"mm"/utf8>>;
inches ->
<<"inch"/utf8>>
end.
-spec cell_select_to_string(cell_selection()) -> binary().
cell_select_to_string(C) ->
case C of
land ->
<<"land"/utf8>>;
sea ->
<<"sea"/utf8>>;
nearest ->
<<"nearest"/utf8>>
end.
-spec params(sunny@position:position()) -> forecast_params().
params(Position) ->
{forecast_params,
Position,
[],
[],
[],
[],
celsius,
kilometers_per_hour,
millimeters,
<<"GMT"/utf8>>,
0,
7,
none,
none,
none,
none,
none,
none,
none,
none,
none,
none,
land}.
-spec set_temperature_unit(forecast_params(), temperature_unit()) -> forecast_params().
set_temperature_unit(Params, Unit) ->
erlang:setelement(7, Params, Unit).
-spec set_wind_speed_unit(forecast_params(), wind_speed_unit()) -> forecast_params().
set_wind_speed_unit(Params, Unit) ->
erlang:setelement(8, Params, Unit).
-spec set_precipitation_unit(forecast_params(), precipitation_unit()) -> forecast_params().
set_precipitation_unit(Params, Unit) ->
erlang:setelement(9, Params, Unit).
-spec set_cell_selection(forecast_params(), cell_selection()) -> forecast_params().
set_cell_selection(Params, Cell_selection) ->
erlang:setelement(23, Params, Cell_selection).
-spec set_timezone(forecast_params(), binary()) -> forecast_params().
set_timezone(Params, Timezone) ->
erlang:setelement(10, Params, Timezone).
-spec set_forecast_days(forecast_params(), integer()) -> forecast_params().
set_forecast_days(Params, Forecast_days) ->
erlang:setelement(12, Params, gleam@int:clamp(Forecast_days, 0, 16)).
-spec set_past_days(forecast_params(), integer()) -> forecast_params().
set_past_days(Params, Past_days) ->
erlang:setelement(11, Params, gleam@int:clamp(Past_days, 0, 95)).
-spec set_forecast_hours(forecast_params(), integer()) -> forecast_params().
set_forecast_hours(Params, Forecast_hours) ->
case Forecast_hours of
_ when Forecast_hours =< 0 ->
erlang:setelement(13, Params, none);
_ ->
erlang:setelement(13, Params, {some, Forecast_hours})
end.
-spec set_forecast_minutely_15(forecast_params(), integer()) -> forecast_params().
set_forecast_minutely_15(Params, Forecast_minutely_15) ->
case Forecast_minutely_15 of
_ when Forecast_minutely_15 =< 0 ->
erlang:setelement(14, Params, none);
_ ->
erlang:setelement(14, Params, {some, Forecast_minutely_15})
end.
-spec set_past_hours(forecast_params(), integer()) -> forecast_params().
set_past_hours(Params, Past_hours) ->
case Past_hours of
_ when Past_hours =< 0 ->
erlang:setelement(15, Params, none);
_ ->
erlang:setelement(15, Params, {some, Past_hours})
end.
-spec set_past_minutely_15(forecast_params(), integer()) -> forecast_params().
set_past_minutely_15(Params, Past_minutely_15) ->
case Past_minutely_15 of
_ when Past_minutely_15 =< 0 ->
erlang:setelement(16, Params, none);
_ ->
erlang:setelement(16, Params, {some, Past_minutely_15})
end.
-spec set_start_date(forecast_params(), birl:time()) -> forecast_params().
set_start_date(Params, Start_date) ->
erlang:setelement(17, Params, {some, Start_date}).
-spec set_end_date(forecast_params(), birl:time()) -> forecast_params().
set_end_date(Params, End_date) ->
erlang:setelement(18, Params, {some, End_date}).
-spec set_start_hour(forecast_params(), birl:time()) -> forecast_params().
set_start_hour(Params, Start_hour) ->
erlang:setelement(19, Params, {some, Start_hour}).
-spec set_end_hour(forecast_params(), birl:time()) -> forecast_params().
set_end_hour(Params, End_hour) ->
erlang:setelement(20, Params, {some, End_hour}).
-spec set_start_minutely_15(forecast_params(), birl:time()) -> forecast_params().
set_start_minutely_15(Params, Start_minutely_15) ->
erlang:setelement(21, Params, {some, Start_minutely_15}).
-spec set_end_minutely_15(forecast_params(), birl:time()) -> forecast_params().
set_end_minutely_15(Params, End_minutely_15) ->
erlang:setelement(22, Params, {some, End_minutely_15}).
-spec set_hourly(
forecast_params(),
list(sunny@api@forecast@instant:instant_variable())
) -> forecast_params().
set_hourly(Params, Hourly_list) ->
erlang:setelement(3, Params, Hourly_list).
-spec set_daily(
forecast_params(),
list(sunny@api@forecast@daily:daily_variable())
) -> forecast_params().
set_daily(Params, Daily_list) ->
erlang:setelement(4, Params, Daily_list).
-spec set_minutely(
forecast_params(),
list(sunny@api@forecast@instant:instant_variable())
) -> forecast_params().
set_minutely(Params, Minutely_list) ->
erlang:setelement(5, Params, Minutely_list).
-spec set_current(
forecast_params(),
list(sunny@api@forecast@instant:instant_variable())
) -> forecast_params().
set_current(Params, Current_list) ->
erlang:setelement(6, Params, Current_list).
-spec set_all(
forecast_params(),
list(KOV),
list(KOV),
fun((forecast_params(), list(KOV)) -> forecast_params())
) -> forecast_params().
set_all(Params, Except, All, Set_fn) ->
case Except of
[] ->
_pipe = Params,
Set_fn(_pipe, All);
[_ | _] ->
_pipe@1 = Params,
Set_fn(
_pipe@1,
gleam@list:filter(
All,
fun(X) -> gleam@list:contains(Except, X) end
)
)
end.
-spec set_all_hourly(
forecast_params(),
list(sunny@api@forecast@instant:instant_variable())
) -> forecast_params().
set_all_hourly(Params, Except) ->
set_all(
Params,
Except,
[temperature2m,
temperature80m,
temperature120m,
temperature180m,
relative_humidity2m,
dew_point2m,
apparent_temperature,
pressure_msl,
surface_pressure,
cloud_cover,
cloud_cover_low,
cloud_cover_mid,
cloud_cover_high,
wind_speed10m,
wind_speed80m,
wind_speed120m,
wind_speed180m,
wind_direction10m,
wind_direction80m,
wind_direction120m,
wind_direction180m,
wind_gusts10m,
precipitation,
snowfall,
precipitation_probability,
rain,
showers,
weather_code,
snow_depth,
freezing_level_height,
visibility,
is_day],
fun set_hourly/2
).
-spec set_all_daily(
forecast_params(),
list(sunny@api@forecast@daily:daily_variable())
) -> forecast_params().
set_all_daily(Params, Except) ->
set_all(
Params,
Except,
[maximum_temperature2m,
minimum_temperature2m,
apparent_temperature_max,
apparent_temperature_min,
precipitation_sum,
rain_sum,
showers_sum,
snowfall_sum,
precipitation_hours,
precipitation_probability_max,
precipitation_probability_min,
precipitation_probability_mean,
worst_weather_code,
sunshine_suration,
daylight_duration,
wind_speed10m_max,
wind_gusts10m_max,
wind_direction10m_dominant],
fun set_daily/2
).
-spec set_all_minutely(
forecast_params(),
list(sunny@api@forecast@instant:instant_variable())
) -> forecast_params().
set_all_minutely(Params, Except) ->
set_all(
Params,
Except,
[temperature2m,
temperature80m,
temperature120m,
temperature180m,
relative_humidity2m,
dew_point2m,
apparent_temperature,
pressure_msl,
surface_pressure,
cloud_cover,
cloud_cover_low,
cloud_cover_mid,
cloud_cover_high,
wind_speed10m,
wind_speed80m,
wind_speed120m,
wind_speed180m,
wind_direction10m,
wind_direction80m,
wind_direction120m,
wind_direction180m,
wind_gusts10m,
precipitation,
snowfall,
precipitation_probability,
rain,
showers,
weather_code,
snow_depth,
freezing_level_height,
visibility,
is_day],
fun set_minutely/2
).
-spec set_all_current(
forecast_params(),
list(sunny@api@forecast@instant:instant_variable())
) -> forecast_params().
set_all_current(Params, Except) ->
set_all(
Params,
Except,
[temperature2m,
temperature80m,
temperature120m,
temperature180m,
relative_humidity2m,
dew_point2m,
apparent_temperature,
pressure_msl,
surface_pressure,
cloud_cover,
cloud_cover_low,
cloud_cover_mid,
cloud_cover_high,
wind_speed10m,
wind_speed80m,
wind_speed120m,
wind_speed180m,
wind_direction10m,
wind_direction80m,
wind_direction120m,
wind_direction180m,
wind_gusts10m,
precipitation,
snowfall,
precipitation_probability,
rain,
showers,
weather_code,
snow_depth,
freezing_level_height,
visibility,
is_day],
fun set_current/2
).
-spec set_if_some(
forecast_params(),
gleam@option:option(KPC),
fun((forecast_params(), KPC) -> forecast_params())
) -> forecast_params().
set_if_some(Params, Opt, Func) ->
case Opt of
{some, X} ->
Func(Params, X);
none ->
Params
end.
-spec verify_params(forecast_params()) -> forecast_params().
verify_params(Params) ->
_pipe = erlang:setelement(
6,
erlang:setelement(
5,
erlang:setelement(
4,
erlang:setelement(
3,
Params,
gleam@list:unique(erlang:element(3, Params))
),
gleam@list:unique(erlang:element(4, Params))
),
gleam@list:unique(erlang:element(5, Params))
),
gleam@list:unique(erlang:element(6, Params))
),
_pipe@1 = set_past_days(_pipe, erlang:element(11, Params)),
_pipe@2 = set_forecast_days(_pipe@1, erlang:element(12, Params)),
_pipe@3 = set_if_some(
_pipe@2,
erlang:element(13, Params),
fun set_forecast_hours/2
),
_pipe@4 = set_if_some(
_pipe@3,
erlang:element(14, Params),
fun set_forecast_minutely_15/2
),
_pipe@5 = set_if_some(
_pipe@4,
erlang:element(15, Params),
fun set_past_hours/2
),
set_if_some(_pipe@5, erlang:element(16, Params), fun set_past_minutely_15/2).
-spec option_to_param_list(
gleam@option:option(KPF),
binary(),
fun((KPF) -> binary())
) -> list(sunny@internal@utils:request_parameter()).
option_to_param_list(Opt, Opt_string, To_string_fn) ->
case Opt of
{some, X} ->
[{request_parameter,
Opt_string,
begin
_pipe = X,
To_string_fn(_pipe)
end}];
none ->
[]
end.
-spec list_to_param_list(list(KPI), binary(), fun((KPI) -> binary())) -> list(sunny@internal@utils:request_parameter()).
list_to_param_list(L, L_string, To_string_fn) ->
case L of
[_ | _] ->
[begin
_pipe = L,
_pipe@1 = sunny@internal@utils:param_list_to_string(
_pipe,
To_string_fn
),
{request_parameter, L_string, _pipe@1}
end];
[] ->
[]
end.
-spec forecast_params_to_params_list(forecast_params()) -> list(sunny@internal@utils:request_parameter()).
forecast_params_to_params_list(Params) ->
_pipe = option_to_param_list(
erlang:element(13, Params),
<<"forecast_hours"/utf8>>,
fun gleam@int:to_string/1
),
_pipe@1 = lists:append(
_pipe,
list_to_param_list(
erlang:element(3, Params),
<<"hourly"/utf8>>,
fun sunny@internal@api@forecast:instant_to_string/1
)
),
_pipe@2 = lists:append(
_pipe@1,
list_to_param_list(
erlang:element(4, Params),
<<"daily"/utf8>>,
fun sunny@internal@api@forecast:daily_to_string/1
)
),
_pipe@3 = lists:append(
_pipe@2,
list_to_param_list(
erlang:element(5, Params),
<<"minutely_15"/utf8>>,
fun sunny@internal@api@forecast:instant_to_string/1
)
),
_pipe@4 = lists:append(
_pipe@3,
list_to_param_list(
erlang:element(6, Params),
<<"current"/utf8>>,
fun sunny@internal@api@forecast:instant_to_string/1
)
),
_pipe@5 = lists:append(
_pipe@4,
option_to_param_list(
erlang:element(14, Params),
<<"forecast_minutely_15"/utf8>>,
fun gleam@int:to_string/1
)
),
_pipe@6 = lists:append(
_pipe@5,
option_to_param_list(
erlang:element(15, Params),
<<"past_hours"/utf8>>,
fun gleam@int:to_string/1
)
),
_pipe@7 = lists:append(
_pipe@6,
option_to_param_list(
erlang:element(16, Params),
<<"past_minutely_15"/utf8>>,
fun gleam@int:to_string/1
)
),
_pipe@8 = lists:append(
_pipe@7,
option_to_param_list(
erlang:element(17, Params),
<<"start_date"/utf8>>,
fun birl:to_naive_date_string/1
)
),
_pipe@9 = lists:append(
_pipe@8,
option_to_param_list(
erlang:element(18, Params),
<<"end_date"/utf8>>,
fun birl:to_naive_date_string/1
)
),
_pipe@10 = lists:append(
_pipe@9,
option_to_param_list(
erlang:element(19, Params),
<<"start_hour"/utf8>>,
fun birl:to_naive_time_string/1
)
),
_pipe@11 = lists:append(
_pipe@10,
option_to_param_list(
erlang:element(20, Params),
<<"end_hour"/utf8>>,
fun birl:to_naive_date_string/1
)
),
_pipe@12 = lists:append(
_pipe@11,
option_to_param_list(
erlang:element(21, Params),
<<"start_minutely_15"/utf8>>,
fun birl:to_naive_date_string/1
)
),
_pipe@13 = lists:append(
_pipe@12,
option_to_param_list(
erlang:element(22, Params),
<<"end_minutely_15"/utf8>>,
fun birl:to_naive_date_string/1
)
),
lists:append(
_pipe@13,
[{request_parameter,
<<"latitude"/utf8>>,
begin
_pipe@14 = erlang:element(2, erlang:element(2, Params)),
gleam@float:to_string(_pipe@14)
end},
{request_parameter,
<<"longitude"/utf8>>,
begin
_pipe@15 = erlang:element(3, erlang:element(2, Params)),
gleam@float:to_string(_pipe@15)
end},
{request_parameter,
<<"temperature_unit"/utf8>>,
begin
_pipe@16 = erlang:element(7, Params),
temp_unit_to_string(_pipe@16)
end},
{request_parameter,
<<"wind_speed_unit"/utf8>>,
begin
_pipe@17 = erlang:element(8, Params),
wind_unit_to_string(_pipe@17)
end},
{request_parameter,
<<"precipitation_unit"/utf8>>,
begin
_pipe@18 = erlang:element(9, Params),
precipitation_unit_to_string(_pipe@18)
end},
{request_parameter, <<"timezone"/utf8>>, erlang:element(10, Params)},
{request_parameter,
<<"past_days"/utf8>>,
begin
_pipe@19 = erlang:element(11, Params),
gleam@int:to_string(_pipe@19)
end},
{request_parameter,
<<"forecast_days"/utf8>>,
begin
_pipe@20 = erlang:element(12, Params),
gleam@int:to_string(_pipe@20)
end},
{request_parameter,
<<"cell_selection"/utf8>>,
begin
_pipe@21 = erlang:element(23, Params),
cell_select_to_string(_pipe@21)
end}]
).
-spec get_request(sunny@internal@client:client(), forecast_params()) -> gleam@http@request:request(binary()).
get_request(Client, Params) ->
Params@1 = verify_params(Params),
_pipe@1 = sunny@internal@utils:get_final_url(
erlang:element(2, Client),
<<""/utf8>>,
erlang:element(3, Client),
<<"/forecast"/utf8>>,
erlang:element(4, Client),
begin
_pipe = Params@1,
forecast_params_to_params_list(_pipe)
end
),
sunny@internal@utils:get_request(_pipe@1).
-spec refine_raw_result(sunny@internal@api@forecast:raw_forecast_result()) -> {ok,
forecast_result()} |
{error, sunny@errors:internal_error()}.
refine_raw_result(Raw) ->
gleam@result:'try'(
sunny@internal@api@forecast:refine_raw_time_ranged_data(
erlang:element(8, Raw),
erlang:element(9, Raw),
fun sunny@internal@api@forecast:string_to_instant/1
),
fun(Hourly) ->
gleam@result:'try'(
sunny@internal@api@forecast:refine_raw_time_ranged_data(
erlang:element(10, Raw),
erlang:element(11, Raw),
fun sunny@internal@api@forecast:string_to_daily/1
),
fun(Daily) ->
gleam@result:'try'(
sunny@internal@api@forecast:refine_raw_time_ranged_data(
erlang:element(12, Raw),
erlang:element(13, Raw),
fun sunny@internal@api@forecast:string_to_instant/1
),
fun(Minutely) ->
gleam@result:'try'(
sunny@internal@api@forecast:refine_raw_current_data(
erlang:element(14, Raw),
erlang:element(15, Raw),
fun sunny@internal@api@forecast:string_to_instant/1
),
fun(Current) ->
{ok,
{forecast_result,
{position,
erlang:element(2, Raw),
erlang:element(3, Raw)},
erlang:element(4, Raw),
erlang:element(5, Raw),
erlang:element(6, Raw),
erlang:element(7, Raw),
Hourly,
Daily,
Minutely,
Current}}
end
)
end
)
end
)
end
).
-spec get_result(binary()) -> {ok, forecast_result()} |
{error, sunny@errors:sunny_error()}.
get_result(Response_body) ->
gleam@result:'try'(
sunny@internal@api@forecast:raw_forecast_result_from_json(Response_body),
fun(Raw_result) -> _pipe = Raw_result,
_pipe@1 = refine_raw_result(_pipe),
gleam@result:map_error(
_pipe@1,
fun(E) -> {sunny_internal_error, E} end
) end
).