Skip to content

Commit

Permalink
feat: snow indicator on province temp/precip (#602)
Browse files Browse the repository at this point in the history
  • Loading branch information
Forceh91 authored Jan 12, 2024
1 parent 3f20f2a commit ea84167
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 21 deletions.
5 changes: 2 additions & 3 deletions src/__tests__/provinceTracking.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import axios from "lib/backendAxios";

jest.mock("lib/config/config", () => ({
initializeConfig: () => ({
primaryLocation: { name: "Toronto", province: "ON", location: "s0000458" },
provinceHighLowEnabled: true,
provinceStations: [
{ name: "Toronto", code: "ON/s0000458" },
Expand All @@ -17,13 +18,11 @@ jest.mock("lib/eccc", () => ({
}),
initializeHistoricalTempPrecip: () => ({
yesterdayPrecipData: jest.fn(() => ({ amount: 23.5 })),
yesterdaySnowData: jest.fn(() => ({ amount: null })),
}),
}));

jest.mock("fs");
jest.mock("consts/server.consts", () => ({
DEFAULT_WEATHER_STATION_ID: "ON/s0000458",
}));

import { initializeProvinceTracking } from "lib/provincetracking/provinceTracking";
import fakeTorontoWeather, {
Expand Down
2 changes: 2 additions & 0 deletions src/__tests__/testdata/ecccData/provincetracking/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ export default {
maxTemp: 26.4,
displayTemp: "M",
yesterdayPrecip: 23.5,
yesterdayPrecipUnit: "mm",
},
{
station: { name: "Ottawa", code: "ON/s0000623" },
minTemp: Math.min(),
maxTemp: 25.8,
displayTemp: "M",
yesterdayPrecip: 0,
yesterdayPrecipUnit: "mm",
},
],
isOvernight: true,
Expand Down
13 changes: 8 additions & 5 deletions src/display/components/screens/provincetracking.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,18 @@ export function ProvinceTrackingScreen(props: ProvinceTrackingProps) {

if (!stations?.length) return <></>;

const precipString = (precip: string | number) => {
// precip string must be longer than 13 chars
const precipString = (precip: string | number, unit: string) => {
if (typeof precip === "string") return precip;

const precipNumber = Number(precip);
if (!precipNumber) return "NIL".padStart(5);

// less than 0.2mm is trace amounts
if (precipNumber < 0.2) return "TRACE";

return `${precipNumber.toFixed(1)} MM`.padStart(7);
const noPrecipType = unit.length === 2;
return `${noPrecipType ? "".padStart(2) : ""}${precipNumber.toFixed(1)} ${unit ?? "mm"}`.toUpperCase();
};

const formatTemp = (temp: number | string) => {
Expand All @@ -56,10 +59,10 @@ export function ProvinceTrackingScreen(props: ProvinceTrackingProps) {
<ol>
{stations.map((station) => (
<li key={station.station.code}>
<span>{station.station.name.slice(0, 10).padEnd(10)}</span>
<span>{station.station.name.slice(0, 10).replace(/[-_/]/g, "").padEnd(10)}</span>
<span>{formatTemp(station.displayTemp).padStart(8)}</span>
<span>{"".padEnd(7)}</span>
<span>{precipString(station.yesterdayPrecip)}</span>
<span>{"".padEnd(5)}</span>
<span>{precipString(station.yesterdayPrecip, station.yesterdayPrecipUnit)}</span>
</li>
))}
</ol>
Expand Down
17 changes: 14 additions & 3 deletions src/lib/eccc/historicalTempPrecip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ class HistoricalTempPrecip {

private _lastYearTemperatures: HistoricalTemperatureAlmanac = { min: null, max: null };
private _seasonPrecipData: HistoricalPrecipData = { amount: 0, normal: 0, unit: "mm", type: "rain" };
private _yesterdayPrecipData: HistoricalPrecipData = { amount: 0, normal: 0, unit: "mm", type: "rain" };
private _yesterdayPrecipData: HistoricalPrecipData = { amount: null, normal: 0, unit: "mm", type: "rain" };
private _yesterdaySnowData: HistoricalPrecipData = { amount: null, normal: 0, unit: "cm", type: "snow" };
private _lastMonthSummary: LastMonthSummary = null;

constructor() {
Expand Down Expand Up @@ -123,6 +124,7 @@ class HistoricalTempPrecip {
const isWinterSeason = getIsWinterSeason();
let rainfall = 0;
let yesterdayRainfall = 0;
let yesterdaySnowfall = 0;
this._historicalData?.forEach((historicalData) => {
if (!historicalData?._attributes) return;

Expand All @@ -149,8 +151,12 @@ class HistoricalTempPrecip {
}

// also store yesterday's precip data, just for reasons
if (isYesterday(parseISO(date)))
yesterdayRainfall = Number(Number(historicalData?.totalprecipitation?._text ?? 0).toFixed(1));
if (isYesterday(parseISO(date))) {
yesterdayRainfall = Number(
Number(historicalData?.totalrain?._text ?? historicalData.totalprecipitation?._text ?? 0).toFixed(1)
);
yesterdaySnowfall = Number(Number(historicalData?.totalsnow?._text ?? 0).toFixed(1));
}
});

// now we can store the total amount for the season
Expand All @@ -159,6 +165,7 @@ class HistoricalTempPrecip {

// and the total amount for yesterday
this._yesterdayPrecipData.amount = yesterdayRainfall;
this._yesterdaySnowData.amount = yesterdaySnowfall;

logger.log("Calculated precip data for the season/yesterday");

Expand Down Expand Up @@ -238,6 +245,10 @@ class HistoricalTempPrecip {
return this._yesterdayPrecipData;
}

public yesterdaySnowData() {
return this._yesterdaySnowData;
}

public lastMonthSummary() {
return this._lastMonthSummary;
}
Expand Down
25 changes: 15 additions & 10 deletions src/lib/provincetracking/provinceTracking.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
const Weather = require("ec-weather-js");
import fs from "fs";
import {
DEFAULT_WEATHER_STATION_ID,
EVENT_BUS_CONFIG_CHANGE_PROVINCE_TRACKING,
PROVINCE_TRACKING_TEMP_TO_TRACK,
} from "consts";
import { EVENT_BUS_CONFIG_CHANGE_PROVINCE_TRACKING, PROVINCE_TRACKING_TEMP_TO_TRACK } from "consts";
import axios from "lib/backendAxios";
import { initializeConfig } from "lib/config";
import Logger from "lib/logger";
Expand Down Expand Up @@ -63,6 +59,7 @@ class ProvinceTracking {
maxTemp: Math.max(),
displayTemp: null,
yesterdayPrecip: null,
yesterdayPrecipUnit: "mm",
}));
}

Expand Down Expand Up @@ -98,12 +95,20 @@ class ProvinceTracking {
if (station.yesterdayPrecip === null || this.shouldUpdatePrecipData()) {
const { yesterdayConditions } = weather.all;

// if winnipeg then use historical data, otherwise we can use the data from the conditions api
const yesterdayPrecip =
(station.station.code === DEFAULT_WEATHER_STATION_ID
? historicalData.yesterdayPrecipData().amount
: yesterdayConditions.precip?.value) ?? "MISSING";
// if selected station then use historical data, otherwise we can use the data from the conditions api
const isLocalStation =
station.station.code === `${config.primaryLocation.province}/${config.primaryLocation.location}`;

// pull in precip values with plenty of fallbacks so we do our best to display a value
const detailedPrecip = isLocalStation
? historicalData.yesterdaySnowData().amount ?? historicalData.yesterdayPrecipData().amount
: null;

// now store these to the station
const yesterdayPrecip = detailedPrecip ?? yesterdayConditions.precip?.value ?? "MISSING";
station.yesterdayPrecip = !isNaN(yesterdayPrecip) ? Number(yesterdayPrecip) : yesterdayPrecip;
station.yesterdayPrecipUnit =
isLocalStation && historicalData.yesterdaySnowData().amount > 0 ? "cm snow" : "mm";

// store what date this data is from
this._yesterdayPrecipDate = format(subDays(conditions.observedDateTimeAtStation(), 1), "MMM dd").replace(
Expand Down
1 change: 1 addition & 0 deletions src/types/provincetracking.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export type ProvinceStationTracking = {
maxTemp: number | null;
displayTemp: number | string;
yesterdayPrecip: number | string | null;
yesterdayPrecipUnit: string;
};

export type ProvinceTracking = {
Expand Down

0 comments on commit ea84167

Please sign in to comment.