From f27c0a3f7f874ff95457c9db4eacc0e3f2442e19 Mon Sep 17 00:00:00 2001 From: Gisle Aune Date: Sun, 3 Mar 2019 21:23:40 +0100 Subject: [PATCH] BridgeController: Added GET /api/bridge/discover/:driver_name --- controllers/bridge-controller.go | 12 ++++++++++++ light/hue/driver.go | 22 +++++++++++++++++++++- light/service.go | 29 +++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/controllers/bridge-controller.go b/controllers/bridge-controller.go index 6b37182..f2460e1 100644 --- a/controllers/bridge-controller.go +++ b/controllers/bridge-controller.go @@ -212,6 +212,17 @@ func (c *BridgeController) deleteBridgeLight(w http.ResponseWriter, r *http.Requ respond.Data(w, bridge) } +// discoverBridges (`GET /discover/:driver`): Get all bridges +func (c *BridgeController) discoverBridges(w http.ResponseWriter, r *http.Request) { + newBridges, err := c.service.DiscoverBridges(r.Context(), mux.Vars(r)["driver_name"]) + if err != nil { + httperr.Respond(w, err) + return + } + + respond.Data(w, newBridges) +} + // Mount mounts the controller func (c *BridgeController) Mount(router *mux.Router, prefix string) { sub := router.PathPrefix(prefix).Subrouter() @@ -225,6 +236,7 @@ func (c *BridgeController) Mount(router *mux.Router, prefix string) { sub.HandleFunc("/{bridge_id}", c.deleteBridge).Methods("DELETE") sub.HandleFunc("/{bridge_id}/light/{light_id}", c.deleteBridgeLight).Methods("DELETE") sub.HandleFunc("/{bridge_id}/discover", c.postBridgeDiscover).Methods("POST") + sub.HandleFunc("/discover/{driver_name}", c.discoverBridges).Methods("GET") } func (c *BridgeController) adminMiddleware() mux.MiddlewareFunc { diff --git a/light/hue/driver.go b/light/hue/driver.go index 422a799..3515985 100644 --- a/light/hue/driver.go +++ b/light/hue/driver.go @@ -147,7 +147,27 @@ func (d *driver) Lights(ctx context.Context, bridge models.Bridge) ([]models.Lig } func (d *driver) Bridges(ctx context.Context) ([]models.Bridge, error) { - panic("not implemented") + hueBridges, err := gohue.FindBridges() + if err != nil { + if err.Error() == "no bridges found" { // It's not my fault the library doesn't have good errors. D:< + return []models.Bridge{}, nil + } + + return nil, err + } + + bridges := make([]models.Bridge, 0, len(hueBridges)) + for _, hueBridge := range hueBridges { + bridges = append(bridges, models.Bridge{ + ID: -1, + InternalID: hueBridge.Info.Device.SerialNumber, + Driver: "hue", + Name: fmt.Sprintf("New bridge (%s, %s)", hueBridge.Info.Device.FriendlyName, hueBridge.Info.Device.SerialNumber), + Addr: hueBridge.IPAddress, + }) + } + + return bridges, err } func (d *driver) Connect(ctx context.Context, bridge models.Bridge) (models.Bridge, error) { diff --git a/light/service.go b/light/service.go index 8262ed3..10a4f82 100644 --- a/light/service.go +++ b/light/service.go @@ -245,6 +245,35 @@ func (s *Service) DiscoverLights(ctx context.Context, bridge models.Bridge) erro return d.DiscoverLights(ctx, bridge) } +// DiscoverBridges discovers new lights. +func (s *Service) DiscoverBridges(ctx context.Context, driver string) ([]models.Bridge, error) { + d, ok := drivers[driver] + if !ok { + return nil, ErrUnknownDriver + } + + existingBridges, err := s.Bridges(ctx) + if err != nil { + return nil, err + } + + newBridges, err := d.Bridges(ctx) + if err != nil { + return nil, err + } + + for _, existingBridge := range existingBridges { + for j, newBridge := range newBridges { + if newBridge.InternalID == existingBridge.InternalID { + newBridges = append(newBridges[:j], newBridges[j+1:]...) + break + } + } + } + + return newBridges, nil +} + // NewService creates a new light.Service. func NewService(bridges models.BridgeRepository, lights models.LightRepository) *Service { return &Service{