-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added config, partial estacions API operations, basic skeleton for el…
…asticsearch example
- Loading branch information
Showing
13 changed files
with
8,031 additions
and
52 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
package meteocat | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"net/http" | ||
"strings" | ||
) | ||
|
||
// Coordenades struct holds georeference information of the stations | ||
type Coordenades struct { | ||
Latitud float64 `json:"latitud"` // Latitude expressed in decimal degrees. WSG84 reference system | ||
Longitud float64 `json:"Longitud"` // Longitude expressed in decimal degrees. WSG84 reference system | ||
} | ||
|
||
// Municipi struct holds information on which municipi is located the station. | ||
type Municipi struct { | ||
Codi string `json:"codi"` // INE code of the municipi | ||
Nom string `json:"nom"` // Name of the municipi | ||
} | ||
|
||
// Comarca struct holds information on which Comarca is located the station. | ||
type Comarca struct { | ||
Codi int `json:"codi"` // Comarca identification code | ||
Nom string `json:"nom"` // Name of the comarca | ||
} | ||
|
||
// Provincia struct holds information on which Provincia is located the station. | ||
type Provincia struct { | ||
Codi int `json:"codi"` // Provincia identification code | ||
Nom string `json:"nom"` // Name of the provincia | ||
} | ||
|
||
// Xarxa struct holds information on which Xarxa is located the station. The xarxa field | ||
// refers to the stations of the Network of Automatic Meteorological Stations (XEMA) of Catalonia | ||
type Xarxa struct { | ||
Codi int `json:"codi"` // Xarxa identification code | ||
Nom string `json:"nom"` // Name of the Network | ||
} | ||
|
||
// Aggregation of fields and structs to unmarshal the responses | ||
type MetadadesEstacions struct { | ||
Codi string `json:"codi"` // Identification code for each automatic weather station (EMA) | ||
Nom string `json:"nom"` // Name of the EMA | ||
Tipus string `json:"tipus"` // Type of station typically automatic | ||
Coordenades Coordenades `json:"coordenades"` // Georeference data of the station | ||
Emplacament string `json:"emplacament"` // Descriptive name of where the station is located e.g Planters Gusi, ctra. antiga de València, km 14 | ||
Altitud float64 `json:"altitud"` // Altitude in meters of the station above the sea level. | ||
Municipi Municipi `json:"municipi"` // Municipi | ||
Comarca Comarca `json:"comarca"` // Comarca | ||
Provincia Provincia `json:"provincia"` // Provincia | ||
Xarxa Xarxa `json:"xarxa"` // Network tipically XEMA | ||
Estats Estats `json:"estats"` | ||
} | ||
|
||
// Mesurades holds all the data representations to unmarshall the API responses | ||
type Estacions struct { | ||
MetadadesEstacions | ||
Key string | ||
CodiEstacio string // ? | ||
CodiVariable string // ? | ||
*Settings | ||
} | ||
|
||
// Returns a list of metadata from all stations. If settings are specified, filters by specified status and date | ||
// The API resource is /estacions/metadades?estat={estat}&data={data} where the | ||
// parameters `estat` and data optional. | ||
// Request example: https://api.meteo.cat/xema/v1/estacions/metadades?estat=ope&data=2017-03-27Z | ||
func (e *Estacions) StationsAll(p *Parameters) error { | ||
|
||
dataOk := ValidData(p.Data) | ||
|
||
if p.codiEstat != "" && dataOk == true { | ||
p.codiEstat = strings.ToLower(p.codiEstat) | ||
|
||
if ValidCodiEstat(p.codiEstat) { | ||
sFlag = true | ||
url = fmt.Sprintf(baseURL, fmt.Sprintf("/estacions/metadades?estat=%s&data=%s-%s-%sZ", p.codiEstat, p.Any, p.Mes, p.Dia)) | ||
} else { | ||
return errEstacioUnavailable | ||
} | ||
|
||
} else { | ||
url = fmt.Sprintf(baseURL, fmt.Sprintf("/estacions/metadades")) | ||
} | ||
|
||
req, err := http.NewRequest("GET", url, nil) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
req.Header.Add("X-Api-Key", e.Key) | ||
|
||
resp, err := e.client.Do(req) | ||
|
||
if err != nil { | ||
fmt.Println(err) | ||
return err | ||
} | ||
defer resp.Body.Close() | ||
if sFlag == true { | ||
if err = json.NewDecoder(resp.Body).Decode(&e.MetadadesEstacions); err != nil { | ||
return err | ||
} | ||
} else { | ||
if err = json.NewDecoder(resp.Body).Decode(&e.MetadadesEstacions); err != nil { | ||
return err | ||
} | ||
} | ||
// print status line and headers | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"github.com/kelseyhightower/envconfig" | ||
"github.com/oscaromeu/meteocat" | ||
"github.com/oscaromeu/meteocat/examples/elasticsearch/config" | ||
"github.com/sirupsen/logrus" | ||
"github.com/spf13/viper" | ||
"io/ioutil" | ||
"os" | ||
"path/filepath" | ||
"strconv" | ||
) | ||
|
||
// Entry point of the app | ||
|
||
var ( | ||
log = logrus.New() | ||
appdir = os.Getenv("PWD") | ||
homeDir string | ||
pidFile string | ||
logDir = filepath.Join(appdir, "log") | ||
confDir = filepath.Join(appdir, "config") | ||
downloadDir = filepath.Join(appdir, "download") | ||
dataDir = confDir | ||
configFile = filepath.Join(confDir, "conf.yaml") | ||
// MainConfig has all configuration | ||
MainConfig config.Config | ||
) | ||
|
||
func writePIDFile() { | ||
if pidFile == "" { | ||
return | ||
} | ||
|
||
// Ensure the required directory structure exists. | ||
err := os.MkdirAll(filepath.Dir(pidFile), 0700) | ||
if err != nil { | ||
log.Fatal(3, "Failed to verify pid directory", err) | ||
} | ||
|
||
// Retrieve the PID and write it. | ||
pid := strconv.Itoa(os.Getpid()) | ||
if err := ioutil.WriteFile(pidFile, []byte(pid), 0644); err != nil { | ||
log.Fatal(3, "Failed to write pidfile", err) | ||
} | ||
} | ||
|
||
func init() { | ||
|
||
customFormatter := new(logrus.TextFormatter) | ||
customFormatter.TimestampFormat = "2006-01-02 15:04:05" | ||
log.Formatter = customFormatter | ||
customFormatter.FullTimestamp = true | ||
|
||
//log.SetOutput(os.Stdout) | ||
v := viper.New() | ||
|
||
// now load up config settings | ||
if _, err := os.Stat(configFile); err == nil { | ||
v.SetConfigFile(configFile) | ||
confDir = filepath.Dir(configFile) | ||
} else { | ||
v.SetConfigName("conf") | ||
v.SetConfigType("yaml") | ||
v.AddConfigPath("../config") | ||
v.AddConfigPath("../../config") | ||
v.AddConfigPath(".") | ||
} | ||
err := v.ReadInConfig() | ||
if err != nil { | ||
log.Errorf("Fatal error config file: %s \n", err) | ||
os.Exit(1) | ||
} | ||
err = v.Unmarshal(&MainConfig) | ||
if err != nil { | ||
log.Errorf("Fatal error config file: %s \n", err) | ||
os.Exit(1) | ||
} | ||
log.Infof("CONFIG FROM FILE : %+v", &MainConfig) | ||
|
||
//parse config with environtment vars | ||
|
||
//envConf := &config.Config{} | ||
|
||
err = envconfig.Process("M_", &MainConfig) | ||
if err != nil { | ||
log.Warnf("Some error happened when trying to read config from env: %s", err) | ||
} | ||
//log.Infof("CONFIG FROM ENV : %+v", envConf) | ||
|
||
//mergo.MergeWithOverwrite(&agent.MainConfig, envConf) | ||
|
||
log.Infof("CONFIG AFTER MERGE : %+v", &MainConfig) | ||
// Setting defaults | ||
|
||
cfg := &MainConfig | ||
|
||
if cfg.General.LogMode != "file" { | ||
//default if not set | ||
log.Out = os.Stdout | ||
|
||
} else { | ||
if len(cfg.General.LogDir) > 0 { | ||
logDir = cfg.General.LogDir | ||
os.Mkdir(logDir, 0755) | ||
//Log output | ||
f, _ := os.OpenFile(logDir+"/es_meteocat.log", os.O_APPEND|os.O_CREATE|os.O_RDWR, 0644) | ||
log.Out = f | ||
} | ||
} | ||
if len(cfg.General.LogLevel) > 0 { | ||
l, _ := logrus.ParseLevel(cfg.General.LogLevel) | ||
log.Level = l | ||
} | ||
|
||
if len(cfg.General.HomeDir) > 0 { | ||
homeDir = cfg.General.HomeDir | ||
} | ||
|
||
log.Debugf("MAINCONFIG LOAD %#+v", cfg) | ||
fmt.Println("") | ||
|
||
} | ||
|
||
func main() { | ||
|
||
// Load Logger settings for other packages. These packages will inherit the log config defined in main | ||
config.SetLogger(log) | ||
|
||
d, err := meteocat.NewMesurades(MainConfig.General.ApiKey) | ||
if err != nil { | ||
log.Fatalln(err) | ||
} | ||
|
||
if meteocat.CheckAPIKeyExists(d.Key) == false { | ||
fmt.Println("ApiKey is not set. ") | ||
} | ||
|
||
data := meteocat.Data{ | ||
Any: "2021", | ||
Mes: "01", | ||
Dia: "06", | ||
} | ||
params, _ := meteocat.NewParameters( | ||
meteocat.OptionCodiVariable("32"), | ||
meteocat.OptionData(data), | ||
) | ||
|
||
// Call MeasurementByDay Method | ||
d.MeasurementLast(params) | ||
|
||
for _,v := range d.Measurements { | ||
fmt.Println(v) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
general: | ||
# log directory set the Directory path for each device individual log | ||
# could be set also with M_LOGDIR env var,default $CWD/log | ||
log_dir: "./log" | ||
# logLevel set de main process log level | ||
# valid values: panic,fatal,error,warn,info,debug | ||
# could also be set with M_LOGLEVEL env var, default info if not set | ||
log_level: "info" | ||
# Log mode could be "file/console" default "console" ir not set | ||
# could be set also with M_LOGMODE env var | ||
log_mode: "console" | ||
#home_dir: | ||
temporal_path: "/tmp" | ||
# could also be set M_ES_USERNAME env var | ||
es_user: "Admin" | ||
# could also be set M_ES_PASSWORD env var | ||
es_password: "Admin" | ||
# could also be set M_ES_SERVER env var | ||
es_server: "localhost" | ||
# could also be set with M_API_KEY | ||
api_key: "api_key" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package config | ||
|
||
import ( | ||
"github.com/pkg/errors" | ||
"github.com/sirupsen/logrus" | ||
"github.com/spf13/viper" | ||
"strings" | ||
) | ||
|
||
var ( | ||
|
||
//Log the Logger | ||
log *logrus.Logger | ||
) | ||
|
||
|
||
|
||
// ReadEnv reads the environmental variable associated with a given key function paramater | ||
func ReadEnv(key string) string { | ||
|
||
v := viper.New() | ||
|
||
// SetEnvPrefix defines a prefix that ENVIRONMENT variables will use. | ||
// E.g. In this case the prefix is "gs", the env registry will look for env | ||
// variables that start with "GS_". To import a template to a zabbix instance we must set the | ||
// following variables: ZABBIX_PASSWORD, ZABBIX_SERVER, ZABBIX_USERNAME | ||
v.SetEnvPrefix("gs") | ||
//v.SetDefault("LOG_DEBUG", false) | ||
|
||
// Make sure that ENV.VAR => ENV_VAR | ||
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) | ||
|
||
// Enable VIPER to read Environment Variables | ||
v.AutomaticEnv() | ||
|
||
// AllowEmptyEnv tells Viper to consider set, | ||
// but empty environment variables as valid values instead of falling back. | ||
v.AllowEmptyEnv(true) | ||
|
||
// viper.Get() returns an empty interface{} | ||
// to get the underlying type of the key, | ||
// we have to do the type assertion, we know the underlying value is string | ||
// if we type assert to other type it will throw an error | ||
value, err := v.Get(key).(string) | ||
|
||
if !err { | ||
err := errors.Errorf("Failed to get the environmental variable %q", value) | ||
log.Error(err) | ||
} | ||
return value | ||
} | ||
|
||
//// Load reads the config/config.yaml file | ||
//func Load() (*Config, error) { | ||
// | ||
// v := viper.New() | ||
// // Set the file name of the configurations file | ||
// v.SetConfigName("conf") | ||
// | ||
// // Set the path to look for the configurations file | ||
// v.AddConfigPath("../../config") | ||
// | ||
// // Enable VIPER to read Environment Variables | ||
// v.AutomaticEnv() | ||
// | ||
// v.SetConfigType("yaml") | ||
// //var configuration Configurations | ||
// | ||
// var conf Config | ||
// | ||
// if err := v.ReadInConfig(); err != nil { | ||
// return nil, errors.Wrapf(err, "Error reading config file") | ||
// } | ||
// | ||
// err := v.Unmarshal(&conf) | ||
// if err != nil { | ||
// return nil, errors.Wrapf(err, "Unable to decode into struct, %q", conf) | ||
// } | ||
// return &conf, err | ||
// | ||
//} | ||
|
||
// SetLogger set the output log | ||
func SetLogger(l *logrus.Logger) { | ||
log = l | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package config | ||
|
||
// GeneralConfig has miscellaneous configuration options | ||
type GeneralConfig struct { | ||
LogDir string `mapstructure:"log_dir" envconfig:"M_LOGDIR"` | ||
LogLevel string `mapstructure:"log_level" envconfig:"M_LOGLEVEL"` | ||
LogMode string `mapstructure:"log_mode" envconfig:"M_LOGMODE"` | ||
HomeDir string `mapstructure:"home_dir" envconfig:"M_HOMEDIR"` | ||
TemporalPath string `mapstructure:"temporal_path" envconfig:"M_TEMPORAL_PATH"` | ||
ESUser string `mapstructure:"user" envconfig:"M_ES_USERNAME"` | ||
ESPassword string `mapstructure:"password" envconfig:"M_ES_PASSWORD"` | ||
ESServer string `mapstructure:"password" envconfig:"M_ES_SERVER"` | ||
ApiKey string `mapstructure:"api_key" envconfig:"M_API_KEY"` | ||
} | ||
|
||
|
||
type Config struct { | ||
General GeneralConfig `mapstructure:"general"` | ||
} |
Oops, something went wrong.