1
0
Fork 0
hswro-alarm-bot/filters.go

146 lines
3.7 KiB
Go
Raw Normal View History

2024-02-13 22:20:15 +00:00
package main
import (
2024-02-15 19:06:06 +00:00
"log"
2024-03-10 09:12:04 +00:00
"sync"
2024-02-15 19:06:06 +00:00
2024-03-04 20:11:34 +00:00
"git.sr.ht/~michalr/go-satel"
2024-02-13 22:20:15 +00:00
)
func isBasicEventElementOkay(basicEventElement satel.BasicEventElement, allowedTypes []satel.ChangeType, allowedIndexes []int) bool {
for _, allowedType := range allowedTypes {
if allowedType == basicEventElement.Type {
return true
}
2024-02-18 17:44:08 +00:00
}
for _, allowedIndex := range allowedIndexes {
if allowedIndex == basicEventElement.Index {
return true
}
}
return false
2024-02-13 22:20:15 +00:00
}
2024-02-14 20:34:16 +00:00
2024-03-10 09:12:04 +00:00
func FilterByTypeOrIndex(ev <-chan satel.Event, wg *sync.WaitGroup, allowedTypes []satel.ChangeType, allowedIndexes []int) <-chan satel.Event {
2024-02-18 18:00:49 +00:00
returnChan := make(chan satel.Event)
if (len(allowedTypes) == 0) && (len(allowedIndexes) == 0) {
// no allowed types == all types are allowed
2024-02-18 18:00:49 +00:00
go func() {
2024-03-10 09:12:04 +00:00
wg.Add(1)
defer wg.Done()
2024-02-18 18:00:49 +00:00
for e := range ev {
returnChan <- e
}
close(returnChan)
}()
} else {
go func() {
2024-03-10 09:12:04 +00:00
wg.Add(1)
defer wg.Done()
2024-02-18 18:00:49 +00:00
for e := range ev {
retEv := satel.Event{BasicEvents: make([]satel.BasicEventElement, 0)}
for _, basicEventElement := range e.BasicEvents {
if isBasicEventElementOkay(basicEventElement, allowedTypes, allowedIndexes) {
retEv.BasicEvents = append(retEv.BasicEvents, basicEventElement)
2024-02-18 18:00:49 +00:00
}
}
if len(retEv.BasicEvents) != 0 {
returnChan <- retEv
}
2024-02-18 18:00:49 +00:00
}
close(returnChan)
}()
}
return returnChan
}
2024-03-10 09:12:04 +00:00
func FilterByLastSeen(ev <-chan satel.Event, wg *sync.WaitGroup, dataStore *DataStore, logger *log.Logger) <-chan satel.Event {
2024-02-14 20:34:16 +00:00
returnChan := make(chan satel.Event)
go func() {
2024-03-10 09:12:04 +00:00
wg.Add(1)
defer wg.Done()
2024-02-14 20:34:16 +00:00
for e := range ev {
retEv := satel.Event{BasicEvents: make([]satel.BasicEventElement, 0)}
for _, basicEventElement := range e.BasicEvents {
lastSeen := dataStore.GetSystemState()
val, ok := lastSeen[EventKey{basicEventElement.Type, basicEventElement.Index}]
if !ok || val.Value != basicEventElement.Value {
retEv.BasicEvents = append(retEv.BasicEvents, basicEventElement)
// TODO: flush to disk only after the loop finishes
dataStore.SetSystemState(EventKey{basicEventElement.Type, basicEventElement.Index}, EventValue{basicEventElement.Value})
}
}
if len(retEv.BasicEvents) != 0 {
returnChan <- retEv
2024-02-14 20:34:16 +00:00
}
}
logger.Print("Satel disconnected.")
2024-03-03 11:59:02 +00:00
close(returnChan)
}()
return returnChan
}
2024-03-10 09:52:27 +00:00
func appendToGenericMessage(msg *GenericMessage, new *GenericMessage) *GenericMessage {
if msg == nil {
return new
}
throughNewMessages:
for _, newEv := range new.Messages {
for i, oldEv := range msg.Messages {
if oldEv.Index == newEv.Index && oldEv.Type == newEv.Type {
// this message was seen - update its value
msg.Messages[i].Value = newEv.Value
continue throughNewMessages
}
// apparently this type of message was not yet seen, save it
msg.Messages = append(msg.Messages, newEv)
}
}
return msg
}
func Throttle(inputEvents <-chan GenericMessage, wg *sync.WaitGroup, sleeper Sleeper, logger *log.Logger) <-chan GenericMessage {
returnChan := make(chan GenericMessage)
2024-03-10 09:52:27 +00:00
timeoutEvents := make(chan interface{})
go func() {
wg.Add(1)
var currentEvent *GenericMessage = nil
2024-03-10 09:52:27 +00:00
loop:
for {
select {
case ev, ok := <-inputEvents:
if !ok {
break loop
}
if currentEvent == nil {
logger.Print("Waiting for more messages to arrive before sending...")
sleeper.Sleep(timeoutEvents)
}
currentEvent = appendToGenericMessage(currentEvent, &ev)
2024-03-10 09:52:27 +00:00
case <-timeoutEvents:
logger.Print("Time's up, sending all messages we've got for now.")
returnChan <- *currentEvent
currentEvent = nil
}
}
// If anything is left to be sent, send it now
if currentEvent != nil {
returnChan <- *currentEvent
}
close(returnChan)
wg.Done()
2024-03-10 09:52:27 +00:00
}()
return returnChan
}