homeservice/main.go

118 lines
2.8 KiB
Go
Raw Normal View History

2023-01-30 12:29:26 +00:00
package main
import (
"encoding/json"
2023-02-06 10:33:18 +00:00
"flag"
2023-01-30 12:29:26 +00:00
"log"
"net/http"
2023-01-30 14:54:49 +00:00
"sync"
"time"
2023-01-30 12:29:26 +00:00
2023-01-30 14:54:49 +00:00
mqtt "github.com/eclipse/paho.mqtt.golang"
2023-01-30 12:29:26 +00:00
)
2023-01-30 14:54:49 +00:00
type temperature struct {
Value float64 `json:"value"`
Unit string `json:"unit"`
Time time.Time `json:"time"`
Valid bool `json:"valid"`
2023-01-30 12:29:26 +00:00
}
var (
2023-01-30 14:54:49 +00:00
logger log.Logger = *log.Default()
2023-01-30 12:29:26 +00:00
2023-01-30 14:54:49 +00:00
sauna_mutex sync.Mutex
sauna_temperature = temperature{
Value: 0.0,
Unit: "°C",
2023-01-30 12:29:26 +00:00
}
)
2023-01-30 14:54:49 +00:00
var messagePubHandler mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) {
logger.Printf("Received message: %s from topic: %s\n", msg.Payload(), msg.Topic())
}
var saunaHandler mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) {
log.Printf("Received message: %s from topic: %s\n", msg.Payload(), msg.Topic())
sauna_mutex.Lock()
err := json.Unmarshal(msg.Payload(), &sauna_temperature)
sauna_temperature.Time = time.Now()
2023-01-30 12:29:26 +00:00
if err != nil {
sauna_temperature.Valid = false
sauna_mutex.Unlock()
2023-01-30 14:54:49 +00:00
logger.Print(err)
2023-01-30 12:29:26 +00:00
return
}
sauna_temperature.Valid = true
sauna_mutex.Unlock()
2023-01-30 12:29:26 +00:00
}
2023-01-30 14:54:49 +00:00
var connectHandler mqtt.OnConnectHandler = func(client mqtt.Client) {
logger.Println("Connected")
}
2023-01-30 12:29:26 +00:00
2023-01-30 14:54:49 +00:00
var connectLostHandler mqtt.ConnectionLostHandler = func(client mqtt.Client, err error) {
logger.Printf("Connect lost: %v", err)
2023-01-30 12:29:26 +00:00
}
2023-01-30 14:54:49 +00:00
func init() {
logger.SetPrefix("Homeservice: ")
}
func http_endpoint_sauna(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-type", "application/json; charset=utf-8;")
if r.Method == http.MethodGet {
sauna_mutex.Lock()
data, err := json.Marshal(sauna_temperature)
sauna_mutex.Unlock()
2023-01-30 12:29:26 +00:00
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
2023-01-30 14:54:49 +00:00
w.Write(json.RawMessage(`{"error": "cannot marshal object to json"}`))
} else {
w.WriteHeader(http.StatusOK)
w.Write(data)
2023-01-30 12:29:26 +00:00
}
} else {
w.WriteHeader(http.StatusMethodNotAllowed)
}
}
func main() {
2023-01-30 14:54:49 +00:00
logger.Println("starting")
2023-02-06 10:33:18 +00:00
var webui_path string
flag.StringVar(&webui_path, "d", "./build/webui", "Specify path to serve the web ui. Default is ./static")
2023-02-06 10:33:18 +00:00
flag.Parse()
2023-01-30 14:54:49 +00:00
// MQTT connection
opts := mqtt.NewClientOptions()
opts.AddBroker("tcp://nuc:1883")
opts.SetClientID("homeservice")
opts.SetDefaultPublishHandler(messagePubHandler)
opts.OnConnect = connectHandler
opts.OnConnectionLost = connectLostHandler
client := mqtt.NewClient(opts)
if token := client.Connect(); token.Wait() && token.Error() != nil {
panic(token.Error())
}
// MQTT subscribtion
topic := "sauna/temperature"
token := client.Subscribe(topic, 1, saunaHandler)
token.Wait()
logger.Printf("Subscribed to topic %s", topic)
2023-01-30 12:29:26 +00:00
// API routes
// Serve files from static folder
2023-02-06 10:33:18 +00:00
http.Handle("/", http.FileServer(http.Dir(webui_path)))
2023-01-30 12:29:26 +00:00
http.HandleFunc("/api/sauna", http_endpoint_sauna)
2023-01-30 12:29:26 +00:00
port := ":5000"
2023-01-30 14:54:49 +00:00
logger.Println("Server is running on port" + port)
2023-01-30 12:29:26 +00:00
// Start server on port specified above
2023-01-30 14:54:49 +00:00
logger.Fatal(http.ListenAndServe(port, nil))
2023-01-30 12:29:26 +00:00
}