This repository has been archived on 2023-08-29. You can view files and clone it, but cannot push or open issues or pull requests.
automation/main.go
Dreaded_X 9f4be2d76e
All checks were successful
continuous-integration/drone/push Build is passing
Implemented better config system
2022-11-16 05:20:59 +01:00

141 lines
2.8 KiB
Go

package main
import (
"automation/device"
"automation/integration/hue"
"automation/integration/kasa"
"automation/integration/mqtt"
"automation/integration/ntfy"
"automation/presence"
"fmt"
"log"
"net/http"
"os"
"github.com/gorilla/mux"
"github.com/joho/godotenv"
"github.com/kelseyhightower/envconfig"
"gopkg.in/yaml.v3"
)
type config struct {
Hue hue.Config `yaml:"hue"`
NTFY ntfy.Config `yaml:"ntfy"`
MQTT mqtt.Config `yaml:"mqtt"`
Kasa struct {
Outlets map[string]string `yaml:"outlets"`
} `yaml:"kasa"`
Computer map[string]struct {
MACAddress string `yaml:"mac"`
Room string `yaml:"room"`
Url string `yaml:"url"`
} `yaml:"computers"`
Google device.Config `yaml:"google"`
}
func GetConfig() config {
// First load the config from the yaml file
f, err := os.Open("config.yml")
if err != nil {
log.Fatalln("Failed to open config file", err)
}
defer f.Close()
var cfg config
decoder := yaml.NewDecoder(f)
err = decoder.Decode(&cfg)
if err != nil {
log.Fatalln("Failed to parse config file", err)
}
// Then load values from environment
// This can be used to either override the config or pass in secrets
err = envconfig.Process("", &cfg)
if err != nil {
log.Fatalln("Failed to parse environmet config", err)
}
return cfg
}
func main() {
_ = godotenv.Load()
config := GetConfig()
// MQTT
m := mqtt.Connect(config.MQTT)
defer m.Disconnect()
// Hue
h := hue.Connect(config.Hue)
// Kasa
kasaDevices := make(map[string]kasa.Kasa)
for name, ip := range config.Kasa.Outlets {
kasaDevices[name] = kasa.New(ip)
}
// ntfy.sh
n := ntfy.Connect(config.NTFY)
// Presence
p := presence.New()
m.AddHandler("automation/presence/+", p.PresenceHandler)
// Devices that we control and expose to google home
provider := device.NewProvider(config.Google, &m)
r := mux.NewRouter()
r.HandleFunc("/assistant", provider.Service.FullfillmentHandler)
for name, info := range config.Computer {
provider.AddDevice(device.NewComputer(info.MACAddress, name, info.Room, info.Url))
}
// Event loop
go func() {
fmt.Println("Starting event loop")
for {
select {
case present := <-p.Presence:
fmt.Printf("Presence: %t\n", present)
// Notify users of presence update
n.Presence(present)
// Set presence on the hue bridge
h.SetFlag(41, present)
if !present {
// Turn off all the devices that we manage ourselves
provider.TurnAllOff()
// Turn off kasa devices
for _, device := range kasaDevices {
device.SetState(false)
}
// @TODO Turn off nest thermostat
} else {
// @TODO Turn on the nest thermostat again
}
case <-h.Events:
break
}
}
}()
addr := ":8090"
srv := http.Server{
Addr: addr,
Handler: r,
}
log.Printf("Starting server on %s (PID: %d)\n", addr, os.Getpid())
srv.ListenAndServe()
}