feat: add goreport notation
This commit is contained in:
parent
4bf2f1e02f
commit
0ad5151d98
5 changed files with 186 additions and 181 deletions
|
@ -7,6 +7,10 @@ Which is based on [Keep A Changelog](http://keepachangelog.com/)
|
|||
|
||||
## Unreleased
|
||||
|
||||
### Added
|
||||
|
||||
- goreport notation
|
||||
|
||||
### Fixed
|
||||
|
||||
- too many open files close with influxdb connection
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# Weather
|
||||
|
||||
[![Version](https://img.shields.io/badge/latest_version-1.0.0-green.svg)](https://git.yaegashi.fr/nishiki/weather/releases)
|
||||
[![GoReport](https://goreportcard.com/badge/git.yaegashi.fr/nishiki/weather)](https://goreportcard.com/report/git.yaegashi.fr/nishiki/weather)
|
||||
[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](https://git.yaegashi.fr/nishiki/weather/src/branch/master/LICENSE)
|
||||
|
||||
weather is a small program that fetch weather informations, and store them to influxdb
|
||||
|
|
98
config.go
98
config.go
|
@ -17,78 +17,78 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
// Config struct contains all options
|
||||
type Config struct {
|
||||
InfluxDB struct {
|
||||
URL string `yaml:"url"`
|
||||
Database string `yaml:"database"`
|
||||
Measurement string `yaml:"measurement"`
|
||||
Username string `yaml:"username"`
|
||||
Password string `yaml:"password"`
|
||||
} `yaml:"influxdb"`
|
||||
OpenWeatherMap struct {
|
||||
APIKey string `yaml:"api_key"`
|
||||
Units string `yaml:"units"`
|
||||
} `yaml:"openweathermap"`
|
||||
Cities []string `yaml:"cities"`
|
||||
Interval int64 `yaml:"interval"`
|
||||
InfluxDB struct {
|
||||
URL string `yaml:"url"`
|
||||
Database string `yaml:"database"`
|
||||
Measurement string `yaml:"measurement"`
|
||||
Username string `yaml:"username"`
|
||||
Password string `yaml:"password"`
|
||||
} `yaml:"influxdb"`
|
||||
OpenWeatherMap struct {
|
||||
APIKey string `yaml:"api_key"`
|
||||
Units string `yaml:"units"`
|
||||
} `yaml:"openweathermap"`
|
||||
Cities []string `yaml:"cities"`
|
||||
Interval int64 `yaml:"interval"`
|
||||
}
|
||||
|
||||
// Load the config from a file
|
||||
func (c *Config) Load(path string) error {
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = yaml.Unmarshal(data, &c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = yaml.Unmarshal(data, &c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.Defaults()
|
||||
err = c.Check()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.Defaults()
|
||||
err = c.Check()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// Defaults set options with default value
|
||||
func (c *Config) Defaults() {
|
||||
if c.OpenWeatherMap.Units == "" {
|
||||
c.OpenWeatherMap.Units = "metric"
|
||||
}
|
||||
if c.OpenWeatherMap.Units == "" {
|
||||
c.OpenWeatherMap.Units = "metric"
|
||||
}
|
||||
|
||||
if c.Interval == 0 {
|
||||
c.Interval = 600
|
||||
}
|
||||
if c.Interval == 0 {
|
||||
c.Interval = 600
|
||||
}
|
||||
|
||||
if c.InfluxDB.URL == "" {
|
||||
c.InfluxDB.URL = "http://127.0.0.1:8086"
|
||||
}
|
||||
if c.InfluxDB.URL == "" {
|
||||
c.InfluxDB.URL = "http://127.0.0.1:8086"
|
||||
}
|
||||
|
||||
if c.InfluxDB.Measurement == "" {
|
||||
c.InfluxDB.Measurement = "weather"
|
||||
}
|
||||
if c.InfluxDB.Measurement == "" {
|
||||
c.InfluxDB.Measurement = "weather"
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the options are good
|
||||
func (c *Config) Check() error {
|
||||
if c.InfluxDB.Database == "" {
|
||||
return fmt.Errorf("you must specify influxdb.database in config file")
|
||||
}
|
||||
if c.InfluxDB.Database == "" {
|
||||
return fmt.Errorf("you must specify influxdb.database in config file")
|
||||
}
|
||||
|
||||
if c.OpenWeatherMap.APIKey == "" {
|
||||
return fmt.Errorf("you must specify api_key in config file")
|
||||
}
|
||||
if c.OpenWeatherMap.APIKey == "" {
|
||||
return fmt.Errorf("you must specify api_key in config file")
|
||||
}
|
||||
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
|
84
main.go
84
main.go
|
@ -17,63 +17,63 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"flag"
|
||||
"os"
|
||||
"time"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Options and OpenWeatherMap URI
|
||||
var (
|
||||
URI = "https://api.openweathermap.org/data/2.5"
|
||||
CONFIG = flag.String("config", "", "config file path")
|
||||
DAEMON = flag.Bool("daemon", false, "run in daemon mode")
|
||||
HELP = flag.Bool("help", false, "print this help message")
|
||||
URI = "https://api.openweathermap.org/data/2.5"
|
||||
CONFIG = flag.String("config", "", "config file path")
|
||||
DAEMON = flag.Bool("daemon", false, "run in daemon mode")
|
||||
HELP = flag.Bool("help", false, "print this help message")
|
||||
)
|
||||
|
||||
func init() {
|
||||
flag.Parse()
|
||||
flag.Parse()
|
||||
}
|
||||
|
||||
func main() {
|
||||
var w Weather
|
||||
var w Weather
|
||||
|
||||
if *HELP {
|
||||
flag.PrintDefaults()
|
||||
os.Exit(1)
|
||||
}
|
||||
if *HELP {
|
||||
flag.PrintDefaults()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if *CONFIG == "" {
|
||||
fmt.Println("you must specify a config file with -config option")
|
||||
os.Exit(1)
|
||||
}
|
||||
if *CONFIG == "" {
|
||||
fmt.Println("you must specify a config file with -config option")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
err := w.Config.Load(*CONFIG)
|
||||
if err != nil {
|
||||
fmt.Printf("%s\n", err)
|
||||
os.Exit(2)
|
||||
}
|
||||
err := w.Config.Load(*CONFIG)
|
||||
if err != nil {
|
||||
fmt.Printf("%s\n", err)
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
for {
|
||||
startTime := time.Now().Unix()
|
||||
for {
|
||||
startTime := time.Now().Unix()
|
||||
|
||||
w.FetchData()
|
||||
err = w.SendToInfluxDB()
|
||||
if err != nil {
|
||||
fmt.Printf("%s\n", err)
|
||||
}
|
||||
w.FetchData()
|
||||
err = w.SendToInfluxDB()
|
||||
if err != nil {
|
||||
fmt.Printf("%s\n", err)
|
||||
}
|
||||
|
||||
if *DAEMON == false {
|
||||
if err == nil {
|
||||
os.Exit(0)
|
||||
} else {
|
||||
os.Exit(2)
|
||||
}
|
||||
}
|
||||
if *DAEMON == false {
|
||||
if err == nil {
|
||||
os.Exit(0)
|
||||
} else {
|
||||
os.Exit(2)
|
||||
}
|
||||
}
|
||||
|
||||
sleepTime := time.Now().Unix() - startTime + w.Config.Interval
|
||||
if sleepTime > 0 {
|
||||
time.Sleep(time.Duration(sleepTime) * time.Second)
|
||||
}
|
||||
}
|
||||
sleepTime := time.Now().Unix() - startTime + w.Config.Interval
|
||||
if sleepTime > 0 {
|
||||
time.Sleep(time.Duration(sleepTime) * time.Second)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
180
weather.go
180
weather.go
|
@ -17,118 +17,118 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"time"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
influx "github.com/influxdata/influxdb1-client/v2"
|
||||
influx "github.com/influxdata/influxdb1-client/v2"
|
||||
)
|
||||
|
||||
// Weather is the main struct
|
||||
type Weather struct {
|
||||
Config Config
|
||||
WeatherDatas []WeatherData
|
||||
Config Config
|
||||
WeatherDatas []WeatherData
|
||||
}
|
||||
|
||||
// WeatherData contains weather data from openweathermap
|
||||
type WeatherData struct {
|
||||
City string `json:"name"`
|
||||
Main struct {
|
||||
Humidity int `json:"humidity"`
|
||||
Pressure int `json:"pressure"`
|
||||
Temperature float32 `json:"temp"`
|
||||
} `json:"main"`
|
||||
Clouds struct {
|
||||
All int `json:"all"`
|
||||
} `json:"clouds"`
|
||||
Rain struct {
|
||||
OneHour float32 `json:"1h"`
|
||||
TreeHours float32 `json:"3h"`
|
||||
} `json:"rain"`
|
||||
Snow struct {
|
||||
OneHour float32 `json:"1h"`
|
||||
TreeHours float32 `json:"3h"`
|
||||
} `json:"snow"`
|
||||
Wind struct {
|
||||
Speed float32 `json:"speed"`
|
||||
Direction int `json:"deg"`
|
||||
} `json:"Wind"`
|
||||
Sys struct {
|
||||
Country string `json:"country"`
|
||||
} `json:"sys"`
|
||||
City string `json:"name"`
|
||||
Main struct {
|
||||
Humidity int `json:"humidity"`
|
||||
Pressure int `json:"pressure"`
|
||||
Temperature float32 `json:"temp"`
|
||||
} `json:"main"`
|
||||
Clouds struct {
|
||||
All int `json:"all"`
|
||||
} `json:"clouds"`
|
||||
Rain struct {
|
||||
OneHour float32 `json:"1h"`
|
||||
TreeHours float32 `json:"3h"`
|
||||
} `json:"rain"`
|
||||
Snow struct {
|
||||
OneHour float32 `json:"1h"`
|
||||
TreeHours float32 `json:"3h"`
|
||||
} `json:"snow"`
|
||||
Wind struct {
|
||||
Speed float32 `json:"speed"`
|
||||
Direction int `json:"deg"`
|
||||
} `json:"Wind"`
|
||||
Sys struct {
|
||||
Country string `json:"country"`
|
||||
} `json:"sys"`
|
||||
}
|
||||
|
||||
// FetchData from OpenWeatherMap API
|
||||
func (w *Weather) FetchData() {
|
||||
for _, city := range w.Config.Cities {
|
||||
resp, err := http.Get(
|
||||
fmt.Sprintf(
|
||||
"%s/weather?q=%s&appid=%s&units=%s",
|
||||
URI,
|
||||
city,
|
||||
w.Config.OpenWeatherMap.APIKey,
|
||||
w.Config.OpenWeatherMap.Units,
|
||||
),
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Printf("%s", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
for _, city := range w.Config.Cities {
|
||||
resp, err := http.Get(
|
||||
fmt.Sprintf(
|
||||
"%s/weather?q=%s&appid=%s&units=%s",
|
||||
URI,
|
||||
city,
|
||||
w.Config.OpenWeatherMap.APIKey,
|
||||
w.Config.OpenWeatherMap.Units,
|
||||
),
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Printf("%s", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
fmt.Printf("%s", err)
|
||||
}
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
fmt.Printf("%s", err)
|
||||
}
|
||||
|
||||
weatherData := WeatherData{}
|
||||
json.Unmarshal(data, &weatherData)
|
||||
w.WeatherDatas = append(w.WeatherDatas, weatherData)
|
||||
weatherData := WeatherData{}
|
||||
json.Unmarshal(data, &weatherData)
|
||||
w.WeatherDatas = append(w.WeatherDatas, weatherData)
|
||||
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
}
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
||||
// SendToInfluxDB send data in influxdb
|
||||
func (w *Weather) SendToInfluxDB() error {
|
||||
conn, err := influx.NewHTTPClient(influx.HTTPConfig{
|
||||
Addr: w.Config.InfluxDB.URL,
|
||||
Username: w.Config.InfluxDB.Username,
|
||||
Password: w.Config.InfluxDB.Password,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer conn.Close()
|
||||
conn, err := influx.NewHTTPClient(influx.HTTPConfig{
|
||||
Addr: w.Config.InfluxDB.URL,
|
||||
Username: w.Config.InfluxDB.Username,
|
||||
Password: w.Config.InfluxDB.Password,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
bps, _ := influx.NewBatchPoints(
|
||||
influx.BatchPointsConfig{
|
||||
Database: w.Config.InfluxDB.Database,
|
||||
})
|
||||
bps, _ := influx.NewBatchPoints(
|
||||
influx.BatchPointsConfig{
|
||||
Database: w.Config.InfluxDB.Database,
|
||||
})
|
||||
|
||||
for _, weather := range w.WeatherDatas {
|
||||
tags := map[string]string{ "city": weather.City, "country": weather.Sys.Country }
|
||||
fields := map[string]interface{}{
|
||||
"temperature": weather.Main.Temperature,
|
||||
"humidity": weather.Main.Humidity,
|
||||
"pressure": weather.Main.Pressure,
|
||||
"clouds": weather.Clouds.All,
|
||||
"wind_speed": weather.Wind.Speed,
|
||||
"wind_direction": weather.Wind.Direction,
|
||||
"rain_1h": weather.Rain.OneHour,
|
||||
"rain_3h": weather.Rain.TreeHours,
|
||||
"snow_1h": weather.Snow.OneHour,
|
||||
"snow_3h": weather.Snow.TreeHours,
|
||||
}
|
||||
point, _ := influx.NewPoint(w.Config.InfluxDB.Measurement, tags, fields, time.Now())
|
||||
bps.AddPoint(point)
|
||||
}
|
||||
for _, weather := range w.WeatherDatas {
|
||||
tags := map[string]string{"city": weather.City, "country": weather.Sys.Country}
|
||||
fields := map[string]interface{}{
|
||||
"temperature": weather.Main.Temperature,
|
||||
"humidity": weather.Main.Humidity,
|
||||
"pressure": weather.Main.Pressure,
|
||||
"clouds": weather.Clouds.All,
|
||||
"wind_speed": weather.Wind.Speed,
|
||||
"wind_direction": weather.Wind.Direction,
|
||||
"rain_1h": weather.Rain.OneHour,
|
||||
"rain_3h": weather.Rain.TreeHours,
|
||||
"snow_1h": weather.Snow.OneHour,
|
||||
"snow_3h": weather.Snow.TreeHours,
|
||||
}
|
||||
point, _ := influx.NewPoint(w.Config.InfluxDB.Measurement, tags, fields, time.Now())
|
||||
bps.AddPoint(point)
|
||||
}
|
||||
|
||||
err = conn.Write(bps)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = conn.Write(bps)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue