hayai/wolfx/wolfx.go

177 lines
4.6 KiB
Go
Raw Normal View History

2024-08-25 12:20:20 +02:00
package wolfx
import (
"encoding/json"
"fmt"
"hayai/config"
"hayai/constants"
"hayai/seismo"
"hayai/utils"
"log"
"net/url"
"os"
"time"
"embed"
2024-08-25 14:12:59 +02:00
"github.com/faiface/beep"
"github.com/faiface/beep/flac"
2024-08-25 12:20:20 +02:00
"github.com/faiface/beep/speaker"
"github.com/gen2brain/beeep"
"github.com/gorilla/websocket"
"github.com/sqweek/dialog"
)
2024-08-25 14:12:59 +02:00
//go:embed assets/alertv3-sat.flac
2024-08-25 12:20:20 +02:00
var alertSoundFile embed.FS
type TypeMessage struct {
Type string
}
type Issue struct {
Source string
Status string
}
type Accuracy struct {
Epicenter string
Depth string
Magnitude string
}
type MaxIntChange struct {
String string
Reason string
}
type WarnArea struct {
Chiiki string
Shindo1 string
Shindo2 string
Time string
Type string
2024-08-25 13:52:26 +02:00
Arrive bool
2024-08-25 12:20:20 +02:00
}
type JMAEEW struct {
Type string
Title string
CodeType string
Issue Issue
EventID string
Serial int
AnnouncedTime string
OriginTime string
Hypocenter string
Latitude float64
Longitude float64
Magunitude float64
Depth int
MaxIntensity string
Accuracy Accuracy
MaxIntChange MaxIntChange
WarnArea []WarnArea
IsSea bool
IsTraining bool
IsAssumption bool
IsWarn bool
IsFinal bool
IsCancel bool
OriginalText string
Pond string
}
var LastRetry time.Time
2024-08-25 12:20:20 +02:00
func Listen() {
// Init sound
2024-08-25 14:12:59 +02:00
alertSound, err := alertSoundFile.Open("assets/alertv3-sat.flac")
2024-08-25 12:20:20 +02:00
utils.CheckError(err)
defer alertSound.Close()
2024-08-25 14:12:59 +02:00
streamer, format, err := flac.Decode(alertSound)
2024-08-25 12:20:20 +02:00
utils.CheckError(err)
defer streamer.Close()
// Listen
u := url.URL{Scheme: "wss", Host: constants.WSHost, Path: "/all_eew"}
for {
log.Printf("connecting to %s", u.String())
c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
if err != nil {
log.Print("dial:", err)
time.Sleep(time.Duration(config.Config.RetryConnectionEveryXS) * time.Second)
continue
}
2024-08-25 12:20:20 +02:00
defer c.Close()
2024-08-25 12:20:20 +02:00
done := make(chan struct{})
2024-08-25 12:20:20 +02:00
defer close(done)
2024-08-25 12:20:20 +02:00
log.Printf("connected.")
for {
_, message, err := c.ReadMessage()
utils.CheckError(err)
if message == nil {
log.Printf("connection lost.")
if time.Since(LastRetry) < time.Duration(config.Config.RetryConnectionEveryXS)*time.Second {
time.Sleep(time.Duration(config.Config.RetryConnectionEveryXS) * time.Second)
LastRetry = time.Now()
}
break
2024-08-25 12:20:20 +02:00
}
var typeMessage TypeMessage
if config.Config.TestWarning {
message = constants.TestMessage
}
json.Unmarshal(message, &typeMessage)
if typeMessage.Type == "jma_eew" {
log.Printf("recv: %s", message)
var jmaeew JMAEEW
json.Unmarshal(message, &jmaeew)
if !jmaeew.IsWarn && config.Config.OnlyWarnings {
continue
2024-08-25 12:20:20 +02:00
}
equivalentMagnitude := seismo.CalculateEquivalentMagnitude(jmaeew.Magunitude, jmaeew.Latitude, jmaeew.Longitude, config.Config.Latitude, config.Config.Longitude)
if config.Config.IssueWarningAtAnyMagnitude || config.Config.IssueWarningAtEquivalentMagnitude < equivalentMagnitude {
2024-08-25 13:52:26 +02:00
warnareas := ""
if len(jmaeew.WarnArea) != 0 {
warnareas += "\nWarnings issued for:"
}
for _, warnarea := range jmaeew.WarnArea {
warnareas += fmt.Sprintf("\n - %s (at %s) [Shindo %s / %s] [%s]", warnarea.Chiiki, warnarea.Time, warnarea.Shindo1, warnarea.Shindo2, warnarea.Type)
}
alert_body := fmt.Sprintf("Epicenter: %s\nMagnitude %0.1f\nApproximately magnitude %0.1f at your location%s\n\nStrong shaking is expected soon.\nStay calm and seek shelter nearby.\n\nOrigin time: %s JST\nAnnouncement time: %s JST\nDepth: %dkm\nCoordinates: %0.1f, %0.1f\n\nSource: %s\nStatus: %s\n\n%s", jmaeew.Hypocenter, jmaeew.Magunitude, equivalentMagnitude, warnareas, jmaeew.OriginTime, jmaeew.AnnouncedTime, jmaeew.Depth, jmaeew.Latitude, jmaeew.Longitude, jmaeew.Issue.Source, jmaeew.Issue.Status, jmaeew.OriginalText)
if config.Config.IssuePopup {
go dialog.Message("%s", alert_body).Title("Early Earthquake Warning!").Info()
}
2024-08-25 12:20:20 +02:00
if config.Config.IssueNotification {
homedir, err := os.UserHomeDir()
utils.CheckError(err)
err = beeep.Notify("Early Earthquake Warning!", alert_body, homedir+"/.icons/actions/scalable/dialog-warning.svg")
utils.CheckError(err)
}
2024-08-25 12:20:20 +02:00
if config.Config.OpenWebPages {
utils.OpenURL(constants.OpenURLA)
utils.OpenURL(constants.OpenURLB)
}
2024-08-25 12:20:20 +02:00
if config.Config.IssueWarningSound {
speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
2024-08-25 12:20:20 +02:00
streamer.Seek(0)
2024-08-25 14:12:59 +02:00
donep := make(chan bool)
speaker.Play(beep.Seq(streamer, beep.Callback(func() {
donep <- true
})))
<-donep
speaker.Close()
2024-08-25 12:20:20 +02:00
}
}
}
}
}
}