Add gateway and daemon boilerplate
This commit is contained in:
parent
bcb15b75e8
commit
72b0a690a6
|
@ -0,0 +1,93 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"git.netflux.io/rob/solar-toolkit/inverter"
|
||||
)
|
||||
|
||||
const (
|
||||
httpUserAgent = "solar-toolkit (git.netflux.io)"
|
||||
httpTimeout = time.Second * 5
|
||||
)
|
||||
|
||||
func main() {
|
||||
var (
|
||||
inverterAddr string
|
||||
gatewayEndpoint string
|
||||
gatewayUsername string
|
||||
gatewayPassword string
|
||||
pollInterval time.Duration
|
||||
)
|
||||
|
||||
flag.StringVar(&inverterAddr, "inverter-addr", "", "IP+port of solar inverter")
|
||||
flag.StringVar(&gatewayEndpoint, "endpoint", "", "URL to post metrics to")
|
||||
flag.StringVar(&gatewayUsername, "username", "", "HTTP basic auth username")
|
||||
flag.StringVar(&gatewayPassword, "password", "", "HTTP basic auth password")
|
||||
flag.DurationVar(&pollInterval, "pollInterval", time.Minute, "Poll interval, example: 60s")
|
||||
flag.Parse()
|
||||
|
||||
if gatewayEndpoint == "" {
|
||||
flag.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
conn, err := net.Dial("udp", inverterAddr)
|
||||
if err != nil {
|
||||
log.Fatalf("error dialing: %s", err)
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
var inv inverter.ET
|
||||
|
||||
ticker := time.NewTicker(pollInterval)
|
||||
defer ticker.Stop()
|
||||
|
||||
client := http.Client{Timeout: httpTimeout}
|
||||
|
||||
for ; true; <-ticker.C {
|
||||
runtimeData, err := inv.RuntimeData(context.Background(), conn)
|
||||
if err != nil {
|
||||
log.Printf("error fetching runtime data: %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
reqBody, err := json.Marshal(runtimeData)
|
||||
if err != nil {
|
||||
log.Printf("error encoding runtime data: %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
req, err := http.NewRequest(http.MethodPost, gatewayEndpoint, bytes.NewReader(reqBody))
|
||||
if err != nil {
|
||||
log.Printf("error building request: %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
req.Header.Set("content-type", "application/json")
|
||||
req.Header.Set("user-agent", httpUserAgent)
|
||||
if gatewayUsername != "" && gatewayPassword != "" {
|
||||
req.SetBasicAuth(gatewayUsername, gatewayPassword)
|
||||
}
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
log.Printf("error sending request: %s", err)
|
||||
continue
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
log.Printf("unexpected HTTP response code: %d", resp.StatusCode)
|
||||
continue
|
||||
}
|
||||
|
||||
log.Printf("Sent: %+v", runtimeData)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"git.netflux.io/rob/solar-toolkit/gateway/handler"
|
||||
"git.netflux.io/rob/solar-toolkit/gateway/store"
|
||||
"github.com/jmoiron/sqlx"
|
||||
_ "github.com/lib/pq"
|
||||
)
|
||||
|
||||
const defaultBindAddr = ":8888"
|
||||
|
||||
func main() {
|
||||
databaseURL := os.Getenv("DATABASE_URL")
|
||||
if databaseURL == "" {
|
||||
log.Fatal("missing configuration DATABASE_URL")
|
||||
}
|
||||
|
||||
bindAddr := os.Getenv("BIND_ADDR")
|
||||
if bindAddr == "" {
|
||||
bindAddr = defaultBindAddr
|
||||
}
|
||||
|
||||
db, err := sqlx.Connect("postgres", databaseURL)
|
||||
if err != nil {
|
||||
log.Fatalf("could not connect to database: %s", err)
|
||||
}
|
||||
|
||||
store := store.NewSQL(db)
|
||||
handler := handler.NewHandler(store)
|
||||
srv := http.Server{
|
||||
ReadTimeout: time.Second * 3,
|
||||
WriteTimeout: time.Second * 3,
|
||||
Handler: handler,
|
||||
Addr: bindAddr,
|
||||
}
|
||||
|
||||
log.Printf("Listening on %s...", bindAddr)
|
||||
if err := srv.ListenAndServe(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"git.netflux.io/rob/solar-toolkit/inverter"
|
||||
)
|
||||
|
||||
type Store interface {
|
||||
InsertETRuntimeData(*inverter.ETRuntimeData) error
|
||||
}
|
||||
|
||||
type Handler struct {
|
||||
store Store
|
||||
}
|
||||
|
||||
func NewHandler(store Store) *Handler { return &Handler{store: store} }
|
||||
|
||||
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package store
|
||||
|
||||
import (
|
||||
"git.netflux.io/rob/solar-toolkit/inverter"
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
|
||||
type PostgresStore struct {
|
||||
db *sqlx.DB
|
||||
}
|
||||
|
||||
func NewSQL(db *sqlx.DB) *PostgresStore {
|
||||
return &PostgresStore{db: db}
|
||||
}
|
||||
|
||||
func (s *PostgresStore) InsertETRuntimeData(runtimeData *inverter.ETRuntimeData) error {
|
||||
return nil
|
||||
}
|
2
go.mod
2
go.mod
|
@ -3,6 +3,8 @@ module git.netflux.io/rob/solar-toolkit
|
|||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/jmoiron/sqlx v1.3.5
|
||||
github.com/lib/pq v1.10.6
|
||||
github.com/stretchr/testify v1.8.0
|
||||
golang.org/x/exp v0.0.0-20220706164943-b4a6d9510983
|
||||
)
|
||||
|
|
9
go.sum
9
go.sum
|
@ -1,6 +1,15 @@
|
|||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g=
|
||||
github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.10.6 h1:jbk+ZieJ0D7EVGJYpL9QTz7/YW6UHbmdnZWYyK5cdBs=
|
||||
github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg=
|
||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
|
|
Loading…
Reference in New Issue