You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

100 lines
1.9 KiB

3 years ago
  1. package mill
  2. import (
  3. "context"
  4. "fmt"
  5. "git.aiterp.net/lucifer/new-server/models"
  6. "sync"
  7. "time"
  8. )
  9. type Driver struct {
  10. mu sync.Mutex
  11. bridges map[int]*bridge
  12. }
  13. func (d *Driver) SearchBridge(ctx context.Context, address, token string, _ bool) ([]models.Bridge, error) {
  14. bridgeData := models.Bridge{
  15. Name: fmt.Sprintf("Mill account (%s)", address),
  16. Driver: models.DTMill,
  17. Address: address,
  18. Token: token,
  19. }
  20. b, err := d.ensureBridge(bridgeData)
  21. if err != nil {
  22. return nil, err
  23. }
  24. err = b.authenticate(ctx)
  25. if err != nil {
  26. return nil, err
  27. }
  28. return []models.Bridge{bridgeData}, nil
  29. }
  30. func (d *Driver) SearchDevices(context.Context, models.Bridge, time.Duration) ([]models.Device, error) {
  31. // You would have to configure devices with the Mill app, unfortunately.
  32. return []models.Device{}, nil
  33. }
  34. func (d *Driver) ListDevices(ctx context.Context, bridge models.Bridge) ([]models.Device, error) {
  35. b, err := d.ensureBridge(bridge)
  36. if err != nil {
  37. return nil, err
  38. }
  39. return b.listDevices(ctx)
  40. }
  41. func (d *Driver) Publish(ctx context.Context, bridge models.Bridge, devices []models.Device) error {
  42. b, err := d.ensureBridge(bridge)
  43. if err != nil {
  44. return err
  45. }
  46. for _, device := range devices {
  47. err = b.pushStateChange(ctx, device)
  48. if err != nil {
  49. return err
  50. }
  51. }
  52. return nil
  53. }
  54. func (d *Driver) Run(ctx context.Context, _ models.Bridge, _ chan<- models.Event) error {
  55. // TODO: Maybe do something with the thermostat on the device
  56. for {
  57. select {
  58. case <-ctx.Done():
  59. return ctx.Err()
  60. }
  61. }
  62. }
  63. func (d *Driver) ensureBridge(model models.Bridge) (*bridge, error) {
  64. d.mu.Lock()
  65. defer d.mu.Unlock()
  66. if d.bridges == nil {
  67. d.bridges = make(map[int]*bridge, 4)
  68. }
  69. if d.bridges[model.ID] == nil {
  70. newBridge := &bridge{
  71. luciferID: model.ID,
  72. username: model.Address,
  73. password: model.Token,
  74. }
  75. if model.ID <= 0 {
  76. return newBridge, nil
  77. }
  78. d.bridges[model.ID] = newBridge
  79. }
  80. return d.bridges[model.ID], nil
  81. }