backup
This commit is contained in:
parent
b250a6b3c8
commit
081626b434
5 changed files with 137 additions and 14 deletions
|
@ -60,6 +60,11 @@ type jsonConf struct {
|
|||
McastGroup string `json:"multicast_group"`
|
||||
SrcAddr string `json:"src_addr"`
|
||||
} `json:"boot_provider"`
|
||||
HomeAssistant struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
Host string `json:"host"`
|
||||
APIToken string `json:"token"`
|
||||
} `json:"home_assistant"`
|
||||
}
|
||||
|
||||
type AppConfig struct {
|
||||
|
@ -75,6 +80,9 @@ type AppConfig struct {
|
|||
UDPPort int
|
||||
UDPIface string
|
||||
UDPSrcAddr string
|
||||
HomeAssistantEnabled bool
|
||||
HomeAssistantHost string
|
||||
HomeAssistantToken string
|
||||
}
|
||||
|
||||
func parseLevel(lvlStr string) logrus.Level {
|
||||
|
@ -108,6 +116,9 @@ func (ac *AppConfig) UnmarshalJSON(data []byte) error {
|
|||
ac.UDPSrcAddr = jsonConf.BootProvider.SrcAddr
|
||||
ac.DataFilepath = jsonConf.Storage.Path
|
||||
ac.StaticDir = jsonConf.Storage.StaticDir
|
||||
ac.HomeAssistantEnabled = jsonConf.HomeAssistant.Enabled
|
||||
ac.HomeAssistantHost = jsonConf.HomeAssistant.Host
|
||||
ac.HomeAssistantToken = jsonConf.HomeAssistant.APIToken
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,9 @@ import (
|
|||
"io"
|
||||
"net/http"
|
||||
|
||||
"git.faercol.me/faercol/http-boot-server/bootserver/config"
|
||||
"git.faercol.me/faercol/http-boot-server/bootserver/helpers"
|
||||
"git.faercol.me/faercol/http-boot-server/bootserver/homeassistant"
|
||||
"git.faercol.me/faercol/http-boot-server/bootserver/services"
|
||||
"github.com/google/uuid"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
@ -22,13 +24,15 @@ type setBootOptionPayload struct {
|
|||
|
||||
type BootController struct {
|
||||
clientService *services.ClientHandlerService
|
||||
appConf *config.AppConfig
|
||||
l *logrus.Logger
|
||||
}
|
||||
|
||||
func NewBootController(logger *logrus.Logger, service *services.ClientHandlerService) *BootController {
|
||||
func NewBootController(logger *logrus.Logger, service *services.ClientHandlerService, conf *config.AppConfig) *BootController {
|
||||
return &BootController{
|
||||
clientService: service,
|
||||
l: logger,
|
||||
appConf: conf,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,6 +65,18 @@ func (bc *BootController) setBootOption(w http.ResponseWriter, r *http.Request)
|
|||
return http.StatusInternalServerError, nil, fmt.Errorf("failed to set boot option for client: %w", err)
|
||||
}
|
||||
|
||||
if bc.appConf.HomeAssistantEnabled {
|
||||
bc.l.Debug("Notifying HomeAssistant of change")
|
||||
newConf, err := bc.clientService.GetClientConfig(clientID)
|
||||
if err != nil {
|
||||
bc.l.Errorf("Failed to get new config to send to HA: %s", err.Error())
|
||||
} else {
|
||||
if err := homeassistant.New(bc.appConf).SendBootOption(r.Context(), newConf.Name, newConf.Options[newConf.SelectedOption].Name); err != nil {
|
||||
bc.l.Errorf("Failed to notify HA: %s", err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return http.StatusAccepted, nil, nil
|
||||
}
|
||||
|
||||
|
|
80
bootserver/homeassistant/sender..go
Normal file
80
bootserver/homeassistant/sender..go
Normal file
|
@ -0,0 +1,80 @@
|
|||
package homeassistant
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"git.faercol.me/faercol/http-boot-server/bootserver/config"
|
||||
"git.faercol.me/faercol/http-boot-server/bootserver/logger"
|
||||
)
|
||||
|
||||
type Entity struct {
|
||||
State string `json:"state"`
|
||||
ID string `json:"-"`
|
||||
Attributes map[string]string `json:"attributes,omitempty"`
|
||||
}
|
||||
|
||||
func newBootOptionEntity(device, option string) Entity {
|
||||
return Entity{
|
||||
State: option,
|
||||
ID: "httpboot." + device,
|
||||
Attributes: nil,
|
||||
}
|
||||
}
|
||||
|
||||
type HomeAssistantExporter struct {
|
||||
clt *http.Client
|
||||
baseURL string
|
||||
token string
|
||||
}
|
||||
|
||||
func New(conf *config.AppConfig) *HomeAssistantExporter {
|
||||
clt := http.Client{}
|
||||
return &HomeAssistantExporter{
|
||||
clt: &clt,
|
||||
baseURL: conf.HomeAssistantHost,
|
||||
token: conf.HomeAssistantToken,
|
||||
}
|
||||
}
|
||||
|
||||
func (e *HomeAssistantExporter) SendBootOption(ctx context.Context, device string, option string) error {
|
||||
subCtx, cancel := context.WithTimeout(ctx, 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
entity := newBootOptionEntity(device, option)
|
||||
|
||||
dat, err := json.Marshal(entity)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(subCtx, http.MethodPost, e.baseURL+"/api/states/"+entity.ID, bytes.NewBuffer(dat))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Header.Add("Authorization", "Bearer "+e.token)
|
||||
|
||||
resp, err := e.clt.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch resp.StatusCode {
|
||||
case http.StatusOK:
|
||||
logger.L.Debugf("Updated boot info for device %s to %s", device, option)
|
||||
case http.StatusCreated:
|
||||
logger.L.Debugf("Created boot info for device %s with value %s", device, option)
|
||||
default:
|
||||
respBod, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return fmt.Errorf("unexpected returncode %d (%s)", resp.StatusCode, string(respBod))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -8,6 +8,7 @@ import (
|
|||
"time"
|
||||
|
||||
"git.faercol.me/faercol/http-boot-server/bootserver/config"
|
||||
"git.faercol.me/faercol/http-boot-server/bootserver/homeassistant"
|
||||
"git.faercol.me/faercol/http-boot-server/bootserver/logger"
|
||||
"git.faercol.me/faercol/http-boot-server/bootserver/server"
|
||||
"git.faercol.me/faercol/http-boot-server/bootserver/services"
|
||||
|
@ -61,6 +62,21 @@ func main() {
|
|||
logger.L.Fatalf("Failed to start UDP listener: %s", err.Error())
|
||||
}
|
||||
|
||||
if conf.HomeAssistantEnabled {
|
||||
logger.L.Info("Home assistant integration enabled, sending current configuration to the host")
|
||||
haClt := homeassistant.New(conf)
|
||||
cltSrv := services.NewClientHandlerService(conf.DataFilepath, logger.L)
|
||||
clts, err := cltSrv.GetAllClientConfig()
|
||||
if err != nil {
|
||||
logger.L.Fatalf("Failed to get current clients from the storage: %s", err.Error())
|
||||
}
|
||||
for _, c := range clts {
|
||||
if err := haClt.SendBootOption(context.Background(), c.Name, c.Options[c.SelectedOption].Name); err != nil {
|
||||
logger.L.Errorf("Failed to send config to homeassistant: %s", err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
go s.Run(mainCtx)
|
||||
go listener.Run(mainCtx)
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ func New(appConf *config.AppConfig, logger *logrus.Logger) (*Server, error) {
|
|||
controllers := map[string]http.Handler{
|
||||
client.EnrollRoute: middlewares.WithLogger(client.NewEnrollController(logger, service, appConf.UDPPort, appConf.UPDMcastGroup), logger),
|
||||
client.ConfigRoute: middlewares.WithLogger(client.NewGetConfigController(logger, service, appConf), logger),
|
||||
client.SetBootRoute: middlewares.WithLogger(client.NewBootController(logger, service), logger),
|
||||
client.SetBootRoute: middlewares.WithLogger(client.NewBootController(logger, service, appConf), logger),
|
||||
ui.StaticRoute: middlewares.WithLogger(ui.NewStaticController(appConf.StaticDir), logger),
|
||||
ui.UIRoute: middlewares.WithLogger(ui.NewUIController(logger, service, appConf.StaticDir), logger),
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue