Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ASA - Critical Hours Frontend #3909

Merged
merged 50 commits into from
Sep 10, 2024
Merged
Show file tree
Hide file tree
Changes from 49 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
bfebb1e
initial work
brettedw Aug 27, 2024
95d79c9
box colour
brettedw Aug 27, 2024
b2903c9
adds tooltip
brettedw Aug 27, 2024
7dad4f5
tooltip key
brettedw Aug 27, 2024
95aa1eb
select first zone on load
brettedw Aug 27, 2024
9ad5482
styled fuel headers
brettedw Aug 27, 2024
af3ed51
fuel bar tooltip
brettedw Aug 27, 2024
d3bd58d
thicker indicator
brettedw Aug 27, 2024
dcf9200
Remove elevation call
brettedw Aug 30, 2024
b62cca3
radio button console warning
brettedw Sep 3, 2024
b58555d
TPI centre endpoint & tab zooming
brettedw Sep 3, 2024
013343e
radio test fix
brettedw Sep 4, 2024
4c220d3
nullish op
brettedw Sep 4, 2024
abb3bba
Merge branch 'main' into task/asa-zone-unit-tabs
brettedw Sep 4, 2024
236f714
merge fix
brettedw Sep 4, 2024
38196e9
smells
brettedw Sep 4, 2024
568569b
hfiFuels fire centre endpoint & frontend
brettedw Sep 5, 2024
49205d2
custom hook?
brettedw Sep 5, 2024
1ae8828
commented code remove
brettedw Sep 5, 2024
7e95081
Merge branch 'main' into task/asa-zone-unit-tabs
brettedw Sep 5, 2024
d018738
hook name change
brettedw Sep 5, 2024
040b37f
Merge branch 'main' into task/asa-zone-unit-tabs
brettedw Sep 9, 2024
a121464
Merge branch 'main' into task/asa-zone-unit-tabs
brettedw Sep 9, 2024
9d963d0
memoize variables & data-testid's
brettedw Sep 9, 2024
b95d9a6
add tests
brettedw Sep 9, 2024
71f0ca6
comments
brettedw Sep 9, 2024
1e35698
js doc for custom hook
brettedw Sep 9, 2024
1945443
tab colour tests
brettedw Sep 9, 2024
9a00d95
new lines
brettedw Sep 9, 2024
7bda8aa
reorder details func
brettedw Sep 9, 2024
78badf1
consolidate zone status calculators
brettedw Sep 9, 2024
2033a75
Implement e2e
conbrad Sep 9, 2024
eb368d6
Merge branch 'task/asa-zone-unit-tabs' into task/critical-hours-front…
conbrad Sep 9, 2024
ac14911
Cleanup dead frontend code
conbrad Sep 9, 2024
7265891
make typescript happy
brettedw Sep 9, 2024
ba6275a
Endpoint tests
conbrad Sep 9, 2024
f0d73d3
Merge branch 'task/asa-zone-unit-tabs' into task/critical-hours-front…
conbrad Sep 9, 2024
b415831
Merge branch 'main' into task/critical-hours-frontend-3
conbrad Sep 9, 2024
a99d112
Remove unused selectors
conbrad Sep 10, 2024
96acbf7
Fix test mock
conbrad Sep 10, 2024
816504f
Cleanup logging and comments
conbrad Sep 10, 2024
dec76bf
Delete unused endpoint
conbrad Sep 10, 2024
3d99885
Merge branch 'main' into task/critical-hours-frontend-3
conbrad Sep 10, 2024
c8effa0
Add component test
conbrad Sep 10, 2024
b7f4ddd
Renaming
conbrad Sep 10, 2024
e9f1716
Remove tooltip
conbrad Sep 10, 2024
fb0294e
Fix merge regression
conbrad Sep 10, 2024
8484b9b
Handle no critical hours
conbrad Sep 10, 2024
6a2c057
Ran formatting with prettier
conbrad Sep 10, 2024
79e4d29
Adjust styling of fuel table to remove horizontal scroll
conbrad Sep 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
"HRDPS",
"idir",
"Indeterminates",
"Kamloops",
"luxon",
"maxx",
"maxy",
Expand All @@ -108,6 +109,7 @@
"PROJCS",
"pydantic",
"RDPS",
"reduxjs",
"reproject",
"rocketchat",
"rollup",
Expand All @@ -116,6 +118,7 @@
"sfms",
"sqlalchemy",
"starlette",
"testid",
"tobytes",
"upsampled",
"uvicorn",
Expand Down
23 changes: 15 additions & 8 deletions api/app/db/crud/auto_spatial_advisory.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ async def get_zone_ids_in_centre(session: AsyncSession, fire_centre_name: str):

