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

168 lines
3.6 KiB
Go

package main
import (
"automation/connect"
"automation/device"
"automation/integration/hue"
"automation/integration/kasa"
"automation/integration/mqtt"
"automation/integration/ntfy"
"automation/presence"
"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
}
var devices map[string]interface{}
// // @TODO Implement this for the other devices as well
// func GetDeviceKasa(name string) (*kasa.Kasa, error) {
// deviceGeneric, ok := devices[name]
// if !ok {
// return nil, fmt.Errorf("Device does not exist")
// }
// device, ok := deviceGeneric.(kasa.Kasa)
// if !ok {
// return nil, fmt.Errorf("Device is not a Kasa device")
// }
// return &device, nil
// }
// func SetupBindings(m *mqtt.MQTT) {
// m.AddHandler("zigbee2mqtt/living_room/audio_remote", func(_ paho.Client, msg paho.Message) {
// mixer, err := GetDeviceKasa("living_room/mixer")
// if err != nil {
// log.Println(err)
// return
// }
// speakers, err := GetDeviceKasa("living_room/speakers")
// if err != nil {
// log.Println(err)
// return
// }
// var message struct {
// Action string `json:"action"`
// }
// err = json.Unmarshal(msg.Payload(), &message)
// if err != nil {
// log.Println(err)
// return
// }
// if message.Action == "on" {
// if mixer.GetState() {
// mixer.SetState(false)
// speakers.SetState(false)
// } else {
// mixer.SetState(true)
// }
// } else if message.Action == "brightness_move_up" {
// if speakers.GetState() {
// speakers.SetState(false)
// } else {
// speakers.SetState(true)
// mixer.SetState(true)
// }
// }
// })
// }
func main() {
_ = godotenv.Load()
config := GetConfig()
devices = make(map[string]interface{})
var connect connect.Connect
// MQTT
connect.Client = mqtt.New(config.MQTT)
defer connect.Client.Disconnect(250)
// ntfy.sh
connect.Notify = ntfy.New(config.NTFY)
// Hue
connect.Hue = hue.Connect(config.Hue)
// Kasa
for name, ip := range config.Kasa.Outlets {
devices[name] = kasa.New(ip)
}
// Devices that we control and expose to google home
provider := device.NewProvider(config.Google, connect.Client)
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))
}
// Presence
p := presence.New(&connect)
defer p.Delete()
addr := ":8090"
srv := http.Server{
Addr: addr,
Handler: r,
}
log.Printf("Starting server on %s (PID: %d)\n", addr, os.Getpid())
srv.ListenAndServe()
}