2022-07-19 09:11:50 +00:00
|
|
|
package dwingest
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"encoding/json"
|
2022-07-25 08:55:25 +00:00
|
|
|
"fmt"
|
2022-07-19 09:11:50 +00:00
|
|
|
"log"
|
|
|
|
"sync"
|
|
|
|
"time"
|
|
|
|
|
2024-06-15 14:31:02 +00:00
|
|
|
"git.joco.dk/snr/fermentord/internal/configuration"
|
|
|
|
"git.joco.dk/snr/fermentord/internal/controllers"
|
|
|
|
"git.joco.dk/snr/fermentord/pkg/temperature"
|
|
|
|
"git.joco.dk/snr/fermentord/pkg/tilt"
|
2022-07-19 09:11:50 +00:00
|
|
|
"github.com/getsentry/sentry-go"
|
2022-07-29 21:53:55 +00:00
|
|
|
"github.com/gofrs/uuid"
|
2022-07-19 09:11:50 +00:00
|
|
|
"github.com/nats-io/nats.go"
|
|
|
|
)
|
|
|
|
|
|
|
|
type DWIngest struct {
|
2022-08-02 14:04:06 +00:00
|
|
|
ConfigUpdates chan configuration.Configuration
|
|
|
|
|
2022-07-19 09:11:50 +00:00
|
|
|
chTemperatureReading chan temperature.TemperatureReading
|
|
|
|
chState chan controllers.ChamberState
|
2022-08-02 18:39:31 +00:00
|
|
|
chEvent chan string
|
2022-07-25 08:55:25 +00:00
|
|
|
|
2022-08-02 05:04:47 +00:00
|
|
|
js nats.JetStream
|
2022-08-02 14:04:06 +00:00
|
|
|
config configuration.Configuration
|
2022-07-29 21:53:55 +00:00
|
|
|
hub *sentry.Hub
|
2022-07-19 09:11:50 +00:00
|
|
|
}
|
|
|
|
|
2022-08-02 14:04:06 +00:00
|
|
|
func NewDWIngest(js nats.JetStream, config configuration.Configuration) *DWIngest {
|
2022-07-19 09:11:50 +00:00
|
|
|
return &DWIngest{
|
|
|
|
chTemperatureReading: make(chan temperature.TemperatureReading, 3600),
|
|
|
|
chState: make(chan controllers.ChamberState, 100),
|
2022-08-02 18:39:31 +00:00
|
|
|
chEvent: make(chan string, 100),
|
2022-07-25 08:55:25 +00:00
|
|
|
hub: sentry.CurrentHub().Clone(),
|
2022-08-02 05:04:47 +00:00
|
|
|
js: js,
|
2022-08-02 14:04:06 +00:00
|
|
|
config: config,
|
|
|
|
ConfigUpdates: make(chan configuration.Configuration, 1),
|
2022-07-19 09:11:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *DWIngest) AddReading(reading temperature.TemperatureReading) {
|
2022-07-24 07:38:40 +00:00
|
|
|
select {
|
|
|
|
case p.chTemperatureReading <- reading:
|
2022-07-25 08:55:25 +00:00
|
|
|
break
|
|
|
|
|
2022-07-24 07:38:40 +00:00
|
|
|
default:
|
2022-07-25 08:55:25 +00:00
|
|
|
err := fmt.Errorf("channel overflow on dwingest temperature channel")
|
|
|
|
p.hub.CaptureException(err)
|
|
|
|
log.Print(err)
|
2022-07-24 07:38:40 +00:00
|
|
|
}
|
2022-07-19 09:11:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (p *DWIngest) AddState(state controllers.ChamberState) {
|
2022-07-24 07:38:40 +00:00
|
|
|
select {
|
|
|
|
case p.chState <- state:
|
2022-07-25 08:55:25 +00:00
|
|
|
break
|
|
|
|
|
2022-07-24 07:38:40 +00:00
|
|
|
default:
|
2022-07-25 08:55:25 +00:00
|
|
|
err := fmt.Errorf("channel overflow on dwingest state channel")
|
|
|
|
p.hub.CaptureException(err)
|
|
|
|
log.Print(err)
|
2022-07-24 07:38:40 +00:00
|
|
|
}
|
2022-07-19 09:11:50 +00:00
|
|
|
}
|
|
|
|
|
2022-08-02 18:39:31 +00:00
|
|
|
func (p *DWIngest) AddEvent(event string) {
|
|
|
|
select {
|
|
|
|
case p.chEvent <- event:
|
|
|
|
break
|
|
|
|
|
|
|
|
default:
|
|
|
|
err := fmt.Errorf("channel overflow on dwingest event channel")
|
|
|
|
p.hub.CaptureException(err)
|
|
|
|
log.Print(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-02 14:04:06 +00:00
|
|
|
func (p *DWIngest) Run(ctx context.Context, wg *sync.WaitGroup) {
|
2022-07-19 09:11:50 +00:00
|
|
|
defer wg.Done()
|
2022-07-25 08:55:25 +00:00
|
|
|
defer p.hub.Flush(10 * time.Second)
|
2022-07-19 09:11:50 +00:00
|
|
|
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case reading := <-p.chTemperatureReading:
|
2022-08-02 18:39:31 +00:00
|
|
|
p.publishTemperatureReading(reading)
|
2022-07-19 09:11:50 +00:00
|
|
|
|
2022-07-23 14:10:34 +00:00
|
|
|
case state := <-p.chState:
|
2022-08-02 18:39:31 +00:00
|
|
|
p.publishState(state)
|
2022-07-19 09:11:50 +00:00
|
|
|
|
2022-08-02 18:39:31 +00:00
|
|
|
case ev := <-p.chEvent:
|
|
|
|
p.publishEvent(ev)
|
|
|
|
|
|
|
|
// TODO Refactor
|
2022-07-23 14:10:34 +00:00
|
|
|
case t := <-tilt.C:
|
2022-08-02 18:39:31 +00:00
|
|
|
p.publishTilt(t)
|
2022-07-19 09:11:50 +00:00
|
|
|
|
2022-08-02 14:04:06 +00:00
|
|
|
case config := <-p.ConfigUpdates:
|
|
|
|
p.config = config
|
|
|
|
|
2022-07-19 09:11:50 +00:00
|
|
|
case <-ctx.Done():
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-07-23 14:10:34 +00:00
|
|
|
|
2022-08-02 18:39:31 +00:00
|
|
|
func (p *DWIngest) publish(subject string, reading any) error {
|
2022-07-23 14:10:34 +00:00
|
|
|
b, err := json.Marshal(reading)
|
|
|
|
if err != nil {
|
2022-07-29 21:53:55 +00:00
|
|
|
p.hub.CaptureException(err)
|
2022-07-23 14:10:34 +00:00
|
|
|
log.Printf("Error marshaling JSON: %v", err)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2024-06-15 13:58:47 +00:00
|
|
|
msgID, err := uuid.NewV7()
|
2022-07-29 21:53:55 +00:00
|
|
|
if err != nil {
|
|
|
|
p.hub.CaptureException(err)
|
|
|
|
log.Print(err)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
msg := nats.NewMsg(subject)
|
|
|
|
msg.Header.Add("Nats-Msg-Id", msgID.String())
|
|
|
|
msg.Data = b
|
2022-08-02 18:39:31 +00:00
|
|
|
_, err = p.js.PublishMsg(msg, nats.AckWait(30*time.Second))
|
2022-07-23 14:10:34 +00:00
|
|
|
if err != nil {
|
2022-07-29 21:53:55 +00:00
|
|
|
p.hub.CaptureException(err)
|
2022-07-26 10:59:17 +00:00
|
|
|
log.Print(err)
|
2022-07-29 21:53:55 +00:00
|
|
|
return err
|
2022-07-23 14:10:34 +00:00
|
|
|
}
|
|
|
|
|
2022-07-29 21:53:55 +00:00
|
|
|
return nil
|
2022-07-23 14:10:34 +00:00
|
|
|
}
|
2022-08-02 18:39:31 +00:00
|
|
|
|
|
|
|
func (p *DWIngest) publishTilt(t tilt.Tilt) error {
|
|
|
|
ev := Tilt{
|
|
|
|
Time: time.Now().UTC(),
|
2022-08-03 13:51:40 +00:00
|
|
|
BrewUUID: p.config.Brew.UUID,
|
2022-08-02 18:39:31 +00:00
|
|
|
Color: string(t.Color()),
|
|
|
|
Gravity: t.Gravity(),
|
|
|
|
Temperature: t.Celsius(),
|
|
|
|
}
|
|
|
|
|
|
|
|
return p.publish(p.config.NATS.Subject.Tilt, ev)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *DWIngest) publishTemperatureReading(reading temperature.TemperatureReading) error {
|
2022-08-03 13:51:40 +00:00
|
|
|
reading.BrewUUID = p.config.Brew.UUID
|
|
|
|
|
2022-08-02 18:39:31 +00:00
|
|
|
return p.publish(p.config.NATS.Subject.Temp, reading)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *DWIngest) publishState(state controllers.ChamberState) error {
|
|
|
|
st := State{
|
2022-08-03 13:51:40 +00:00
|
|
|
Time: time.Now().UTC(),
|
|
|
|
BrewUUID: p.config.Brew.UUID,
|
|
|
|
State: controllers.ChamberStateMap[state],
|
2022-08-02 18:39:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return p.publish(p.config.NATS.Subject.State, st)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *DWIngest) publishEvent(event string) error {
|
|
|
|
ev := Event{
|
2022-08-03 13:51:40 +00:00
|
|
|
Time: time.Now().UTC(),
|
|
|
|
BrewUUID: p.config.Brew.UUID,
|
|
|
|
Event: event,
|
2022-08-02 18:39:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return p.publish(p.config.NATS.Subject.Event, ev)
|
|
|
|
}
|