return all_results


async def get_all_sfms_fuel_type_records(session: AsyncSession) -> List[SFMSFuelType]:
"""
Retrieve all records from the sfms_fuel_types table.
Expand All @@ -154,26 +154,33 @@ async def get_all_sfms_fuel_type_records(session: AsyncSession) -> List[SFMSFuel
return result.all()


async def get_precomputed_high_hfi_fuel_type_areas_for_shape(session: AsyncSession, run_type: RunTypeEnum, run_datetime: datetime, for_date: date, advisory_shape_id: int) -> List[Row]:
async def get_precomputed_stats_for_shape(session: AsyncSession, run_type: RunTypeEnum, run_datetime: datetime, for_date: date, advisory_shape_id: int) -> List[Row]:
perf_start = perf_counter()
stmt = (
select(AdvisoryFuelStats.advisory_shape_id, AdvisoryFuelStats.fuel_type, AdvisoryFuelStats.threshold, AdvisoryFuelStats.area, AdvisoryFuelStats.run_parameters)
.join_from(AdvisoryFuelStats, RunParameters, AdvisoryFuelStats.run_parameters == RunParameters.id)
.join_from(AdvisoryFuelStats, Shape, AdvisoryFuelStats.advisory_shape_id == Shape.id)
select(
CriticalHours.start_hour,
CriticalHours.end_hour,
AdvisoryFuelStats.fuel_type,
AdvisoryFuelStats.threshold,
AdvisoryFuelStats.area,
)
.distinct(AdvisoryFuelStats.fuel_type, AdvisoryFuelStats.run_parameters)
.outerjoin(RunParameters, AdvisoryFuelStats.run_parameters == RunParameters.id)
.outerjoin(CriticalHours, CriticalHours.run_parameters == RunParameters.id)
.outerjoin(Shape, AdvisoryFuelStats.advisory_shape_id == Shape.id)
.where(
Shape.source_identifier == str(advisory_shape_id),
RunParameters.run_type == run_type.value,
RunParameters.run_datetime == run_datetime,
RunParameters.for_date == for_date,
)
.order_by(AdvisoryFuelStats.fuel_type)
.order_by(AdvisoryFuelStats.threshold)
)

result = await session.execute(stmt)
all_results = result.all()
perf_end = perf_counter()
delta = perf_end - perf_start
logger.info("%f delta count before and after fuel types/high hfi/zone query", delta)
logger.info("%f delta count before and after advisory stats query", delta)
return all_results


Expand Down
73 changes: 9 additions & 64 deletions api/app/routers/fba.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,20 @@
get_all_sfms_fuel_types,
get_all_hfi_thresholds,
get_hfi_area,
get_precomputed_high_hfi_fuel_type_areas_for_shape,
get_precomputed_stats_for_shape,
get_provincial_rollup,
get_run_datetimes,
get_zonal_elevation_stats,
get_zonal_tpi_stats,
get_centre_tpi_stats,
get_zone_ids_in_centre,
)
from app.db.models.auto_spatial_advisory import RunTypeEnum
from app.schemas.fba import (
AdvisoryCriticalHours,
ClassifiedHfiThresholdFuelTypeArea,
FireCenterListResponse,
FireShapeAreaListResponse,
FireShapeArea,
FireZoneElevationStats,
FireZoneElevationStatsByThreshold,
FireZoneElevationStatsListResponse,
FireZoneTPIStats,
SFMSFuelType,
HfiThreshold,
Expand Down Expand Up @@ -105,50 +102,12 @@ async def get_provincial_summary(run_type: RunType, run_datetime: datetime, for_
return ProvincialSummaryResponse(provincial_summary=fire_shape_area_details)


@router.get("/hfi-fuels/{run_type}/{for_date}/{run_datetime}/{zone_id}", response_model=dict[int, List[ClassifiedHfiThresholdFuelTypeArea]])
async def get_hfi_fuels_data_for_fire_zone(run_type: RunType, for_date: date, run_datetime: datetime, zone_id: int):
"""
Fetch rollup of fuel type/HFI threshold/area data for a specified fire zone.
"""
logger.info("hfi-fuels/%s/%s/%s/%s", run_type.value, for_date, run_datetime, zone_id)

async with get_async_read_session_scope() as session:
# get thresholds data
thresholds = await get_all_hfi_thresholds(session)
# get fuel type ids data
fuel_types = await get_all_sfms_fuel_types(session)

# get HFI/fuels data for specific zone
hfi_fuel_type_ids_for_zone = await get_precomputed_high_hfi_fuel_type_areas_for_shape(
session, run_type=RunTypeEnum(run_type.value), for_date=for_date, run_datetime=run_datetime, advisory_shape_id=zone_id
)
data = []

for record in hfi_fuel_type_ids_for_zone:
fuel_type_id = record[1]
threshold_id = record[2]
# area is stored in square metres in DB. For user convenience, convert to hectares
# 1 ha = 10,000 sq.m.
area = record[3] / 10000
fuel_type_obj = next((ft for ft in fuel_types if ft.fuel_type_id == fuel_type_id), None)
threshold_obj = next((th for th in thresholds if th.id == threshold_id), None)
data.append(
ClassifiedHfiThresholdFuelTypeArea(
fuel_type=SFMSFuelType(fuel_type_id=fuel_type_obj.fuel_type_id, fuel_type_code=fuel_type_obj.fuel_type_code, description=fuel_type_obj.description),
threshold=HfiThreshold(id=threshold_obj.id, name=threshold_obj.name, description=threshold_obj.description),
area=area,
)
)

return {zone_id: data}


@router.get("/fire-centre-hfi-fuels/{run_type}/{for_date}/{run_datetime}/{fire_centre_name}", response_model=dict[str, dict[int, List[ClassifiedHfiThresholdFuelTypeArea]]])
@router.get("/fire-centre-hfi-stats/{run_type}/{for_date}/{run_datetime}/{fire_centre_name}", response_model=dict[str, dict[int, List[ClassifiedHfiThresholdFuelTypeArea]]])
async def get_hfi_fuels_data_for_fire_centre(run_type: RunType, for_date: date, run_datetime: datetime, fire_centre_name: str):
"""
Fetch rollup of fuel type/HFI threshold/area data for a specified fire zone.
Fetch fuel type and critical hours data for all fire zones in a fire centre for a given date
"""
logger.info("fire-centre-hfi-fuels/%s/%s/%s/%s", run_type.value, for_date, run_datetime, fire_centre_name)
logger.info("fire-centre-hfi-stats/%s/%s/%s/%s", run_type.value, for_date, run_datetime, fire_centre_name)

async with get_async_read_session_scope() as session:
# get thresholds data
Expand All @@ -161,23 +120,22 @@ async def get_hfi_fuels_data_for_fire_centre(run_type: RunType, for_date: date,
all_zone_data = {}
for zone_id in zone_ids:
dgboss marked this conversation as resolved.
Show resolved Hide resolved
# get HFI/fuels data for specific zone
hfi_fuel_type_ids_for_zone = await get_precomputed_high_hfi_fuel_type_areas_for_shape(
hfi_fuel_type_ids_for_zone = await get_precomputed_stats_for_shape(
session, run_type=RunTypeEnum(run_type.value), for_date=for_date, run_datetime=run_datetime, advisory_shape_id=zone_id
)
zone_data = []

for record in hfi_fuel_type_ids_for_zone:
fuel_type_id = record[1]
threshold_id = record[2]
for critical_hour_start, critical_hour_end, fuel_type_id, threshold_id, area in hfi_fuel_type_ids_for_zone:
# area is stored in square metres in DB. For user convenience, convert to hectares
# 1 ha = 10,000 sq.m.
area = record[3] / 10000
area = area / 10000
fuel_type_obj = next((ft for ft in fuel_types if ft.fuel_type_id == fuel_type_id), None)
threshold_obj = next((th for th in thresholds if th.id == threshold_id), None)
zone_data.append(
ClassifiedHfiThresholdFuelTypeArea(
fuel_type=SFMSFuelType(fuel_type_id=fuel_type_obj.fuel_type_id, fuel_type_code=fuel_type_obj.fuel_type_code, description=fuel_type_obj.description),
threshold=HfiThreshold(id=threshold_obj.id, name=threshold_obj.name, description=threshold_obj.description),
critical_hours=AdvisoryCriticalHours(start_time=critical_hour_start, end_time=critical_hour_end),
area=area,
)
)
Expand All @@ -201,19 +159,6 @@ async def get_run_datetimes_for_date_and_runtype(run_type: RunType, for_date: da
return datetimes


@router.get("/fire-zone-elevation-info/{run_type}/{for_date}/{run_datetime}/{fire_zone_id}", response_model=FireZoneElevationStatsListResponse)
async def get_fire_zone_elevation_stats(fire_zone_id: int, run_type: RunType, run_datetime: datetime, for_date: date, _=Depends(authentication_required)):
"""Return the elevation statistics for each advisory threshold"""
async with get_async_read_session_scope() as session:
data = []
rows = await get_zonal_elevation_stats(session, fire_zone_id, run_type, run_datetime, for_date)
for row in rows:
stats = FireZoneElevationStats(minimum=row.minimum, quartile_25=row.quartile_25, median=row.median, quartile_75=row.quartile_75, maximum=row.maximum)
stats_by_threshold = FireZoneElevationStatsByThreshold(threshold=row.threshold, elevation_info=stats)
data.append(stats_by_threshold)
return FireZoneElevationStatsListResponse(hfi_elevation_info=data)


@router.get("/fire-zone-tpi-stats/{run_type}/{for_date}/{run_datetime}/{fire_zone_id}", response_model=FireZoneTPIStats)
async def get_fire_zone_tpi_stats(fire_zone_id: int, run_type: RunType, run_datetime: datetime, for_date: date, _=Depends(authentication_required)):
"""Return the elevation TPI statistics for each advisory threshold"""
Expand Down
8 changes: 8 additions & 0 deletions api/app/schemas/fba.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,21 @@ class SFMSFuelType(BaseModel):
description: str


class AdvisoryCriticalHours(BaseModel):
"""Critical Hours for an advisory."""

start_time: Optional[float]
end_time: Optional[float]


class ClassifiedHfiThresholdFuelTypeArea(BaseModel):
"""Collection of data objects recording the area within an advisory shape
that meets a particular HfiThreshold for a specific SFMSFuelType
"""

fuel_type: SFMSFuelType
threshold: HfiThreshold
critical_hours: AdvisoryCriticalHours
area: float


Expand Down
62 changes: 31 additions & 31 deletions api/app/tests/fba/test_fba_endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,21 @@
from fastapi.testclient import TestClient
from datetime import date, datetime, timezone
from collections import namedtuple
from app.db.models.auto_spatial_advisory import AdvisoryElevationStats, AdvisoryTPIStats, RunParameters
from app.db.models.auto_spatial_advisory import AdvisoryTPIStats, HfiClassificationThreshold, RunParameters, SFMSFuelType

mock_fire_centre_name = "PGFireCentre"

get_fire_centres_url = "/api/fba/fire-centers"
get_fire_zone_areas_url = "/api/fba/fire-shape-areas/forecast/2022-09-27/2022-09-27"
get_fire_zone_tpi_stats_url = "/api/fba/fire-zone-tpi-stats/forecast/2022-09-27/2022-09-27/1"
get_fire_centre_info_url = "/api/fba/fire-centre-hfi-stats/forecast/2022-09-27/2022-09-27/Kamloops%20Fire%20Centre"
get_fire_zone_elevation_info_url = "/api/fba/fire-zone-elevation-info/forecast/2022-09-27/2022-09-27/1"
get_fire_centre_tpi_stats_url = f"/api/fba/fire-centre-tpi-stats/forecast/2024-08-10/2024-08-10/{mock_fire_centre_name}"
get_sfms_run_datetimes_url = "/api/fba/sfms-run-datetimes/forecast/2022-09-27"

decode_fn = "jwt.decode"
mock_tpi_stats = AdvisoryTPIStats(id=1, advisory_shape_id=1, valley_bottom=1, mid_slope=2, upper_slope=3, pixel_size_metres=50)
mock_elevation_info = [AdvisoryElevationStats(id=1, advisory_shape_id=1, threshold=1, minimum=1.0, quartile_25=2.0, median=3.0, quartile_75=4.0, maximum=5.0)]
mock_fire_centre_info = [(9.0, 11.0, 1, 1, 50)]
mock_sfms_run_datetimes = [
RunParameters(id=1, run_type="forecast", run_datetime=datetime(year=2024, month=1, day=1, hour=1, tzinfo=timezone.utc), for_date=date(year=2024, month=1, day=2))
]
Expand All @@ -43,12 +44,12 @@ async def mock_get_tpi_stats(*_, **__):
return mock_tpi_stats


async def mock_get_centre_tpi_stats(*_, **__):
return [mock_centre_tpi_stats_1, mock_centre_tpi_stats_2]
async def mock_get_fire_centre_info(*_, **__):
return mock_fire_centre_info


async def mock_get_elevation_info(*_, **__):
return mock_elevation_info
async def mock_get_centre_tpi_stats(*_, **__):
return [mock_centre_tpi_stats_1, mock_centre_tpi_stats_2]


async def mock_get_sfms_run_datetimes(*_, **__):
Expand All @@ -65,7 +66,7 @@ def client():

@pytest.mark.parametrize(
"endpoint",
[get_fire_centres_url, get_fire_zone_areas_url, get_fire_zone_tpi_stats_url, get_fire_zone_elevation_info_url, get_sfms_run_datetimes_url],
[get_fire_centres_url, get_fire_zone_areas_url, get_fire_zone_tpi_stats_url, get_fire_centre_info_url, get_sfms_run_datetimes_url],
)
def test_get_endpoints_unauthorized(client: TestClient, endpoint: str):
"""Forbidden to get fire zone areas when unauthorized"""
Expand All @@ -83,19 +84,32 @@ def test_get_fire_centres_authorized(client: TestClient):
assert response.status_code == 200


async def mock_hfi_thresholds(*_, **__):
return [HfiClassificationThreshold(id=1, description="4000 < hfi < 10000", name="advisory")]


async def mock_sfms_fuel_types(*_, **__):
return [SFMSFuelType(id=1, fuel_type_id=1, fuel_type_code="C2", description="test fuel type c2")]


async def mock_zone_ids_in_centre(*_, **__):
return [1]


@patch("app.routers.fba.get_auth_header", mock_get_auth_header)
@patch("app.routers.fba.get_zonal_elevation_stats", mock_get_elevation_info)
@patch("app.routers.fba.get_precomputed_stats_for_shape", mock_get_fire_centre_info)
@patch("app.routers.fba.get_all_hfi_thresholds", mock_hfi_thresholds)
@patch("app.routers.fba.get_all_sfms_fuel_types", mock_sfms_fuel_types)
@patch("app.routers.fba.get_zone_ids_in_centre", mock_zone_ids_in_centre)
@pytest.mark.usefixtures("mock_jwt_decode")
def test_get_fire_zone_elevation_info_authorized(client: TestClient):
"""Allowed to get fire zone elevation info when authorized"""
response = client.get(get_fire_zone_elevation_info_url)
def test_get_fire_center_info_authorized(client: TestClient):
"""Allowed to get fire centre info when authorized"""
response = client.get(get_fire_centre_info_url)
assert response.status_code == 200
assert response.json()["hfi_elevation_info"][0]["threshold"] == mock_elevation_info[0].threshold
assert response.json()["hfi_elevation_info"][0]["elevation_info"]["minimum"] == mock_elevation_info[0].minimum
assert response.json()["hfi_elevation_info"][0]["elevation_info"]["quartile_25"] == mock_elevation_info[0].quartile_25
assert response.json()["hfi_elevation_info"][0]["elevation_info"]["median"] == mock_elevation_info[0].median
assert response.json()["hfi_elevation_info"][0]["elevation_info"]["quartile_75"] == mock_elevation_info[0].quartile_75
assert response.json()["hfi_elevation_info"][0]["elevation_info"]["maximum"] == mock_elevation_info[0].maximum
assert response.json()["Kamloops Fire Centre"]["1"][0]["fuel_type"]["fuel_type_id"] == 1
assert response.json()["Kamloops Fire Centre"]["1"][0]["threshold"]["id"] == 1
assert response.json()["Kamloops Fire Centre"]["1"][0]["critical_hours"]["start_time"] == 9.0
assert response.json()["Kamloops Fire Centre"]["1"][0]["critical_hours"]["end_time"] == 11.0


@patch("app.routers.fba.get_auth_header", mock_get_auth_header)
Expand All @@ -108,20 +122,6 @@ def test_get_sfms_run_datetimes_authorized(client: TestClient):
assert response.json()[0] == datetime(year=2024, month=1, day=1, hour=1, tzinfo=timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")


@patch("app.routers.fba.get_auth_header", mock_get_auth_header)
@patch("app.routers.fba.get_zonal_tpi_stats", mock_get_tpi_stats)
@pytest.mark.usefixtures("mock_jwt_decode")
def test_get_fire_zone_tpi_stats_authorized(client: TestClient):
"""Allowed to get fire zone tpi stats when authorized"""
response = client.get(get_fire_zone_tpi_stats_url)
square_metres = math.pow(mock_tpi_stats.pixel_size_metres, 2)
assert response.status_code == 200
assert response.json()["fire_zone_id"] == 1
assert response.json()["valley_bottom"] == mock_tpi_stats.valley_bottom * square_metres
assert response.json()["mid_slope"] == mock_tpi_stats.mid_slope * square_metres
assert response.json()["upper_slope"] == mock_tpi_stats.upper_slope * square_metres


@patch("app.routers.fba.get_auth_header", mock_get_auth_header)
@patch("app.routers.fba.get_centre_tpi_stats", mock_get_centre_tpi_stats)
@pytest.mark.usefixtures("mock_jwt_decode")
Expand Down
29 changes: 13 additions & 16 deletions web/src/api/fbaAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,16 @@ export interface FBAResponse {
fire_centers: FireCenter[]
}

export interface FireZoneThresholdFuelTypeArea {
export interface AdvisoryCriticalHours {
start_time?: number
end_time?: number
}


export interface FireZoneFuelStats {
fuel_type: FuelType
threshold: HfiThreshold
critical_hours: AdvisoryCriticalHours
area: number
}

Expand Down Expand Up @@ -96,9 +103,9 @@ export interface FuelType {
description: string
}

export interface FireCentreHfiFuelsData {
export interface FireCentreHFIStats {
[fire_centre_name: string]: {
[fire_zone_id: number]: FireZoneThresholdFuelTypeArea[]
[fire_zone_id: number]: FireZoneFuelStats[]
}
}

Expand Down Expand Up @@ -142,24 +149,14 @@ export async function getAllRunDates(run_type: RunType, for_date: string): Promi
return data
}

export async function getHFIThresholdsFuelTypesForZone(
run_type: RunType,
for_date: string,
run_datetime: string,
zone_id: number
): Promise<Record<number, FireZoneThresholdFuelTypeArea[]>> {
const url = `fba/hfi-fuels/${run_type.toLowerCase()}/${for_date}/${run_datetime}/${zone_id}`
const { data } = await axios.get(url)
return data
}

export async function getHFIThresholdsFuelTypesForCentre(
export async function getFireCentreHFIStats(
run_type: RunType,
for_date: string,
run_datetime: string,
fire_centre: string
): Promise<FireCentreHfiFuelsData> {
const url = `fba/fire-centre-hfi-fuels/${run_type.toLowerCase()}/${for_date}/${run_datetime}/${fire_centre}`
): Promise<FireCentreHFIStats> {
const url = `fba/fire-centre-hfi-stats/${run_type.toLowerCase()}/${for_date}/${run_datetime}/${fire_centre}`
const { data } = await axios.get(url)
return data
}
Expand Down
Loading
Loading