All devices are now stored in a central map, part of large refactor
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
6368fce40d
commit
01b2d492ba
|
@ -59,6 +59,10 @@ func (c *computer) GetID() string {
|
||||||
return c.macAddress
|
return c.macAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *computer) GetName() string {
|
||||||
|
return c.name
|
||||||
|
}
|
||||||
|
|
||||||
func (c *computer) SetState(state bool) {
|
func (c *computer) SetState(state bool) {
|
||||||
if state {
|
if state {
|
||||||
http.Get(c.url)
|
http.Get(c.url)
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type kettle struct {
|
type kettle struct {
|
||||||
Info DeviceInfo
|
info DeviceInfo
|
||||||
client paho.Client
|
client paho.Client
|
||||||
updated chan bool
|
updated chan bool
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ func (k *kettle) timerFunc() {
|
||||||
select {
|
select {
|
||||||
case <- k.timer.C:
|
case <- k.timer.C:
|
||||||
log.Println("Turning kettle automatically off")
|
log.Println("Turning kettle automatically off")
|
||||||
if token := k.client.Publish(fmt.Sprintf("zigbee2mqtt/%s/set", k.Info.FriendlyName), 1, false, `{"state": "OFF"}`); token.Wait() && token.Error() != nil {
|
if token := k.client.Publish(fmt.Sprintf("zigbee2mqtt/%s/set", k.info.FriendlyName), 1, false, `{"state": "OFF"}`); token.Wait() && token.Error() != nil {
|
||||||
log.Println(token.Error())
|
log.Println(token.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,14 +79,14 @@ func (k *kettle) Delete() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewKettle(info DeviceInfo, client paho.Client, s *google.Service) *kettle {
|
func NewKettle(info DeviceInfo, client paho.Client, s *google.Service) *kettle {
|
||||||
k := &kettle{Info: info, client: client, updated: make(chan bool, 1), timerLength: 5 * time.Minute, stop: make(chan interface{})}
|
k := &kettle{info: info, client: client, updated: make(chan bool, 1), timerLength: 5 * time.Minute, stop: make(chan interface{})}
|
||||||
k.timer = time.NewTimer(k.timerLength)
|
k.timer = time.NewTimer(k.timerLength)
|
||||||
k.timer.Stop()
|
k.timer.Stop()
|
||||||
|
|
||||||
// Start function
|
// Start function
|
||||||
go k.timerFunc()
|
go k.timerFunc()
|
||||||
|
|
||||||
if token := k.client.Subscribe(fmt.Sprintf("zigbee2mqtt/%s", k.Info.FriendlyName), 1, k.stateHandler); token.Wait() && token.Error() != nil {
|
if token := k.client.Subscribe(fmt.Sprintf("zigbee2mqtt/%s", k.info.FriendlyName), 1, k.stateHandler); token.Wait() && token.Error() != nil {
|
||||||
log.Println(token.Error())
|
log.Println(token.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ func (k *kettle) Sync() *google.Device {
|
||||||
device := google.NewDevice(k.GetID(), google.TypeKettle)
|
device := google.NewDevice(k.GetID(), google.TypeKettle)
|
||||||
device.AddOnOffTrait(false, false)
|
device.AddOnOffTrait(false, false)
|
||||||
|
|
||||||
s := strings.Split(k.Info.FriendlyName, "/")
|
s := strings.Split(k.info.FriendlyName, "/")
|
||||||
room := ""
|
room := ""
|
||||||
name := s[0]
|
name := s[0]
|
||||||
if len(s) > 1 {
|
if len(s) > 1 {
|
||||||
|
@ -122,9 +122,9 @@ func (k *kettle) Sync() *google.Device {
|
||||||
}
|
}
|
||||||
|
|
||||||
device.DeviceInfo = google.DeviceInfo{
|
device.DeviceInfo = google.DeviceInfo{
|
||||||
Manufacturer: k.Info.Manufacturer,
|
Manufacturer: k.info.Manufacturer,
|
||||||
Model: k.Info.ModelID,
|
Model: k.info.ModelID,
|
||||||
SwVersion: k.Info.SoftwareBuildID,
|
SwVersion: k.info.SoftwareBuildID,
|
||||||
}
|
}
|
||||||
|
|
||||||
return device
|
return device
|
||||||
|
@ -180,7 +180,15 @@ func (k *kettle) Execute(execution google.Execution, updatedState *google.Device
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k *kettle) GetID() string {
|
func (k *kettle) GetID() string {
|
||||||
return k.Info.IEEEAdress
|
return k.info.IEEEAdress
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k *kettle) GetName() string {
|
||||||
|
return k.info.FriendlyName
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k *kettle) GetDeviceInfo() DeviceInfo {
|
||||||
|
return k.info
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k *kettle) SetState(state bool) {
|
func (k *kettle) SetState(state bool) {
|
||||||
|
@ -189,7 +197,8 @@ func (k *kettle) SetState(state bool) {
|
||||||
msg = "ON"
|
msg = "ON"
|
||||||
}
|
}
|
||||||
|
|
||||||
if token := k.client.Publish(fmt.Sprintf("zigbee2mqtt/%s/set", k.Info.FriendlyName), 1, false, fmt.Sprintf(`{ "state": "%s" }`, msg)); token.Wait() && token.Error() != nil {
|
if token := k.client.Publish(fmt.Sprintf("zigbee2mqtt/%s/set", k.info.FriendlyName), 1, false, fmt.Sprintf(`{ "state": "%s" }`, msg)); token.Wait() && token.Error() != nil {
|
||||||
log.Println(token.Error())
|
log.Println(token.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,11 @@ package device
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"automation/integration/google"
|
"automation/integration/google"
|
||||||
|
"automation/integration/kasa"
|
||||||
"context"
|
"context"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/kr/pretty"
|
"github.com/kr/pretty"
|
||||||
|
@ -14,6 +16,74 @@ import (
|
||||||
paho "github.com/eclipse/paho.mqtt.golang"
|
paho "github.com/eclipse/paho.mqtt.golang"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type BaseDevice interface {
|
||||||
|
GetName() string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Devices struct {
|
||||||
|
Devices map[string]interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDevices() *Devices {
|
||||||
|
return &Devices{Devices: make(map[string]interface{})}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Devices) GetGoogleDevices() map[string]google.DeviceInterface {
|
||||||
|
devices := make(map[string]google.DeviceInterface)
|
||||||
|
|
||||||
|
for _, device := range d.Devices {
|
||||||
|
if gd, ok := device.(google.DeviceInterface); ok {
|
||||||
|
// Instead of using name we use the internal ID for google, that way devices can freely be renamed without causing issues with google home
|
||||||
|
devices[gd.GetID()] = gd
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return devices
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Devices) GetGoogleDevice(name string) (google.DeviceInterface, error) {
|
||||||
|
device, ok := d.GetGoogleDevices()[name]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("Device does not exist")
|
||||||
|
}
|
||||||
|
|
||||||
|
return device, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Devices) GetZigbeeDevices() map[string]ZigbeeDevice {
|
||||||
|
devices := make(map[string]ZigbeeDevice)
|
||||||
|
|
||||||
|
for name, device := range d.Devices {
|
||||||
|
if zd, ok := device.(ZigbeeDevice); ok {
|
||||||
|
devices[name] = zd
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return devices
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Devices) GetKasaDevices() map[string]*kasa.Kasa {
|
||||||
|
devices := make(map[string]*kasa.Kasa)
|
||||||
|
|
||||||
|
for _, device := range d.Devices {
|
||||||
|
if gd, ok := device.(*kasa.Kasa); ok {
|
||||||
|
// Instead of using name we use the internal ID for google, that way devices can freely be renamed without causing issues with google home
|
||||||
|
devices[gd.GetName()] = gd
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return devices
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Devices) GetKasaDevice(name string) (*kasa.Kasa, error) {
|
||||||
|
device, ok := d.GetKasaDevices()[name]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("Device does not exist")
|
||||||
|
}
|
||||||
|
|
||||||
|
return device, nil
|
||||||
|
}
|
||||||
|
|
||||||
type DeviceInfo struct {
|
type DeviceInfo struct {
|
||||||
IEEEAdress string `json:"ieee_address"`
|
IEEEAdress string `json:"ieee_address"`
|
||||||
FriendlyName string `json:"friendly_name"`
|
FriendlyName string `json:"friendly_name"`
|
||||||
|
@ -23,6 +93,11 @@ type DeviceInfo struct {
|
||||||
SoftwareBuildID string `json:"software_build_id"`
|
SoftwareBuildID string `json:"software_build_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ZigbeeDevice interface {
|
||||||
|
GetDeviceInfo() DeviceInfo
|
||||||
|
SetState(state bool)
|
||||||
|
}
|
||||||
|
|
||||||
type DeviceInterface interface {
|
type DeviceInterface interface {
|
||||||
google.DeviceInterface
|
google.DeviceInterface
|
||||||
SetState(state bool)
|
SetState(state bool)
|
||||||
|
@ -32,8 +107,7 @@ type Provider struct {
|
||||||
Service *google.Service
|
Service *google.Service
|
||||||
userID string
|
userID string
|
||||||
|
|
||||||
devices map[string]DeviceInterface
|
Devices *Devices
|
||||||
manualDevices map[string]DeviceInterface
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type credentials []byte
|
type credentials []byte
|
||||||
|
@ -56,15 +130,17 @@ func (p *Provider) devicesHandler(client paho.Client, msg paho.Message) {
|
||||||
log.Println("zigbee2mqtt devices:")
|
log.Println("zigbee2mqtt devices:")
|
||||||
pretty.Logln(devices)
|
pretty.Logln(devices)
|
||||||
|
|
||||||
// Remove all automatically added devices
|
for name := range p.Devices.GetZigbeeDevices() {
|
||||||
p.devices = p.manualDevices
|
// Delete all zigbee devices from the device list
|
||||||
|
delete(p.Devices.Devices, name)
|
||||||
|
}
|
||||||
|
|
||||||
for _, device := range devices {
|
for _, device := range devices {
|
||||||
switch device.Description {
|
switch device.Description {
|
||||||
case "Kettle":
|
case "Kettle":
|
||||||
kettle := NewKettle(device, client, p.Service)
|
kettle := NewKettle(device, client, p.Service)
|
||||||
p.devices[device.IEEEAdress] = kettle
|
p.Devices.Devices[kettle.GetDeviceInfo().FriendlyName] = kettle
|
||||||
log.Printf("Added Kettle (%s) %s\n", device.IEEEAdress, device.FriendlyName)
|
log.Printf("Added Kettle (%s) %s\n", kettle.GetDeviceInfo().IEEEAdress, kettle.GetDeviceInfo().FriendlyName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +149,7 @@ func (p *Provider) devicesHandler(client paho.Client, msg paho.Message) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewProvider(config Config, client paho.Client) *Provider {
|
func NewProvider(config Config, client paho.Client) *Provider {
|
||||||
provider := &Provider{userID: "Dreaded_X", devices: make(map[string]DeviceInterface), manualDevices: make(map[string]DeviceInterface)}
|
provider := &Provider{userID: "Dreaded_X", Devices: NewDevices()}
|
||||||
|
|
||||||
homegraphService, err := homegraph.NewService(context.Background(), option.WithCredentialsJSON(config.Credentials))
|
homegraphService, err := homegraph.NewService(context.Background(), option.WithCredentialsJSON(config.Credentials))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -89,15 +165,14 @@ func NewProvider(config Config, client paho.Client) *Provider {
|
||||||
return provider
|
return provider
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Provider) AddDevice(device DeviceInterface) {
|
func (p *Provider) AddDevice(device BaseDevice) {
|
||||||
p.devices[device.GetID()] = device
|
p.Devices.Devices[device.GetName()] = device
|
||||||
p.manualDevices[device.GetID()] = device
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Provider) Sync(_ context.Context, _ string) ([]*google.Device, error) {
|
func (p *Provider) Sync(_ context.Context, _ string) ([]*google.Device, error) {
|
||||||
var devices []*google.Device
|
var devices []*google.Device
|
||||||
|
|
||||||
for _, device := range p.devices {
|
for _, device := range p.Devices.GetGoogleDevices() {
|
||||||
devices = append(devices, device.Sync())
|
devices = append(devices, device.Sync())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,10 +183,10 @@ func (p *Provider) Query(_ context.Context, _ string, handles []google.DeviceHan
|
||||||
states := make(map[string]google.DeviceState)
|
states := make(map[string]google.DeviceState)
|
||||||
|
|
||||||
for _, handle := range handles {
|
for _, handle := range handles {
|
||||||
if device, found := p.devices[handle.ID]; found {
|
if device, err := p.Devices.GetGoogleDevice(handle.ID); err == nil {
|
||||||
states[handle.ID] = device.Query()
|
states[handle.ID] = device.Query()
|
||||||
} else {
|
} else {
|
||||||
log.Printf("Device (%s) not found\n", handle.ID)
|
log.Println(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,11 +202,11 @@ func (p *Provider) Execute(_ context.Context, _ string, commands []google.Comman
|
||||||
for _, command := range commands {
|
for _, command := range commands {
|
||||||
for _, execution := range command.Execution {
|
for _, execution := range command.Execution {
|
||||||
for _, handle := range command.Devices {
|
for _, handle := range command.Devices {
|
||||||
if device, found := p.devices[handle.ID]; found {
|
if device, err := p.Devices.GetGoogleDevice(handle.ID); err == nil {
|
||||||
errCode, online := device.Execute(execution, &resp.UpdatedState)
|
errCode, online := device.Execute(execution, &resp.UpdatedState)
|
||||||
|
|
||||||
// Update the state
|
// Update the state
|
||||||
p.devices[handle.ID] = device
|
p.Devices.Devices[handle.ID] = device
|
||||||
if !online {
|
if !online {
|
||||||
resp.OfflineDevices = append(resp.OfflineDevices, handle.ID)
|
resp.OfflineDevices = append(resp.OfflineDevices, handle.ID)
|
||||||
} else if len(errCode) == 0 {
|
} else if len(errCode) == 0 {
|
||||||
|
@ -142,7 +217,7 @@ func (p *Provider) Execute(_ context.Context, _ string, commands []google.Comman
|
||||||
resp.FailedDevices[errCode] = e
|
resp.FailedDevices[errCode] = e
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Printf("Device (%s) not found\n", handle.ID)
|
log.Println(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -150,9 +225,3 @@ func (p *Provider) Execute(_ context.Context, _ string, commands []google.Comman
|
||||||
|
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Provider) TurnAllOff() {
|
|
||||||
for _, device := range p.devices {
|
|
||||||
device.SetState(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -47,11 +47,12 @@ func decrypt(data []byte) ([]byte, error) {
|
||||||
|
|
||||||
|
|
||||||
type Kasa struct {
|
type Kasa struct {
|
||||||
|
name string
|
||||||
ip string
|
ip string
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(ip string) Kasa {
|
func New(name string, ip string) *Kasa {
|
||||||
return Kasa{ip}
|
return &Kasa{name, ip}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (kasa *Kasa) sendCmd(cmd cmd) (reply, error) {
|
func (kasa *Kasa) sendCmd(cmd cmd) (reply, error) {
|
||||||
|
@ -130,3 +131,7 @@ func (kasa *Kasa) GetState() bool {
|
||||||
return reply.System.GetSysinfo.RelayState == 1
|
return reply.System.GetSysinfo.RelayState == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (kasa *Kasa) GetName() string {
|
||||||
|
return kasa.name
|
||||||
|
}
|
||||||
|
|
||||||
|
|
112
main.go
112
main.go
|
@ -7,6 +7,7 @@ import (
|
||||||
"automation/integration/mqtt"
|
"automation/integration/mqtt"
|
||||||
"automation/integration/ntfy"
|
"automation/integration/ntfy"
|
||||||
"automation/presence"
|
"automation/presence"
|
||||||
|
"encoding/json"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
@ -15,6 +16,8 @@ import (
|
||||||
"github.com/joho/godotenv"
|
"github.com/joho/godotenv"
|
||||||
"github.com/kelseyhightower/envconfig"
|
"github.com/kelseyhightower/envconfig"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
|
|
||||||
|
paho "github.com/eclipse/paho.mqtt.golang"
|
||||||
)
|
)
|
||||||
|
|
||||||
type config struct {
|
type config struct {
|
||||||
|
@ -73,8 +76,6 @@ func GetConfig() config {
|
||||||
return cfg
|
return cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
var devices map[string]interface{}
|
|
||||||
|
|
||||||
// // @TODO Implement this for the other devices as well
|
// // @TODO Implement this for the other devices as well
|
||||||
// func GetDeviceKasa(name string) (*kasa.Kasa, error) {
|
// func GetDeviceKasa(name string) (*kasa.Kasa, error) {
|
||||||
// deviceGeneric, ok := devices[name]
|
// deviceGeneric, ok := devices[name]
|
||||||
|
@ -90,79 +91,88 @@ var devices map[string]interface{}
|
||||||
// return &device, nil
|
// return &device, nil
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// func SetupBindings(m *mqtt.MQTT) {
|
func SetupBindings(client paho.Client, p *device.Provider) {
|
||||||
// m.AddHandler("zigbee2mqtt/living_room/audio_remote", func(_ paho.Client, msg paho.Message) {
|
var handler paho.MessageHandler = func(client paho.Client, msg paho.Message) {
|
||||||
// mixer, err := GetDeviceKasa("living_room/mixer")
|
mixer, err := p.Devices.GetKasaDevice("living_room/mixer")
|
||||||
// if err != nil {
|
if err != nil {
|
||||||
// log.Println(err)
|
log.Println(err)
|
||||||
// return
|
return
|
||||||
// }
|
}
|
||||||
// speakers, err := GetDeviceKasa("living_room/speakers")
|
speakers, err := p.Devices.GetKasaDevice("living_room/speakers")
|
||||||
// if err != nil {
|
if err != nil {
|
||||||
// log.Println(err)
|
log.Println(err)
|
||||||
// return
|
return
|
||||||
// }
|
}
|
||||||
|
|
||||||
// var message struct {
|
var message struct {
|
||||||
// Action string `json:"action"`
|
Action string `json:"action"`
|
||||||
// }
|
}
|
||||||
// err = json.Unmarshal(msg.Payload(), &message)
|
err = json.Unmarshal(msg.Payload(), &message)
|
||||||
// if err != nil {
|
if err != nil {
|
||||||
// log.Println(err)
|
log.Println(err)
|
||||||
// return
|
return
|
||||||
// }
|
}
|
||||||
|
|
||||||
// if message.Action == "on" {
|
if message.Action == "on" {
|
||||||
// if mixer.GetState() {
|
if mixer.GetState() {
|
||||||
// mixer.SetState(false)
|
mixer.SetState(false)
|
||||||
// speakers.SetState(false)
|
speakers.SetState(false)
|
||||||
// } else {
|
} else {
|
||||||
// mixer.SetState(true)
|
mixer.SetState(true)
|
||||||
// }
|
}
|
||||||
// } else if message.Action == "brightness_move_up" {
|
} else if message.Action == "brightness_move_up" {
|
||||||
// if speakers.GetState() {
|
if speakers.GetState() {
|
||||||
// speakers.SetState(false)
|
speakers.SetState(false)
|
||||||
// } else {
|
} else {
|
||||||
// speakers.SetState(true)
|
speakers.SetState(true)
|
||||||
// mixer.SetState(true)
|
mixer.SetState(true)
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// })
|
}
|
||||||
// }
|
|
||||||
|
if token := client.Subscribe("test/remote", 1, handler); token.Wait() && token.Error() != nil {
|
||||||
|
log.Println(token.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
_ = godotenv.Load()
|
_ = godotenv.Load()
|
||||||
|
|
||||||
config := GetConfig()
|
config := GetConfig()
|
||||||
|
|
||||||
devices = make(map[string]interface{})
|
|
||||||
|
|
||||||
// Setup all the connections to other services
|
// Setup all the connections to other services
|
||||||
client := mqtt.New(config.MQTT.Host, config.MQTT.Port, config.MQTT.ClientID, config.MQTT.Username, config.MQTT.Password)
|
client := mqtt.New(config.MQTT.Host, config.MQTT.Port, config.MQTT.ClientID, config.MQTT.Username, config.MQTT.Password)
|
||||||
defer client.Disconnect(250)
|
defer client.Disconnect(250)
|
||||||
notify := ntfy.New(config.NTFY.topic)
|
notify := ntfy.New(config.NTFY.topic)
|
||||||
hue := hue.New(config.Hue.IP, config.Hue.Token)
|
hue := hue.New(config.Hue.IP, config.Hue.Token)
|
||||||
|
|
||||||
// Setup presence system
|
|
||||||
p := presence.New(client, hue, notify)
|
|
||||||
defer p.Delete()
|
|
||||||
|
|
||||||
// Register all kasa devies
|
|
||||||
for name, ip := range config.Kasa.Outlets {
|
|
||||||
devices[name] = kasa.New(ip)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Devices that we control and expose to google home
|
// Devices that we control and expose to google home
|
||||||
provider := device.NewProvider(config.Google, client)
|
provider := device.NewProvider(config.Google, client)
|
||||||
|
|
||||||
|
// Setup presence system
|
||||||
|
p := presence.New(client, hue, notify, provider)
|
||||||
|
defer p.Delete()
|
||||||
|
|
||||||
r := mux.NewRouter()
|
r := mux.NewRouter()
|
||||||
r.HandleFunc("/assistant", provider.Service.FullfillmentHandler)
|
r.HandleFunc("/assistant", provider.Service.FullfillmentHandler)
|
||||||
|
|
||||||
|
// Register computers
|
||||||
for name, info := range config.Computer {
|
for name, info := range config.Computer {
|
||||||
provider.AddDevice(device.NewComputer(info.MACAddress, name, info.Room, info.Url))
|
provider.AddDevice(device.NewComputer(info.MACAddress, name, info.Room, info.Url))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Presence
|
// Register all kasa devies
|
||||||
|
for name, ip := range config.Kasa.Outlets {
|
||||||
|
provider.AddDevice(kasa.New(name, ip))
|
||||||
|
}
|
||||||
|
|
||||||
|
SetupBindings(client, provider)
|
||||||
|
|
||||||
|
// time.Sleep(time.Second)
|
||||||
|
// pretty.Println(provider.Devices)
|
||||||
|
// pretty.Println(provider.Devices.GetGoogleDevices())
|
||||||
|
// pretty.Println(provider.Devices.GetKasaDevices())
|
||||||
|
// pretty.Println(provider.Devices.GetZigbeeDevices())
|
||||||
|
|
||||||
addr := ":8090"
|
addr := ":8090"
|
||||||
srv := http.Server{
|
srv := http.Server{
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
package presence
|
package presence
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"automation/device"
|
||||||
"automation/integration/hue"
|
"automation/integration/hue"
|
||||||
|
"automation/integration/kasa"
|
||||||
"automation/integration/ntfy"
|
"automation/integration/ntfy"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -17,6 +19,7 @@ type Presence struct {
|
||||||
client paho.Client
|
client paho.Client
|
||||||
hue *hue.Hue
|
hue *hue.Hue
|
||||||
ntfy *ntfy.Notify
|
ntfy *ntfy.Notify
|
||||||
|
provider *device.Provider
|
||||||
|
|
||||||
devices map[string]bool
|
devices map[string]bool
|
||||||
presence bool
|
presence bool
|
||||||
|
@ -94,18 +97,18 @@ func (p *Presence) overallPresenceHandler(client paho.Client, msg paho.Message)
|
||||||
|
|
||||||
if !message.State {
|
if !message.State {
|
||||||
log.Println("Turn off all the devices")
|
log.Println("Turn off all the devices")
|
||||||
// // Turn off all the devices that we manage ourselves
|
|
||||||
// provider.TurnAllOff()
|
|
||||||
|
|
||||||
// // Turn off all devices
|
// Turn off all devices
|
||||||
// // @TODO Maybe allow for exceptions, could be a list in the config that we check against?
|
// @TODO Maybe allow for exceptions, could be a list in the config that we check against?
|
||||||
// for _, device := range devices {
|
for _, dev := range p.provider.Devices.Devices {
|
||||||
// switch d := device.(type) {
|
switch d := dev.(type) {
|
||||||
// case kasa.Kasa:
|
case *kasa.Kasa:
|
||||||
// d.SetState(false)
|
d.SetState(false)
|
||||||
|
case device.ZigbeeDevice:
|
||||||
|
d.SetState(false)
|
||||||
|
}
|
||||||
|
|
||||||
// }
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
// @TODO Turn off nest thermostat
|
// @TODO Turn off nest thermostat
|
||||||
} else {
|
} else {
|
||||||
|
@ -113,8 +116,8 @@ func (p *Presence) overallPresenceHandler(client paho.Client, msg paho.Message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(client paho.Client, hue *hue.Hue, ntfy *ntfy.Notify) *Presence {
|
func New(client paho.Client, hue *hue.Hue, ntfy *ntfy.Notify, provider *device.Provider) *Presence {
|
||||||
p := &Presence{client: client, hue: hue, ntfy: ntfy, devices: make(map[string]bool), presence: false}
|
p := &Presence{client: client, hue: hue, ntfy: ntfy, provider: provider, devices: make(map[string]bool), presence: false}
|
||||||
|
|
||||||
if token := p.client.Subscribe("automation/presence", 1, p.overallPresenceHandler); token.Wait() && token.Error() != nil {
|
if token := p.client.Subscribe("automation/presence", 1, p.overallPresenceHandler); token.Wait() && token.Error() != nil {
|
||||||
log.Println(token.Error())
|
log.Println(token.Error())
|
||||||
|
|
Reference in New Issue
Block a user