Update getTimezone and getTimeData to modern TypeScript

This commit is contained in:
Matthew Oslan
2019-05-09 16:19:07 -04:00
parent bffede7734
commit cc14e089e2

View File

@@ -62,11 +62,12 @@ async function getData( url: string ): Promise< any > {
} }
// Retrieve data from Open Weather Map for water level calculations // Retrieve data from Open Weather Map for water level calculations
function getOWMWateringData( location, callback ) { async function getOWMWateringData( location, callback ) {
var OWM_API_KEY = process.env.OWM_API_KEY, var OWM_API_KEY = process.env.OWM_API_KEY,
forecastUrl = "http://api.openweathermap.org/data/2.5/forecast?appid=" + OWM_API_KEY + "&units=imperial&lat=" + location[ 0 ] + "&lon=" + location[ 1 ]; forecastUrl = "http://api.openweathermap.org/data/2.5/forecast?appid=" + OWM_API_KEY + "&units=imperial&lat=" + location[ 0 ] + "&lon=" + location[ 1 ];
getTimeData( location, async function( weather ) { // TODO change the type of this after defining the appropriate type
const weather: any = getTimeData( location );
// Perform the HTTP request to retrieve the weather data // Perform the HTTP request to retrieve the weather data
let forecast; let forecast;
@@ -101,16 +102,16 @@ function getOWMWateringData( location, callback ) {
weather.raining = ( forecast.list[ 0 ].rain ? ( parseFloat( forecast.list[ 0 ].rain[ "3h" ] || 0 ) > 0 ) : false ); weather.raining = ( forecast.list[ 0 ].rain ? ( parseFloat( forecast.list[ 0 ].rain[ "3h" ] || 0 ) > 0 ) : false );
callback( weather ); callback( weather );
} );
} }
// Retrieve weather data from Open Weather Map for App // Retrieve weather data from Open Weather Map for App
function getOWMWeatherData( location, callback ) { async function getOWMWeatherData( location, callback ) {
var OWM_API_KEY = process.env.OWM_API_KEY, var OWM_API_KEY = process.env.OWM_API_KEY,
currentUrl = "http://api.openweathermap.org/data/2.5/weather?appid=" + OWM_API_KEY + "&units=imperial&lat=" + location[ 0 ] + "&lon=" + location[ 1 ], currentUrl = "http://api.openweathermap.org/data/2.5/weather?appid=" + OWM_API_KEY + "&units=imperial&lat=" + location[ 0 ] + "&lon=" + location[ 1 ],
forecastDailyUrl = "http://api.openweathermap.org/data/2.5/forecast/daily?appid=" + OWM_API_KEY + "&units=imperial&lat=" + location[ 0 ] + "&lon=" + location[ 1 ]; forecastDailyUrl = "http://api.openweathermap.org/data/2.5/forecast/daily?appid=" + OWM_API_KEY + "&units=imperial&lat=" + location[ 0 ] + "&lon=" + location[ 1 ];
getTimeData( location, async function( weather ) { // TODO change the type of this after defining the appropriate type
const weather: any = getTimeData( location );
let current, forecast; let current, forecast;
try { try {
@@ -152,25 +153,28 @@ function getOWMWeatherData( location, callback ) {
} }
callback( weather ); callback( weather );
} );
} }
// Calculate timezone and sun rise/set information /**
function getTimeData( location, callback ) { * Calculates timezone and sunrise/sunset for the specified coordinates.
var timezone = moment().tz( geoTZ( location[ 0 ], location[ 1 ] ) ).utcOffset(); * @param coordinates The coordinates to use to calculate time data.
var tzOffset = getTimezone( timezone, "minutes" ); * @return The TimeData for the specified coordinates.
*/
function getTimeData( coordinates: GeoCoordinates ): TimeData {
const timezone = moment().tz( geoTZ( coordinates[ 0 ], coordinates[ 1 ] ) ).utcOffset();
const tzOffset: number = getTimezone( timezone, true );
// Calculate sunrise and sunset since Weather Underground does not provide it // Calculate sunrise and sunset since Weather Underground does not provide it
var sunData = SunCalc.getTimes( new Date(), location[ 0 ], location[ 1 ] ); const sunData = SunCalc.getTimes( new Date(), coordinates[ 0 ], coordinates[ 1 ] );
sunData.sunrise.setUTCMinutes( sunData.sunrise.getUTCMinutes() + tzOffset ); sunData.sunrise.setUTCMinutes( sunData.sunrise.getUTCMinutes() + tzOffset );
sunData.sunset.setUTCMinutes( sunData.sunset.getUTCMinutes() + tzOffset ); sunData.sunset.setUTCMinutes( sunData.sunset.getUTCMinutes() + tzOffset );
callback( { return {
timezone: timezone, timezone: timezone,
sunrise: ( sunData.sunrise.getUTCHours() * 60 + sunData.sunrise.getUTCMinutes() ), sunrise: ( sunData.sunrise.getUTCHours() * 60 + sunData.sunrise.getUTCMinutes() ),
sunset: ( sunData.sunset.getUTCHours() * 60 + sunData.sunset.getUTCMinutes() ) sunset: ( sunData.sunset.getUTCHours() * 60 + sunData.sunset.getUTCMinutes() )
} ); };
} }
// Calculates the resulting water scale using the provided weather data, adjustment method and options // Calculates the resulting water scale using the provided weather data, adjustment method and options
@@ -294,7 +298,8 @@ exports.getWateringData = async function( req, res ) {
finishRequest = function( weather ) { finishRequest = function( weather ) {
if ( !weather ) { if ( !weather ) {
if ( typeof location[ 0 ] === "number" && typeof location[ 1 ] === "number" ) { if ( typeof location[ 0 ] === "number" && typeof location[ 1 ] === "number" ) {
getTimeData( location, finishRequest ); const timeData: TimeData = getTimeData( location );
finishRequest( timeData );
} else { } else {
res.send( "Error: No weather data found." ); res.send( "Error: No weather data found." );
} }
@@ -465,12 +470,16 @@ function validateValues( keys, array ) {
return true; return true;
} }
// Accepts a time string formatted in ISO-8601 or just the timezone /**
// offset and returns the timezone. * Converts a timezone to an offset in minutes or OpenSprinkler encoded format.
// The timezone output is formatted for OpenSprinkler Unified firmware. * @param time A time string formatted in ISO-8601 or just the timezone.
function getTimezone( time, format ) { * @param useMinutes Indicates if the returned value should be in minutes of the OpenSprinkler encoded format.
* @return The offset of the specified timezone in either minutes or OpenSprinkler encoded format (depending on the
* value of useMinutes).
*/
function getTimezone( time: number | string, useMinutes: boolean = false ): number {
var hour, minute, tz; let hour, minute;
if ( typeof time === "number" ) { if ( typeof time === "number" ) {
hour = Math.floor( time / 60 ); hour = Math.floor( time / 60 );
@@ -478,24 +487,22 @@ function getTimezone( time, format ) {
} else { } else {
// Match the provided time string against a regex for parsing // Match the provided time string against a regex for parsing
time = time.match( filters.time ) || time.match( filters.timezone ); let splitTime = time.match( filters.time ) || time.match( filters.timezone );
hour = parseInt( time[ 7 ] + time[ 8 ] ); hour = parseInt( splitTime[ 7 ] + splitTime[ 8 ] );
minute = parseInt( time[ 9 ] ); minute = parseInt( splitTime[ 9 ] );
} }
if ( format === "minutes" ) { if ( useMinutes ) {
tz = ( hour * 60 ) + minute; return ( hour * 60 ) + minute;
} else { } else {
// Convert the timezone into the OpenSprinkler encoded format // Convert the timezone into the OpenSprinkler encoded format
minute = ( minute / 15 >> 0 ) / 4; minute = ( minute / 15 >> 0 ) / 4;
hour = hour + ( hour >= 0 ? minute : -minute ); hour = hour + ( hour >= 0 ? minute : -minute );
tz = ( ( hour + 12 ) * 4 ) >> 0; return ( ( hour + 12 ) * 4 ) >> 0;
} }
return tz;
} }
// Converts IP string to integer // Converts IP string to integer
@@ -506,3 +513,14 @@ function ipToInt( ip ) {
/** Geographic coordinates. The 1st element is the latitude, and the 2nd element is the longitude. */ /** Geographic coordinates. The 1st element is the latitude, and the 2nd element is the longitude. */
type GeoCoordinates = [number, number]; type GeoCoordinates = [number, number];
interface TimeData {
/** The UTC offset, in minutes. This uses POSIX offsets, which are the negation of typically used offsets
* (https://github.com/eggert/tz/blob/2017b/etcetera#L36-L42).
*/
timezone: number;
/** The time of sunrise, in minutes from UTC midnight. */
sunrise: number;
/** The time of sunset, in minutes from UTC midnight. */
sunset: number;
}