package mill import ( "context" "fmt" "git.aiterp.net/lucifer/new-server/models" "sync" "time" ) type Driver struct { mu sync.Mutex bridges map[int]*bridge } func (d *Driver) SearchBridge(ctx context.Context, address, token string, _ bool) ([]models.Bridge, error) { bridgeData := models.Bridge{ Name: fmt.Sprintf("Mill account (%s)", address), Driver: models.DTMill, Address: address, Token: token, } b, err := d.ensureBridge(bridgeData) if err != nil { return nil, err } err = b.authenticate(ctx) if err != nil { return nil, err } return []models.Bridge{bridgeData}, nil } func (d *Driver) SearchDevices(context.Context, models.Bridge, time.Duration) ([]models.Device, error) { // You would have to configure devices with the Mill app, unfortunately. return []models.Device{}, nil } func (d *Driver) ListDevices(ctx context.Context, bridge models.Bridge) ([]models.Device, error) { b, err := d.ensureBridge(bridge) if err != nil { return nil, err } return b.listDevices(ctx) } func (d *Driver) Publish(ctx context.Context, bridge models.Bridge, devices []models.Device) error { b, err := d.ensureBridge(bridge) if err != nil { return err } for _, device := range devices { err = b.pushStateChange(ctx, device) if err != nil { return err } } return nil } func (d *Driver) Run(ctx context.Context, _ models.Bridge, _ chan<- models.Event) error { // TODO: Maybe do something with the thermostat on the device for { select { case <-ctx.Done(): return ctx.Err() } } } func (d *Driver) ensureBridge(model models.Bridge) (*bridge, error) { d.mu.Lock() defer d.mu.Unlock() if d.bridges == nil { d.bridges = make(map[int]*bridge, 4) } if d.bridges[model.ID] == nil { newBridge := &bridge{ luciferID: model.ID, username: model.Address, password: model.Token, } if model.ID <= 0 { return newBridge, nil } d.bridges[model.ID] = newBridge } return d.bridges[model.ID], nil }