Rabarar's Blog

A blogging framework for mild hackers.

Open Weather API and Golang

| Comments

Weather API

Today I tripped over the OpenWeatherMap and created an account to see what type of weather information I can get from the published api. Cool stuff.

I thought I’d write a quick little golang program to extract the json data and turn it into something that I could send to say(1), and then pump that through darkice(1) and icecast(1) on a raspberry pi! A talking weather station of sorts.

Here’s the code:

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
package main

import (
        "encoding/json"
        "fmt"
        "io/ioutil"
        "log"
        "net/http"
        "net/url"
        "strings"
        "time"
)

const (
        dumpRaw = false
        zip     = "21045,us"
        api     = "XXXXXXXXXXXXXXXXXXXXXXXXXX"
)

var (
        weatherKeys = map[string]bool{"main": false, "wind": false, "coord": false, "weather": true, "sys": false, "clouds": false}
)

func main() {

        urlString := fmt.Sprintf("http://api.openweathermap.org/data/2.5/weather?zip=%s&APPID=%s", zip, api)
        u, err := url.Parse(urlString)
        res, err := http.Get(u.String())
        if err != nil {
                log.Fatal(err)
        }

        jsonBlob, err := ioutil.ReadAll(res.Body)
        res.Body.Close()
        if err != nil {
                log.Fatal(err)
        }

        var data map[string]interface{}

        if dumpRaw {
                fmt.Printf("blob = %s\n\n", jsonBlob)
        }
        err = json.Unmarshal(jsonBlob, &data)
        if err != nil {
                fmt.Println("error:", err)
        }

        if dumpRaw {
                fmt.Printf("%+v", data)
        }
        for k, v := range data {
                val, isAnArray := isKey(k)
                if val {
                        dumpMap(k, v, isAnArray)
                } else {
                }
        }
}

func dumpMap(k string, v interface{}, isArray bool) {

        fmt.Printf("%s:\n", k)
        if isArray {
                for i := 0; i < len(v.([]interface{})); i++ {
                        nmap := v.([]interface{})[i].(map[string]interface{})
                        for kk, vv := range nmap {
                                fmt.Printf("\tthe %s is %v\n", kk, vv)
                        }
                }
        } else {
                nmap := v.(map[string]interface{})
                for kk, vv := range nmap {
                        if isTempVal(kk) {
                                farenTemp := faren(vv.(float64))
                                fmt.Printf("\tthe %s is %f\n", kk, farenTemp)
                        } else if isSunVal(kk) {
                                sunTime := time.Unix((int64(vv.(float64))), 0)
                                fmt.Printf("\tthe %s at %v\n", kk, sunTime)
                        } else {
                                fmt.Printf("\tthe %s is %v\n", kk, vv)
                        }
                }
        }
}

func isKey(k string) (ok bool, isArray bool) {
        isArray, ok = weatherKeys[k]
        return ok, isArray
}

func faren(kelvin float64) float64 {
        return (9.0/5.0*(kelvin-273.0) + 32.0)
}

func isTempVal(k string) bool {
        return strings.Contains(k, "temp")
}

func isSunVal(k string) bool {
        return strings.Contains(k, "sun")
}

So what’s it do??

The given a zipcode, and an API Key, output generates something like this:

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
main:
  the humidity is 83
  the temp_min is 38.962400
  the temp_max is 38.962400
  the sea_level is 1038.13
  the grnd_level is 1031.23
  the temp is 38.962400
  the pressure is 1031.23
wind:
  the speed is 6.26
  the deg is 319.504
clouds:
  the all is 32
sys:
  the message is 0.0066
  the country is US
  the sunrise at 2016-02-05 07:10:10 -0500 EST
  the sunset at 2016-02-05 17:33:06 -0500 EST
coord:
  the lon is -76.84
  the lat is 39.24
weather:
  the description is scattered clouds
  the icon is 03d
  the id is 802
  the main is Clouds

Just a start… check out other API calls too…

Comments