135 lines
2.9 KiB
Go
135 lines
2.9 KiB
Go
package main
|
|
|
|
import (
|
|
_ "github.com/mattn/go-sqlite3"
|
|
)
|
|
|
|
import (
|
|
s "shroom_server/shroom_internals"
|
|
)
|
|
|
|
import (
|
|
"database/sql"
|
|
"embed"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/fs"
|
|
"log"
|
|
"net/http"
|
|
"time"
|
|
)
|
|
|
|
//go:embed static/*
|
|
var content embed.FS
|
|
|
|
type statusJson struct {
|
|
Connected bool `json:"connected"`
|
|
Humidifier bool `json:"humidifier"`
|
|
}
|
|
|
|
func dumpData(db *sql.DB, offset int64) func(http.ResponseWriter, *http.Request) {
|
|
return func(w http.ResponseWriter, _req *http.Request) {
|
|
now := time.Now().Unix()
|
|
t := now + offset
|
|
msg, err := s.GetRows(db, t)
|
|
if err != nil {
|
|
w.WriteHeader(500)
|
|
w.Write([]byte(err.Error()))
|
|
} else {
|
|
w.Write(msg)
|
|
}
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
db, err := sql.Open("sqlite3", "shrooms.db")
|
|
if err != nil {
|
|
log.Fatal("unable to open db ", err)
|
|
}
|
|
if err = db.Ping(); err != nil {
|
|
log.Fatal("unable to ping db ", err)
|
|
}
|
|
|
|
err = s.CreateTable(db)
|
|
if err != nil {
|
|
log.Fatal("unable to create table ", err)
|
|
}
|
|
|
|
status := s.ShroomStatus{
|
|
Wait: make(chan struct{}),
|
|
}
|
|
s.InitTcpServer(db, &status)
|
|
|
|
contentSub, err := fs.Sub(content, "static")
|
|
if err != nil {
|
|
log.Fatal("unable to use subdirectory of embedded fs: ", err)
|
|
}
|
|
|
|
dumpWeek := dumpData(db, -7*24*60*60)
|
|
dumpDay := dumpData(db, -24*60*60)
|
|
dumpHour := dumpData(db, -60*60)
|
|
dumpMinute := dumpData(db, -60)
|
|
|
|
lastPoint := func(w http.ResponseWriter, _req *http.Request) {
|
|
msg, err := s.LastTime(db)
|
|
if err != nil {
|
|
w.WriteHeader(500)
|
|
w.Write([]byte(err.Error()))
|
|
} else {
|
|
w.Write(msg)
|
|
}
|
|
}
|
|
|
|
getStatus := func(w http.ResponseWriter, _req *http.Request) {
|
|
status.RLock()
|
|
num_connections := status.NumConnections
|
|
humidifier := status.HumidifierOn
|
|
status.RUnlock()
|
|
s := statusJson{
|
|
Connected: num_connections > 0,
|
|
Humidifier: humidifier,
|
|
}
|
|
msg, err := json.Marshal(s)
|
|
if err != nil {
|
|
err = fmt.Errorf("unable to marshal json: %w", err)
|
|
w.WriteHeader(500)
|
|
w.Write([]byte(err.Error()))
|
|
} else {
|
|
w.Write(msg)
|
|
}
|
|
}
|
|
|
|
adminHandler := func(w http.ResponseWriter, req *http.Request) {
|
|
w.WriteHeader(500)
|
|
w.Write([]byte("unimplemented"))
|
|
// TODO
|
|
}
|
|
|
|
updateHandler := func(w http.ResponseWriter, req *http.Request) {
|
|
stillopen := true
|
|
for stillopen {
|
|
_, stillopen = <-status.Wait
|
|
}
|
|
w.Write([]byte("ok"))
|
|
}
|
|
|
|
http.Handle("/d/", http.StripPrefix("/d/", http.FileServer(http.Dir("./dev"))))
|
|
http.Handle("/", http.FileServer(http.FS(contentSub)))
|
|
http.HandleFunc("/api/last/week", dumpWeek)
|
|
http.HandleFunc("/api/last/day", dumpDay)
|
|
http.HandleFunc("/api/last/hour", dumpHour)
|
|
http.HandleFunc("/api/last/minute", dumpMinute)
|
|
http.HandleFunc("/api/latest", lastPoint)
|
|
http.HandleFunc("/api/status", getStatus)
|
|
http.HandleFunc("/api/admin", adminHandler)
|
|
http.HandleFunc("/api/update", updateHandler)
|
|
|
|
// TODO periodically clear old entries from the database
|
|
|
|
err = http.ListenAndServe("localhost:8080", nil)
|
|
if err != nil {
|
|
log.Fatal("unable to start server: ", err)
|
|
}
|
|
defer db.Close()
|
|
}
|