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 { Messages []satel.BasicEventElement } type SatelMessage struct { 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{ 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) }