-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
164 lines (140 loc) · 3.7 KB
/
main.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
package main
import (
"encoding/json"
"flag"
"fmt"
"net/http"
"os"
"strings"
"time"
"github.com/gomodule/redigo/redis"
)
var (
name string
version string
gitSHA string
)
// positionURL is the URL to get the ISS position
const positionURL = "http://api.open-notify.org/iss-now.json"
// issPosition contains the latitude and longitude of the ISS
type issPosition struct {
Latitude string `json:"longitude"`
Longitude string `json:"latitude"`
}
// response prepresents the returned JSON from the
// ISS call
type response struct {
ISSPosition *issPosition `json:"iss_position"`
Message string `json:"message"`
Timestamp int64 `json:"timestamp"`
}
// position gets the current position of the ISS
func position(hc *http.Client) (*issPosition, error) {
req, err := http.NewRequest(http.MethodGet, positionURL, nil)
if err != nil {
return nil, err
}
res, err := hc.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
var r response
if err := json.NewDecoder(res.Body).Decode(&r); err != nil {
return nil, err
}
return r.ISSPosition, nil
}
const usage = `version: %s - git: %s
Usage: %s [-p port] [-l domain]
Options:
-h this help
-v show version and exit
-i api query interval in seconds
-s size of geofence in meters
-t tile38 address & port. format: "127.0.0.1:9851"
-l location for geofence. format: 33.4484,112.0740
-e endpoint for the notification to be sent
Examples:
%[3]s -t localhost:9851 -i 10 -s 5000 -l 33.4484,112.0740 run the server
`
func main() {
var vers bool
var intervalFlag int
var geofenseSizeFlag string
var tile38AddressFlag string
var locationFlag string
var endpointFlag string
flag.Usage = func() {
w := os.Stderr
for _, arg := range os.Args {
if arg == "-h" {
w = os.Stdout
break
}
}
fmt.Fprintf(w, usage, version, gitSHA, name)
}
flag.BoolVar(&vers, "v", false, "")
flag.IntVar(&intervalFlag, "i", 60, "")
flag.StringVar(&geofenseSizeFlag, "s", "", "")
flag.StringVar(&tile38AddressFlag, "t", "", "")
flag.StringVar(&locationFlag, "l", "", "")
flag.StringVar(&endpointFlag, "e", "", "")
flag.Parse()
if vers {
fmt.Fprintf(os.Stdout, "version: %s\n", version)
return
}
// make sure the tile38Address isn't an empty
if tile38AddressFlag == "" {
fmt.Println("error: tile38 address required")
os.Exit(1)
}
// make sure the Tile38 address is formatted correcrtly
if !strings.Contains(tile38AddressFlag, ":") {
fmt.Println("error: tile38 address format incorrect")
os.Exit(1)
}
// make sure the endpoint isn't an empty
if endpointFlag == "" {
fmt.Println("error: endpoint required")
os.Exit(1)
}
// connect to Tile38
c, err := redis.Dial("tcp", tile38AddressFlag)
if err != nil {
fmt.Println("error: tile38 - ", err)
os.Exit(1)
}
defer c.Close()
// make sure the given location is formatted correctly
if !strings.Contains(locationFlag, ",") {
fmt.Println("error: location format requires a ',' seperating lat and lon")
os.Exit(1)
}
loc := strings.Split(locationFlag, ",")
// set the geofence notification
_, err = c.Do("SETHOOK", "iss-notify", endpointFlag, "NEARBY", "earth-orbit", "FENCE", "POINT", loc[0], loc[1], geofenseSizeFlag)
if err != nil {
fmt.Println("error: tile38 - ", err)
os.Exit(1)
}
hc := http.Client{
Timeout: 10 * time.Second,
}
ticker := time.NewTicker(time.Second * time.Duration(intervalFlag))
defer ticker.Stop()
for range ticker.C {
pos, err := position(&hc)
if err != nil {
fmt.Println(err)
continue
}
_, err = c.Do("SET", "earth-orbit", "iss", "POINT", pos.Latitude, pos.Longitude)
if err != nil {
fmt.Println(err)
continue
}
}
}