-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathweather.js
146 lines (128 loc) · 4.63 KB
/
weather.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import GLib from 'gi://GLib';
import Soup from 'gi://Soup';
/*
type WeatherAPIData = {
weather: {
id: number, // Weather condition id
main: string, // Group of weather parameters (Rain, Snow, Clouds etc.)
description: string,// Weather condition within the group
icon: string, // Weather icon id
}[],
main: {
temp: number, // Temperature, Metric: Celsius, Imperial: Fahrenheit
feels_like: number, // What temperature it feels like, Metric: Celsius, Imperial: Fahrenheit
temp_min: number, // Minimum temperature at the moment
temp_max: number, // Maximum temperature at the moment
pressure: number, // Atmospheric pressure on the sea level, hPa
humidity: number, // Humidity, %
sea_level: number, // Atmospheric pressure on the sea level, hPa
grnd_level: number, // Atmospheric pressure on the ground level, hPa
},
visibility: number, // Visibility, meter (max 10km)
wind: {
speed: number, // Wind speed, Metric: meter/sec, Imperial: miles/hour
deg: number, // Wind direction, degrees (meteorological)
gust: number, // Wind gust, Metric: meter/sec, Imperial: miles/hour
},
clouds: {
all: number, // Cloudiness, %
},
rain?: {
'1h': number, // Rain volume for the last 1 hour, mm
'3h': number, // Rain volume for the last 3 hours, mm
},
snow?: {
'1h': number, // Snow volume for the last 1 hour, mm
'3h': number, // Snow volume for the last 3 hours, mm
},
dt: number, // Time of data calculation, unix, UTC
sys: {
country: string, // Country code
sunrise: number, // Sunrise time, unix, UTC
sunset: number, // Sunset time, unix, UTC
},
timezone: number, // Shift in seconds from UTC
}
*/
export default class Weather {
// TODO Show more of data
#data = null;
#soupSession = new Soup.Session();
#WeatherTranslate = {
'Clear': 'clear',
'Clearnight': 'clear-night',
'Clouds': 'overcast',
'Cloudsnight': 'overcast',
'Atmosphere': 'fog',
'Atmospherenight': 'fog',
'Snow': 'snow',
'Snownight': 'snow',
'Rain': 'showers',
'Rainnight': 'showers',
'Drizzle': 'showers-scattered',
'Drizzlenight': 'showers-scattered',
'Thunderstorm': 'storm',
'Thunderstormnight': 'storm',
'FewClouds': 'few-clouds',
'FewCloudsnight': 'few-clouds-night',
'Windy': 'windy',
'Alert': 'severe-alert',
};
/**
* Get Gnome weather icon name.
* @returns icon name to use in `new St.Icon`
*/
iconStr() {
// TODO Base also on weather ID
let night = '';
if (this.#data.dt > this.#data.sys.sunset || this.#data.dt < this.#data.sys.sunrise) {
night = 'night';
}
const sky = this.#data.weather[0].main;
const icon = this.#WeatherTranslate[`${sky}${night}`];
return `weather-${icon}-symbolic`;
}
/**
* Get current temperature.
* @returns string of current temperature
*/
temperatureStr() {
return `${Math.round(this.#data.main.temp)}°C`;
}
/**
* Query the Weather API.
* @param lat latitude to query for
* @param lon longitude to query for
* @param apiKey openweathermap.org API key
* @param finalFunc optional function to call after the data is ready
*/
query(lat, lon, apiKey, finalFunc = null) {
const apiURL = `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${apiKey}&units=metric`;
const message = Soup.Message.new('GET', apiURL);
// TODO Add API call counter
this.#soupSession.send_and_read_async(
message,
GLib.PRIORITY_DEFAULT,
null,
(session, result) => {
// TODO What if fails
if (message.get_status() === Soup.Status.OK) {
const bytes = session.send_and_read_finish(result);
const decoder = new TextDecoder('utf-8');
const response = decoder.decode(bytes.get_data());
this.#data = JSON.parse(response);
finalFunc !== null && finalFunc();
}
}
);
}
/**
* Check that the object has weather data.
* @returns True if has data from API
*/
gotData() {
return this.#data !== null;
}
// TODO Get current city
// TODO Get weather description
}