evcc-io/push/hub.go
2021-08-21 12:53:25 +02:00

81 lines
1.8 KiB
Go

package push
import (
"time"
"github.com/evcc-io/evcc/util"
)
// Event is a notification event
type Event struct {
LoadPoint *int // optional loadpoint id
Event string
}
// Hub subscribes to event notifications and sends them to client devices
type Hub struct {
definitions map[string]EventTemplate
sender []Sender
cache *util.Cache
}
// NewHub creates push hub with definitions and receiver
func NewHub(definitions map[string]EventTemplate, cache *util.Cache) *Hub {
h := &Hub{
definitions: definitions,
cache: cache,
}
return h
}
// Add adds a sender to the list of senders
func (h *Hub) Add(sender Sender) {
h.sender = append(h.sender, sender)
}
// apply applies the event template to the content to produce the actual message
func (h *Hub) apply(ev Event, template string) (string, error) {
attr := make(map[string]interface{})
// let cache catch up, refs reverted https://github.com/evcc-io/evcc/pull/445
time.Sleep(100 * time.Millisecond)
// get all values from cache
for _, p := range h.cache.All() {
if p.LoadPoint == nil || ev.LoadPoint == p.LoadPoint {
attr[p.Key] = p.Val
}
}
return util.ReplaceFormatted(template, attr)
}
// Run is the Hub's main publishing loop
func (h *Hub) Run(events <-chan Event) {
for ev := range events {
if len(h.sender) == 0 {
continue
}
definition, ok := h.definitions[ev.Event]
if !ok {
continue
}
title, err := h.apply(ev, definition.Title)
if err != nil {
log.ERROR.Printf("invalid title template for %s: %v", ev.Event, err)
continue
}
msg, err := h.apply(ev, definition.Msg)
if err != nil {
log.ERROR.Printf("invalid message template for %s: %v", ev.Event, err)
continue
}
for _, sender := range h.sender {
go sender.Send(title, msg)
}
}
}