package main
import (
"fmt"
"html/template"
"log"
"strings"
"git.sr.ht/~michalr/go-satel"
)
const (
ArmedPartition_Armed = true
ArmedPartition_Unrmed = false
PartitionAlarm_Alarm = true
PartitionAlarm_AlarmCancelled = false
)
type SatelNameGetter interface {
GetName(devType satel.DeviceType, index byte) (*satel.NameEvent, error)
}
type MsgContent struct {
SatelEvent satel.BasicEventElement
}
type SatelMsgContent struct {
SatelEvent satel.BasicEventElement
s SatelNameGetter
logger *log.Logger
}
type GenericMessage struct {
ChatIds ChatId
Messages []satel.BasicEventElement
}
type SatelMessage struct {
ChatIds ChatId
Messages []SatelMsgContent
}
func getSatelMessageContent(messages []satel.BasicEventElement, s SatelNameGetter, logger *log.Logger) []SatelMsgContent {
retval := make([]SatelMsgContent, len(messages))
for i, v := range messages {
retval[i] = SatelMsgContent{v, s, logger}
}
return retval
}
func (self SatelMsgContent) GetName() string {
if self.SatelEvent.Type == satel.ArmedPartition || self.SatelEvent.Type == satel.PartitionAlarm {
// Satel has 1-based indexes of partitions, go-satel has 0-based
name, err := self.s.GetName(satel.DeviceType_Partition, byte(self.SatelEvent.Index+1))
if err != nil {
self.logger.Print("Could not get partition name: ", err)
return fmt.Sprint("Partition#", self.SatelEvent.Index)
}
return name.DevName
} else {
return self.IndexDesc()
}
}
func (self GenericMessage) Format(template *template.Template, s SatelNameGetter, logger *log.Logger) string {
b := strings.Builder{}
template.Execute(&b, SatelMessage{
self.ChatIds,
getSatelMessageContent(self.Messages, s, logger),
})
return b.String()
}
func getEmojiWhenTrueIsGood(v bool) string {
if v {
return "✅"
} else {
return "🔴"
}
}
func getEmojiWhenTrueIsBad(v bool) string {
if v {
return "🔴"
} else {
return "✅"
}
}
func getArmedPartitionStatus(v bool) string {
if v == ArmedPartition_Armed {
return "✅ - ARMED"
} else {
return "🔴 - DISARMED"
}
}
func getPartitionAlarmStatus(v bool) string {
if v == PartitionAlarm_Alarm {
return "⚠️⚠️ ALARM! ⚠️⚠️"
} else {
return "Alarm cancelled"
}
}
func (self SatelMsgContent) FormatEvent() string {
switch self.SatelEvent.Type {
case satel.ZoneViolation:
return fmt.Sprintf("%s: %s", self.SatelEvent.Type.String(), getEmojiWhenTrueIsBad(self.SatelEvent.Value))
case satel.ZoneTamper:
return fmt.Sprintf("%s: %s", self.SatelEvent.Type.String(), getEmojiWhenTrueIsBad(self.SatelEvent.Value))
case satel.ZoneAlarm:
return fmt.Sprintf("%s: %s", self.SatelEvent.Type.String(), getEmojiWhenTrueIsBad(self.SatelEvent.Value))
case satel.ZoneTamperAlarm:
return fmt.Sprintf("%s: %s", self.SatelEvent.Type.String(), getEmojiWhenTrueIsBad(self.SatelEvent.Value))
case satel.ZoneAlarmMemory:
return fmt.Sprintf("%s: %t", self.SatelEvent.Type.String(), self.SatelEvent.Value)
case satel.ZoneTamperAlarmMemory:
return fmt.Sprintf("%s: %t", self.SatelEvent.Type.String(), self.SatelEvent.Value)
case satel.ZoneBypass:
return fmt.Sprintf("%s: %t", self.SatelEvent.Type.String(), self.SatelEvent.Value)
case satel.ZoneNoViolationTrouble:
return fmt.Sprintf("%s: %t", self.SatelEvent.Type.String(), self.SatelEvent.Value)
case satel.ZoneLongViolationTrouble:
return fmt.Sprintf("%s: %t", self.SatelEvent.Type.String(), self.SatelEvent.Value)
case satel.ArmedPartitionSuppressed:
return fmt.Sprintf("%s: %t", self.SatelEvent.Type.String(), self.SatelEvent.Value)
case satel.ArmedPartition:
return getArmedPartitionStatus(self.SatelEvent.Value)
case satel.PartitionArmedInMode2:
return fmt.Sprintf("%s: %t", self.SatelEvent.Type.String(), self.SatelEvent.Value)
case satel.PartitionArmedInMode3:
return fmt.Sprintf("%s: %t", self.SatelEvent.Type.String(), self.SatelEvent.Value)
case satel.PartitionWith1stCodeEntered:
return fmt.Sprintf("%s: %t", self.SatelEvent.Type.String(), self.SatelEvent.Value)
case satel.PartitionEntryTime:
return fmt.Sprintf("%s: %t", self.SatelEvent.Type.String(), self.SatelEvent.Value)
case satel.PartitionExitTimeOver10s:
return fmt.Sprintf("%s: %t", self.SatelEvent.Type.String(), self.SatelEvent.Value)
case satel.PartitionExitTimeUnder10s:
return fmt.Sprintf("%s: %t", self.SatelEvent.Type.String(), self.SatelEvent.Value)
case satel.PartitionTemporaryBlocked:
return fmt.Sprintf("%s: %t", self.SatelEvent.Type.String(), self.SatelEvent.Value)
case satel.PartitionBlockedForGuardRound:
return fmt.Sprintf("%s: %t", self.SatelEvent.Type.String(), self.SatelEvent.Value)
case satel.PartitionAlarm:
return getPartitionAlarmStatus(self.SatelEvent.Value)
case satel.PartitionFireAlarm:
return fmt.Sprintf("%s: %s", self.SatelEvent.Type.String(), getEmojiWhenTrueIsBad(self.SatelEvent.Value))
case satel.PartitionAlarmMemory:
return fmt.Sprintf("%s: %t", self.SatelEvent.Type.String(), self.SatelEvent.Value)
case satel.PartitionFireAlarmMemory:
return fmt.Sprintf("%s: %t", self.SatelEvent.Type.String(), self.SatelEvent.Value)
case satel.Output:
return fmt.Sprintf("%s: %t", self.SatelEvent.Type.String(), self.SatelEvent.Value)
case satel.DoorOpened:
return fmt.Sprintf("%s: %t", self.SatelEvent.Type.String(), self.SatelEvent.Value)
case satel.DoorOpenedLong:
return fmt.Sprintf("%s: %t", self.SatelEvent.Type.String(), self.SatelEvent.Value)
case satel.StatusBit:
return fmt.Sprintf("%s: %t", self.SatelEvent.Type.String(), self.SatelEvent.Value)
case satel.TroublePart1:
return fmt.Sprintf("%s: %t", self.SatelEvent.Type.String(), self.SatelEvent.Value)
case satel.TroublePart2:
return fmt.Sprintf("%s: %t", self.SatelEvent.Type.String(), self.SatelEvent.Value)
case satel.TroublePart3:
return fmt.Sprintf("%s: %t", self.SatelEvent.Type.String(), self.SatelEvent.Value)
case satel.TroublePart4:
return fmt.Sprintf("%s: %t", self.SatelEvent.Type.String(), self.SatelEvent.Value)
case satel.TroublePart5:
return fmt.Sprintf("%s: %t", self.SatelEvent.Type.String(), self.SatelEvent.Value)
case satel.TroubleMemoryPart1:
return fmt.Sprintf("%s: %t", self.SatelEvent.Type.String(), self.SatelEvent.Value)
case satel.TroubleMemoryPart2:
return fmt.Sprintf("%s: %t", self.SatelEvent.Type.String(), self.SatelEvent.Value)
case satel.TroubleMemoryPart3:
return fmt.Sprintf("%s: %t", self.SatelEvent.Type.String(), self.SatelEvent.Value)
case satel.TroubleMemoryPart4:
return fmt.Sprintf("%s: %t", self.SatelEvent.Type.String(), self.SatelEvent.Value)
case satel.TroubleMemoryPart5:
return fmt.Sprintf("%s: %t", self.SatelEvent.Type.String(), self.SatelEvent.Value)
case satel.PartitionWithViolatedZones:
return fmt.Sprintf("%s: %t", self.SatelEvent.Type.String(), self.SatelEvent.Value)
case satel.ZoneIsolate:
return fmt.Sprintf("%s: %t", self.SatelEvent.Type.String(), self.SatelEvent.Value)
}
panic(fmt.Sprint("Unknown event received: ", self.SatelEvent))
}
func (self SatelMsgContent) IndexDesc() string {
switch self.SatelEvent.Type {
case satel.ZoneViolation:
return fmt.Sprintf("Zone %d", self.SatelEvent.Index)
case satel.ZoneTamper:
return fmt.Sprintf("Zone %d", self.SatelEvent.Index)
case satel.ZoneAlarm:
return fmt.Sprintf("Zone %d", self.SatelEvent.Index)
case satel.ZoneTamperAlarm:
return fmt.Sprintf("Zone %d", self.SatelEvent.Index)
case satel.ZoneAlarmMemory:
return fmt.Sprintf("Zone %d", self.SatelEvent.Index)
case satel.ZoneTamperAlarmMemory:
return fmt.Sprintf("Zone %d", self.SatelEvent.Index)
case satel.ZoneBypass:
return fmt.Sprintf("Zone %d", self.SatelEvent.Index)
case satel.ZoneNoViolationTrouble:
return fmt.Sprintf("Zone %d", self.SatelEvent.Index)
case satel.ZoneLongViolationTrouble:
return fmt.Sprintf("Zone %d", self.SatelEvent.Index)
case satel.ArmedPartitionSuppressed:
return fmt.Sprintf("Partition %d", self.SatelEvent.Index)
case satel.ArmedPartition:
return fmt.Sprintf("Partition %d", self.SatelEvent.Index)
case satel.PartitionArmedInMode2:
return fmt.Sprintf("Partition %d", self.SatelEvent.Index)
case satel.PartitionArmedInMode3:
return fmt.Sprintf("Partition %d", self.SatelEvent.Index)
case satel.PartitionWith1stCodeEntered:
return fmt.Sprintf("Partition %d", self.SatelEvent.Index)
case satel.PartitionEntryTime:
return fmt.Sprintf("Partition %d", self.SatelEvent.Index)
case satel.PartitionExitTimeOver10s:
return fmt.Sprintf("Partition %d", self.SatelEvent.Index)
case satel.PartitionExitTimeUnder10s:
return fmt.Sprintf("Partition %d", self.SatelEvent.Index)
case satel.PartitionTemporaryBlocked:
return fmt.Sprintf("Partition %d", self.SatelEvent.Index)
case satel.PartitionBlockedForGuardRound:
return fmt.Sprintf("Partition %d", self.SatelEvent.Index)
case satel.PartitionAlarm:
return fmt.Sprintf("Partition %d", self.SatelEvent.Index)
case satel.PartitionFireAlarm:
return fmt.Sprintf("Partition %d", self.SatelEvent.Index)
case satel.PartitionAlarmMemory:
return fmt.Sprintf("Partition %d", self.SatelEvent.Index)
case satel.PartitionFireAlarmMemory:
return fmt.Sprintf("Partition %d", self.SatelEvent.Index)
case satel.ZoneIsolate:
return fmt.Sprintf("Zone %d", self.SatelEvent.Index)
}
return fmt.Sprintf("Unknown index: %d", self.SatelEvent.Index)
}