ultrabeam

This commit is contained in:
2026-01-10 11:01:40 +01:00
parent 5fd81a641d
commit f172678560
11 changed files with 1118 additions and 2 deletions

View File

@@ -10,6 +10,7 @@ import (
"git.rouggy.com/rouggy/ShackMaster/internal/devices/powergenius"
"git.rouggy.com/rouggy/ShackMaster/internal/devices/rotatorgenius"
"git.rouggy.com/rouggy/ShackMaster/internal/devices/tunergenius"
"git.rouggy.com/rouggy/ShackMaster/internal/devices/ultrabeam"
"git.rouggy.com/rouggy/ShackMaster/internal/devices/webswitch"
"git.rouggy.com/rouggy/ShackMaster/internal/services/solar"
"git.rouggy.com/rouggy/ShackMaster/internal/services/weather"
@@ -23,6 +24,7 @@ type DeviceManager struct {
tunerGenius *tunergenius.Client
antennaGenius *antennagenius.Client
rotatorGenius *rotatorgenius.Client
ultrabeam *ultrabeam.Client
solarClient *solar.Client
weatherClient *weather.Client
@@ -40,6 +42,7 @@ type SystemStatus struct {
TunerGenius *tunergenius.Status `json:"tuner_genius"`
AntennaGenius *antennagenius.Status `json:"antenna_genius"`
RotatorGenius *rotatorgenius.Status `json:"rotator_genius"`
Ultrabeam *ultrabeam.Status `json:"ultrabeam"`
Solar *solar.SolarData `json:"solar"`
Weather *weather.WeatherData `json:"weather"`
Timestamp time.Time `json:"timestamp"`
@@ -85,6 +88,13 @@ func (dm *DeviceManager) Initialize() error {
dm.config.Devices.RotatorGenius.Port,
)
// Initialize Ultrabeam
log.Printf("Initializing Ultrabeam: host=%s port=%d", dm.config.Devices.Ultrabeam.Host, dm.config.Devices.Ultrabeam.Port)
dm.ultrabeam = ultrabeam.New(
dm.config.Devices.Ultrabeam.Host,
dm.config.Devices.Ultrabeam.Port,
)
// Initialize Solar data client
dm.solarClient = solar.New()
@@ -123,6 +133,15 @@ func (dm *DeviceManager) Initialize() error {
}()
log.Println("RotatorGenius goroutine launched")
log.Println("About to launch Ultrabeam goroutine...")
go func() {
log.Println("Starting Ultrabeam polling goroutine...")
if err := dm.ultrabeam.Start(); err != nil {
log.Printf("Warning: Failed to start Ultrabeam polling: %v", err)
}
}()
log.Println("Ultrabeam goroutine launched")
log.Println("Device manager initialized")
return nil
}
@@ -150,6 +169,9 @@ func (dm *DeviceManager) Stop() {
if dm.rotatorGenius != nil {
dm.rotatorGenius.Close()
}
if dm.ultrabeam != nil {
dm.ultrabeam.Stop()
}
}
func (dm *DeviceManager) monitorDevices() {
@@ -207,6 +229,13 @@ func (dm *DeviceManager) updateStatus() {
log.Printf("Rotator Genius error: %v", err)
}
// Ultrabeam
if ubStatus, err := dm.ultrabeam.GetStatus(); err == nil {
status.Ultrabeam = ubStatus
} else {
log.Printf("Ultrabeam error: %v", err)
}
// Solar Data (fetched every 15 minutes, cached)
if solarData, err := dm.solarClient.GetSolarData(); err == nil {
status.Solar = solarData
@@ -265,3 +294,7 @@ func (dm *DeviceManager) AntennaGenius() *antennagenius.Client {
func (dm *DeviceManager) RotatorGenius() *rotatorgenius.Client {
return dm.rotatorGenius
}
func (dm *DeviceManager) Ultrabeam() *ultrabeam.Client {
return dm.ultrabeam
}

View File

@@ -54,6 +54,10 @@ func (s *Server) SetupRoutes() *http.ServeMux {
mux.HandleFunc("/api/rotator/ccw", s.handleRotatorCCW)
mux.HandleFunc("/api/rotator/stop", s.handleRotatorStop)
// Ultrabeam endpoints
mux.HandleFunc("/api/ultrabeam/frequency", s.handleUltrabeamFrequency)
mux.HandleFunc("/api/ultrabeam/retract", s.handleUltrabeamRetract)
// Tuner endpoints
mux.HandleFunc("/api/tuner/operate", s.handleTunerOperate)
mux.HandleFunc("/api/tuner/bypass", s.handleTunerBypass)
@@ -392,6 +396,45 @@ func (s *Server) handlePowerOperate(w http.ResponseWriter, r *http.Request) {
s.sendJSON(w, map[string]string{"status": "ok"})
}
// Ultrabeam handlers
func (s *Server) handleUltrabeamFrequency(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
var req struct {
Frequency int `json:"frequency"` // KHz
Direction int `json:"direction"` // 0=normal, 1=180°, 2=bi-dir
}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "Invalid request body", http.StatusBadRequest)
return
}
if err := s.deviceManager.Ultrabeam().SetFrequency(req.Frequency, req.Direction); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
s.sendJSON(w, map[string]string{"status": "ok"})
}
func (s *Server) handleUltrabeamRetract(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
if err := s.deviceManager.Ultrabeam().Retract(); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
s.sendJSON(w, map[string]string{"status": "ok"})
}
func (s *Server) sendJSON(w http.ResponseWriter, data interface{}) {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(data)