detector.go 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. package presence
  2. import (
  3. "context"
  4. "goa.design/clue/log"
  5. "douglasthrift.net/presence/ifttt"
  6. "douglasthrift.net/presence/neighbors"
  7. )
  8. type (
  9. Detector interface {
  10. Detect(ctx context.Context) error
  11. Config(config *Config)
  12. Client(client ifttt.Client)
  13. }
  14. detector struct {
  15. config *Config
  16. arp neighbors.ARP
  17. interfaces neighbors.Interfaces
  18. state neighbors.State
  19. states neighbors.HardwareAddrStates
  20. client ifttt.Client
  21. }
  22. )
  23. func NewDetector(config *Config, arp neighbors.ARP, client ifttt.Client) Detector {
  24. d := &detector{
  25. arp: arp,
  26. state: neighbors.NewState(),
  27. states: make(neighbors.HardwareAddrStates, len(config.MACAddresses)),
  28. client: client,
  29. }
  30. d.Config(config)
  31. return d
  32. }
  33. func (d *detector) Detect(ctx context.Context) error {
  34. log.Print(ctx, log.KV{K: "msg", V: "detecting presence"}, log.KV{K: "present", V: d.state.Present()})
  35. err := d.arp.Present(ctx, d.interfaces, d.state, d.states)
  36. if err != nil {
  37. return err
  38. }
  39. for _, a := range d.config.MACAddresses {
  40. state := d.states[a]
  41. log.Print(ctx, log.KV{K: "msg", V: a}, log.KV{K: "present", V: state.Present()}, log.KV{K: "changed", V: state.Changed()})
  42. }
  43. log.Print(ctx, log.KV{K: "msg", V: "detected presence"}, log.KV{K: "present", V: d.state.Present()}, log.KV{K: "changed", V: d.state.Changed()})
  44. if d.state.Changed() {
  45. event, values, err := d.client.Trigger(ctx, d.state.Present())
  46. if err != nil {
  47. d.state.Reset()
  48. return err
  49. }
  50. log.Print(ctx, log.KV{K: "msg", V: "triggered IFTTT"}, log.KV{K: "event", V: event},
  51. log.KV{K: "value1", V: values.Value1},
  52. log.KV{K: "value2", V: values.Value2},
  53. log.KV{K: "value3", V: values.Value3})
  54. }
  55. return nil
  56. }
  57. func (d *detector) Config(config *Config) {
  58. d.config = config
  59. d.interfaces = make(neighbors.Interfaces, len(config.Interfaces))
  60. for _, i := range config.Interfaces {
  61. d.interfaces[i] = true
  62. }
  63. states := make(map[string]bool, len(d.states))
  64. for a := range d.states {
  65. states[a] = true
  66. }
  67. for _, a := range config.MACAddresses {
  68. if states[a] {
  69. states[a] = false
  70. } else {
  71. d.states[a] = neighbors.NewState()
  72. }
  73. }
  74. for a, ok := range states {
  75. if ok {
  76. delete(d.states, a)
  77. }
  78. }
  79. }
  80. func (d *detector) Client(client ifttt.Client) {
  81. d.client = client
  82. }