package main // HRDLog "ON AIR" — publishing the live frequency, mode and rig on hrdlog.net, // so the site shows "F4BPO is on air 14,074,000 FT8 IC-7300" while the station // is operating. // // The endpoint and its field names come from HRDLog's own library // (github.com/iw1qlh/HRDLOG-net-library), not from reading someone's traffic. import ( "context" "strings" "time" "hamlog/internal/applog" "hamlog/internal/extsvc" ) // onAirEvery is how often the status is refreshed. HRDLog drops a station from // the on-air list when it stops hearing from it, so this is a heartbeat, not a // change notification. const onAirEvery = 2 * time.Minute // hrdlogOnAirLoop publishes while the option is on and the rig is readable. func (a *App) hrdlogOnAirLoop() { defer func() { _ = recover() }() // never crash the app from a status broadcast t := time.NewTicker(onAirEvery) defer t.Stop() for range t.C { a.publishHRDLogOnAir() } } // publishHRDLogOnAir sends one update. Silent when switched off, unconfigured, // or when the rig has nothing to report — an announcement with no frequency // would say the operator is on air on 0 Hz. func (a *App) publishHRDLogOnAir() { cfg := a.loadExternalServices().HRDLog if !cfg.OnAir || strings.TrimSpace(cfg.Callsign) == "" || strings.TrimSpace(cfg.Code) == "" { return } if a.cat == nil { return } st := a.cat.State() if !st.Connected || st.FreqHz <= 0 { return } // The rig NAME as the operator knows it — that string is what the site // displays. The active profile's MyRig first, since it is what every QSO is // stamped with; the CAT backend's own model only when the profile has none. radio := "" if a.profiles != nil { if pr, err := a.profiles.Active(a.ctx); err == nil { radio = strings.TrimSpace(pr.MyRig) } } if radio == "" { radio = strings.TrimSpace(st.Rig) } ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) defer cancel() msg, err := extsvc.SendHRDLogOnAir(ctx, nil, cfg.Callsign, cfg.Code, st.FreqHz, st.Mode, radio) if err != nil { // Logged, never surfaced: this is a broadcast the operator did not ask // for at this instant, and a toast every two minutes on a flaky link // would be worse than the missing status. applog.Printf("hrdlog on-air: %v (%s)", err, msg) return } applog.Printf("hrdlog on-air: %s %.3f MHz %s (%s) — %s", cfg.Callsign, float64(st.FreqHz)/1e6, st.Mode, radio, msg) }