-
Notifications
You must be signed in to change notification settings - Fork 73
/
uv.go
181 lines (157 loc) · 4.92 KB
/
uv.go
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
package openweathermap
import (
"encoding/json"
"errors"
"fmt"
"net/http"
"time"
)
var errInvalidUVIndex = errors.New("invalid UV index value")
// UVDataPoints holds the UV specific data
type UVDataPoints struct {
DT int64 `json:"dt"`
Value float64 `json:"value"`
}
// UV contains the response from the OWM UV API
type UV struct {
Coord []float64 `json:"coord"`
Data []UVDataPoints `json:"data,omitempty"`
/*Data []struct {
DT int64 `json:"dt"`
Value float64 `json:"value"`
} `json:"data,omitempty"`*/
DT int64 `json:"dt,omitempty"`
Value float64 `json:"value,omitempty"`
Key string
*Settings
}
// NewUV creates a new reference to UV
func NewUV(key string, options ...Option) (*UV, error) {
k, err := setKey(key)
if err != nil {
return nil, err
}
u := &UV{
Key: k,
Settings: NewSettings(),
}
if err := setOptions(u.Settings, options); err != nil {
return nil, err
}
return u, nil
}
// Current gets the current UV data for the given coordinates
func (u *UV) Current(coord *Coordinates) error {
response, err := u.client.Get(fmt.Sprintf("%suvi?lat=%f&lon=%f&appid=%s", uvURL, coord.Latitude, coord.Longitude, u.Key))
if err != nil {
return err
}
defer response.Body.Close()
if response.StatusCode == http.StatusUnauthorized {
return errInvalidKey
}
if err = json.NewDecoder(response.Body).Decode(&u); err != nil {
return err
}
return nil
}
// Historical gets the historical UV data for the coordinates and times
func (u *UV) Historical(coord *Coordinates, start, end time.Time) error {
response, err := u.client.Get(fmt.Sprintf("%shistory?lat=%f&lon=%f&start=%d&end=%d&appid=%s", uvURL, coord.Latitude, coord.Longitude, start.Unix(), end.Unix(), u.Key))
if err != nil {
return err
}
defer response.Body.Close()
if response.StatusCode == http.StatusUnauthorized {
return errInvalidKey
}
if err = json.NewDecoder(response.Body).Decode(&u); err != nil {
return err
}
return nil
}
// UVIndexInfo
type UVIndexInfo struct {
// UVIndex holds the range of the index
UVIndex []float64
// MGC represents the Media graphic color
MGC string
// Risk of harm from unprotected sun exposure, for the average adult
Risk string
// RecommendedProtection contains information on what a person should
// do when outside in the associated UVIndex
RecommendedProtection string
}
// UVData contains data in regards to UV index ranges, rankings, and steps for protection
var UVData = []UVIndexInfo{
{
UVIndex: []float64{0, 2.9},
MGC: "Green",
Risk: "Low",
RecommendedProtection: "Wear sunglasses on bright days; use sunscreen if there is snow on the ground, which reflects UV radiation, or if you have particularly fair skin.",
},
{
UVIndex: []float64{3, 5.9},
MGC: "Yellow",
Risk: "Moderate",
RecommendedProtection: "Take precautions, such as covering up, if you will be outside. Stay in shade near midday when the sun is strongest.",
},
{
UVIndex: []float64{6, 7.9},
MGC: "Orange",
Risk: "High",
RecommendedProtection: "Cover the body with sun protective clothing, use SPF 30+ sunscreen, wear a hat, reduce time in the sun within three hours of solar noon, and wear sunglasses.",
},
{
UVIndex: []float64{8, 10.9},
MGC: "Red",
Risk: "Very high",
RecommendedProtection: "Wear SPF 30+ sunscreen, a shirt, sunglasses, and a wide-brimmed hat. Do not stay in the sun for too long.",
},
{
UVIndex: []float64{11},
MGC: "Violet",
Risk: "Extreme",
RecommendedProtection: "Take all precautions: Wear SPF 30+ sunscreen, a long-sleeved shirt and trousers, sunglasses, and a very broad hat. Avoid the sun within three hours of solar noon.",
},
}
// UVInformation provides information on the given UV data which includes the severity
// and "Recommended protection"
func (u *UV) UVInformation() ([]UVIndexInfo, error) {
switch {
case u.Value != 0:
switch {
case u.Value < 2.9:
return []UVIndexInfo{UVData[0]}, nil
case u.Value > 3 && u.Value < 5.9:
return []UVIndexInfo{UVData[1]}, nil
case u.Value > 6 && u.Value < 7.9:
return []UVIndexInfo{UVData[2]}, nil
case u.Value > 8 && u.Value < 10.9:
return []UVIndexInfo{UVData[3]}, nil
case u.Value >= 11:
return []UVIndexInfo{UVData[4]}, nil
default:
return nil, errInvalidUVIndex
}
case len(u.Data) > 0:
var uvi []UVIndexInfo
for _, i := range u.Data {
switch {
case i.Value < 2.9:
uvi = append(uvi, UVData[0])
case i.Value > 3 && u.Value < 5.9:
uvi = append(uvi, UVData[1])
case i.Value > 6 && u.Value < 7.9:
uvi = append(uvi, UVData[2])
case i.Value > 8 && u.Value < 10.9:
uvi = append(uvi, UVData[3])
case i.Value >= 11:
uvi = append(uvi, UVData[4])
default:
return nil, errInvalidUVIndex
}
}
}
return nil, nil
}