diff --git a/filters.go b/filters.go index 62b78f0..9923d22 100644 --- a/filters.go +++ b/filters.go @@ -21,3 +21,26 @@ func FilterByType(ev <-chan satel.Event, allowedTypes []satel.ChangeType) <-chan return returnChan } + +type EventKey struct { + ChangeType satel.ChangeType + Index int +} + +func FilterByLastSeen(ev <-chan satel.Event) <-chan satel.Event { + returnChan := make(chan satel.Event) + + go func() { + lastSeen := make(map[EventKey]bool) // key: ChangeType/Index; value: Value + for e := range ev { + val, ok := lastSeen[EventKey{e.Type, e.Index}] + if !ok || val != e.Value { + lastSeen[EventKey{e.Type, e.Index}] = e.Value + returnChan <- e + } + } + close(returnChan) + }() + + return returnChan +} diff --git a/filters_test.go b/filters_test.go index b36f4dd..1058d40 100644 --- a/filters_test.go +++ b/filters_test.go @@ -35,3 +35,32 @@ func TestSatelEventTypeFiltering(t *testing.T) { assert.Contains(t, receivedEvents, satel.Event{Type: satel.ArmedPartition, Index: 1, Value: true}) assert.Contains(t, receivedEvents, satel.Event{Type: satel.PartitionFireAlarm, Index: 4, Value: true}) } + +func TestSatelLastSeenFiltering(t *testing.T) { + testEvents := make(chan satel.Event) + receivedEvents := make([]satel.Event, 0) + wg := sync.WaitGroup{} + + go func() { + wg.Add(1) + for e := range FilterByLastSeen(testEvents) { + receivedEvents = append(receivedEvents, e) + } + wg.Done() + }() + + testEvents <- satel.Event{Type: satel.ArmedPartition, Index: 1, Value: true} + testEvents <- satel.Event{Type: satel.ArmedPartition, Index: 2, Value: true} + testEvents <- satel.Event{Type: satel.ArmedPartition, Index: 1, Value: true} + testEvents <- satel.Event{Type: satel.ArmedPartition, Index: 1, Value: false} + testEvents <- satel.Event{Type: satel.ArmedPartition, Index: 2, Value: true} + testEvents <- satel.Event{Type: satel.ArmedPartition, Index: 1, Value: false} + + close(testEvents) + wg.Wait() + + assert.Len(t, receivedEvents, 3) + assert.Contains(t, receivedEvents, satel.Event{Type: satel.ArmedPartition, Index: 1, Value: true}) + assert.Contains(t, receivedEvents, satel.Event{Type: satel.ArmedPartition, Index: 2, Value: true}) + assert.Contains(t, receivedEvents, satel.Event{Type: satel.ArmedPartition, Index: 1, Value: false}) +}