Possibility to filter by indexes

command_handler
Michał Rudowicz 2024-02-18 19:00:49 +01:00
rodzic ab5bd412f2
commit 557f5481fd
4 zmienionych plików z 103 dodań i 5 usunięć

Wyświetl plik

@ -58,6 +58,10 @@ Supported types are:
- `partition-with-violated-zones`
- `zone-isolate`
### Filtering events by index (I guess "zone", but I'm not sure)
Use the `--allowed-indexes=1,2,3,...` command line parameter to set the list of allowed indexes (of course provide your own list instead of `1,2,3,...`). If that parameter is not provided, then all indexes are allowed; otherwise the notification is sent for all indexes.
## Debugging
Set the `OMIT_TG` environment variable to, well, omit sending anything over to Telegram and just see the logs instead.

Wyświetl plik

@ -38,6 +38,34 @@ func FilterByType(ev <-chan satel.Event, allowedTypes []satel.ChangeType) <-chan
return returnChan
}
func FilterByIndex(ev <-chan satel.Event, allowedIndexes []int) <-chan satel.Event {
returnChan := make(chan satel.Event)
if len(allowedIndexes) == 0 {
// no allowed indexes == all indexes are allowed
go func() {
for e := range ev {
returnChan <- e
}
close(returnChan)
}()
} else {
go func() {
for e := range ev {
for _, allowedIndex := range allowedIndexes {
if allowedIndex == e.Index {
returnChan <- e
continue
}
}
}
close(returnChan)
}()
}
return returnChan
}
type EventKey struct {
ChangeType satel.ChangeType
Index int

Wyświetl plik

@ -65,6 +65,61 @@ func TestSatelEventTypeFiltering_NoAllowedEventTypesMeansAllAreAllowed(t *testin
}
}
func TestSatelIndexFiltering(t *testing.T) {
testEvents := make(chan satel.Event)
receivedEvents := make([]satel.Event, 0)
wg := sync.WaitGroup{}
go func() {
wg.Add(1)
for e := range FilterByIndex(testEvents, []int{1, 3}) {
receivedEvents = append(receivedEvents, e)
}
wg.Done()
}()
testEvents <- satel.Event{Type: satel.ArmedPartition, Index: 1, Value: true}
testEvents <- satel.Event{Type: satel.DoorOpened, Index: 2, Value: true}
testEvents <- satel.Event{Type: satel.PartitionAlarm, Index: 3, Value: true}
testEvents <- satel.Event{Type: satel.PartitionFireAlarm, Index: 4, Value: true}
testEvents <- satel.Event{Type: satel.TroublePart1, Index: 5, Value: true}
testEvents <- satel.Event{Type: satel.ZoneTamper, Index: 6, Value: true}
close(testEvents)
wg.Wait()
assert.Len(t, receivedEvents, 2)
assert.Contains(t, receivedEvents, satel.Event{Type: satel.ArmedPartition, Index: 1, Value: true})
assert.Contains(t, receivedEvents, satel.Event{Type: satel.PartitionAlarm, Index: 3, Value: true})
}
func TestSatelIndexFiltering_NoAllowedEventTypesMeansAllAreAllowed(t *testing.T) {
testEvents := make(chan satel.Event)
receivedEvents := make([]satel.Event, 0)
wg := sync.WaitGroup{}
myReasonableMaxIndex := 100 // I wanted to use math.MaxInt at first, but it's kind of a waste of time here
go func() {
wg.Add(1)
for e := range FilterByIndex(testEvents, []int{}) {
receivedEvents = append(receivedEvents, e)
}
wg.Done()
}()
for i := 0; i < myReasonableMaxIndex; i++ {
testEvents <- satel.Event{Type: satel.ArmedPartition, Index: i, Value: true}
}
close(testEvents)
wg.Wait()
assert.Len(t, receivedEvents, myReasonableMaxIndex)
for i := 0; i < myReasonableMaxIndex; i++ {
assert.Contains(t, receivedEvents, satel.Event{Type: satel.ArmedPartition, Index: i, Value: true})
}
}
func TestSatelLastSeenFiltering(t *testing.T) {
f, err := os.CreateTemp("", "TestSatelLastSeenFiltering")
assert.NoError(t, err)

21
main.go
Wyświetl plik

@ -68,11 +68,12 @@ func (self RealSleeper) Sleep(ch chan<- interface{}) {
}()
}
func getCmdLineParams(logger *log.Logger) (string, []int64, []satel.ChangeType) {
func getCmdLineParams(logger *log.Logger) (string, []int64, []satel.ChangeType, []int) {
satelApiAddr := flag.String("satel-addr", "", "Address that should be used to connect to the SATEL device")
satelApiPort := flag.String("satel-port", "7094", "Port that should be used to connect to the SATEL device")
chatIdRaw := flag.String("tg-chat-id", "", "Telegram Chat ID where to send updates. Use \",\" to specify multiple IDs.")
allowedTypesRaw := flag.String("allowed-types", "", "Satel change types that are allowed. All other types will be discarded. By default all are allowed. Use \",\" to specify multiple types.")
allowedIndexesRaw := flag.String("allowed-indexes", "", "Satel indexes (zones?) that are allowed. All other indexes will be discarded. By default all are allowed. Use \",\" to specify multiple indexes.")
flag.Parse()
if len(*satelApiAddr) == 0 || len(*satelApiPort) == 0 || len(*chatIdRaw) == 0 {
@ -96,9 +97,18 @@ func getCmdLineParams(logger *log.Logger) (string, []int64, []satel.ChangeType)
}
allowedTypes = append(allowedTypes, allowedType)
}
allowedIndexesStrings := strings.Split(*allowedIndexesRaw, ",")
var allowedIndexes []int
for _, allowedIndexStr := range allowedIndexesStrings {
allowedIndex, err := strconv.ParseInt(allowedIndexStr, 10, 0)
if err != nil {
logger.Fatalf("Tried to use a non-int value for one of allowed indexes: %s. That's bad.", allowedIndexStr)
}
allowedIndexes = append(allowedIndexes, int(allowedIndex))
}
satelAddr := fmt.Sprintf("%s:%s", *satelApiAddr, *satelApiPort)
return satelAddr, chatIds, allowedTypes
return satelAddr, chatIds, allowedTypes, allowedIndexes
}
func makeSatel(satelAddr string) *satel.Satel {
@ -117,7 +127,7 @@ func main() {
logger = log.New(os.Stderr, "Main", log.Lmicroseconds)
)
satelAddr, chatIds, allowedTypes := getCmdLineParams(logger)
satelAddr, chatIds, allowedTypes, allowedIndexes := getCmdLineParams(logger)
s := makeSatel(satelAddr)
logger.Printf("Connected to Satel: %s", satelAddr)
@ -135,9 +145,10 @@ func main() {
tgSenderWorker(tgEvents, &wg, sleeper, log.New(os.Stderr, "TgSender", log.Lmicroseconds)),
tgSender, &wg, log.New(os.Stderr, "SendToTg", log.Lmicroseconds)))
for e := range FilterByType(
for e := range FilterByIndex(FilterByType(
FilterByLastSeen(s.Events, "hs_wro_last_seen.bin", log.New(os.Stderr, "FilterByLastSeen", log.Lmicroseconds)),
allowedTypes) {
allowedTypes),
allowedIndexes) {
logger.Print("Received change from SATEL: ", e)
for _, chatId := range chatIds {
sendTgMessage(tgEvents, SatelMsgContent{e}, chatId)