1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- package presence
- import (
- "context"
- "goa.design/clue/log"
- "douglasthrift.net/presence/ifttt"
- "douglasthrift.net/presence/neighbors"
- )
- type (
- Detector interface {
- Detect(ctx context.Context) error
- Config(config *Config)
- Client(client ifttt.Client)
- }
- detector struct {
- config *Config
- arp neighbors.ARP
- interfaces neighbors.Interfaces
- state neighbors.State
- states neighbors.HardwareAddrStates
- client ifttt.Client
- }
- )
- func NewDetector(config *Config, arp neighbors.ARP, client ifttt.Client) Detector {
- d := &detector{
- arp: arp,
- state: neighbors.NewState(),
- states: make(neighbors.HardwareAddrStates, len(config.MACAddresses)),
- client: client,
- }
- d.Config(config)
- return d
- }
- func (d *detector) Detect(ctx context.Context) error {
- log.Print(ctx, log.KV{K: "msg", V: "detecting presence"}, log.KV{K: "present", V: d.state.Present()})
- err := d.arp.Present(ctx, d.interfaces, d.state, d.states)
- if err != nil {
- return err
- }
- for _, a := range d.config.MACAddresses {
- state := d.states[a]
- log.Print(ctx, log.KV{K: "msg", V: a}, log.KV{K: "present", V: state.Present()}, log.KV{K: "changed", V: state.Changed()})
- }
- 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()})
- if d.state.Changed() {
- event, err := d.client.Trigger(ctx, d.state.Present())
- if err != nil {
- d.state.Reset()
- return err
- }
- log.Print(ctx, log.KV{K: "msg", V: "triggered IFTTT"}, log.KV{K: "event", V: event})
- }
- return nil
- }
- func (d *detector) Config(config *Config) {
- d.config = config
- d.interfaces = make(neighbors.Interfaces, len(config.Interfaces))
- for _, i := range config.Interfaces {
- d.interfaces[i] = true
- }
- states := make(map[string]bool, len(d.states))
- for a := range d.states {
- states[a] = true
- }
- for _, a := range config.MACAddresses {
- if states[a] {
- states[a] = false
- } else {
- d.states[a] = neighbors.NewState()
- }
- }
- for a, ok := range states {
- if ok {
- delete(d.states, a)
- }
- }
- }
- func (d *detector) Client(client ifttt.Client) {
- d.client = client
- }
|