rot finished
This commit is contained in:
267
internal/api/device_manager.go
Normal file
267
internal/api/device_manager.go
Normal file
@@ -0,0 +1,267 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"log"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"git.rouggy.com/rouggy/ShackMaster/internal/config"
|
||||
"git.rouggy.com/rouggy/ShackMaster/internal/devices/antennagenius"
|
||||
"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/webswitch"
|
||||
"git.rouggy.com/rouggy/ShackMaster/internal/services/solar"
|
||||
"git.rouggy.com/rouggy/ShackMaster/internal/services/weather"
|
||||
)
|
||||
|
||||
type DeviceManager struct {
|
||||
config *config.Config
|
||||
|
||||
webSwitch *webswitch.Client
|
||||
powerGenius *powergenius.Client
|
||||
tunerGenius *tunergenius.Client
|
||||
antennaGenius *antennagenius.Client
|
||||
rotatorGenius *rotatorgenius.Client
|
||||
solarClient *solar.Client
|
||||
weatherClient *weather.Client
|
||||
|
||||
hub *Hub
|
||||
statusMu sync.RWMutex
|
||||
lastStatus *SystemStatus
|
||||
|
||||
updateInterval time.Duration
|
||||
stopChan chan struct{}
|
||||
}
|
||||
|
||||
type SystemStatus struct {
|
||||
WebSwitch *webswitch.Status `json:"webswitch"`
|
||||
PowerGenius *powergenius.Status `json:"power_genius"`
|
||||
TunerGenius *tunergenius.Status `json:"tuner_genius"`
|
||||
AntennaGenius *antennagenius.Status `json:"antenna_genius"`
|
||||
RotatorGenius *rotatorgenius.Status `json:"rotator_genius"`
|
||||
Solar *solar.SolarData `json:"solar"`
|
||||
Weather *weather.WeatherData `json:"weather"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
}
|
||||
|
||||
func NewDeviceManager(cfg *config.Config, hub *Hub) *DeviceManager {
|
||||
return &DeviceManager{
|
||||
config: cfg,
|
||||
hub: hub,
|
||||
updateInterval: 1 * time.Second, // Update status every second
|
||||
stopChan: make(chan struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
func (dm *DeviceManager) Initialize() error {
|
||||
log.Println("Initializing device manager...")
|
||||
|
||||
// Initialize WebSwitch
|
||||
dm.webSwitch = webswitch.New(dm.config.Devices.WebSwitch.Host)
|
||||
|
||||
// Initialize Power Genius
|
||||
dm.powerGenius = powergenius.New(
|
||||
dm.config.Devices.PowerGenius.Host,
|
||||
dm.config.Devices.PowerGenius.Port,
|
||||
)
|
||||
|
||||
// Initialize Tuner Genius
|
||||
dm.tunerGenius = tunergenius.New(
|
||||
dm.config.Devices.TunerGenius.Host,
|
||||
dm.config.Devices.TunerGenius.Port,
|
||||
)
|
||||
|
||||
// Initialize Antenna Genius
|
||||
dm.antennaGenius = antennagenius.New(
|
||||
dm.config.Devices.AntennaGenius.Host,
|
||||
dm.config.Devices.AntennaGenius.Port,
|
||||
)
|
||||
|
||||
// Initialize Rotator Genius
|
||||
log.Printf("Initializing RotatorGenius: host=%s port=%d", dm.config.Devices.RotatorGenius.Host, dm.config.Devices.RotatorGenius.Port)
|
||||
dm.rotatorGenius = rotatorgenius.New(
|
||||
dm.config.Devices.RotatorGenius.Host,
|
||||
dm.config.Devices.RotatorGenius.Port,
|
||||
)
|
||||
|
||||
// Initialize Solar data client
|
||||
dm.solarClient = solar.New()
|
||||
|
||||
// Initialize Weather client
|
||||
dm.weatherClient = weather.New(
|
||||
dm.config.Weather.OpenWeatherMapAPIKey,
|
||||
dm.config.Location.Latitude,
|
||||
dm.config.Location.Longitude,
|
||||
)
|
||||
|
||||
// Start device polling in background (non-blocking)
|
||||
go func() {
|
||||
if err := dm.powerGenius.Start(); err != nil {
|
||||
log.Printf("Warning: Failed to start PowerGenius polling: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
if err := dm.tunerGenius.Start(); err != nil {
|
||||
log.Printf("Warning: Failed to start TunerGenius polling: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
if err := dm.antennaGenius.Start(); err != nil {
|
||||
log.Printf("Warning: Failed to start AntennaGenius polling: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
log.Println("About to launch RotatorGenius goroutine...")
|
||||
go func() {
|
||||
log.Println("Starting RotatorGenius polling goroutine...")
|
||||
if err := dm.rotatorGenius.Start(); err != nil {
|
||||
log.Printf("Warning: Failed to start RotatorGenius polling: %v", err)
|
||||
}
|
||||
}()
|
||||
log.Println("RotatorGenius goroutine launched")
|
||||
|
||||
log.Println("Device manager initialized")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dm *DeviceManager) Start() error {
|
||||
log.Println("Starting device monitoring...")
|
||||
go dm.monitorDevices()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dm *DeviceManager) Stop() {
|
||||
log.Println("Stopping device manager...")
|
||||
close(dm.stopChan)
|
||||
|
||||
// Close all connections
|
||||
if dm.powerGenius != nil {
|
||||
dm.powerGenius.Close()
|
||||
}
|
||||
if dm.tunerGenius != nil {
|
||||
dm.tunerGenius.Close()
|
||||
}
|
||||
if dm.antennaGenius != nil {
|
||||
dm.antennaGenius.Close()
|
||||
}
|
||||
if dm.rotatorGenius != nil {
|
||||
dm.rotatorGenius.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func (dm *DeviceManager) monitorDevices() {
|
||||
ticker := time.NewTicker(dm.updateInterval)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
dm.updateStatus()
|
||||
case <-dm.stopChan:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (dm *DeviceManager) updateStatus() {
|
||||
status := &SystemStatus{
|
||||
Timestamp: time.Now(),
|
||||
}
|
||||
|
||||
// Query all devices
|
||||
// WebSwitch - get actual relay states
|
||||
if wsStatus, err := dm.webSwitch.GetStatus(); err == nil {
|
||||
status.WebSwitch = wsStatus
|
||||
} else {
|
||||
log.Printf("WebSwitch error: %v", err)
|
||||
}
|
||||
|
||||
// Power Genius
|
||||
if pgStatus, err := dm.powerGenius.GetStatus(); err == nil {
|
||||
status.PowerGenius = pgStatus
|
||||
} else {
|
||||
log.Printf("Power Genius error: %v", err)
|
||||
}
|
||||
|
||||
// Tuner Genius
|
||||
if tgStatus, err := dm.tunerGenius.GetStatus(); err == nil {
|
||||
status.TunerGenius = tgStatus
|
||||
} else {
|
||||
log.Printf("Tuner Genius error: %v", err)
|
||||
}
|
||||
|
||||
// Antenna Genius
|
||||
if agStatus, err := dm.antennaGenius.GetStatus(); err == nil {
|
||||
status.AntennaGenius = agStatus
|
||||
} else {
|
||||
log.Printf("Antenna Genius error: %v", err)
|
||||
}
|
||||
|
||||
// Rotator Genius
|
||||
if rgStatus, err := dm.rotatorGenius.GetStatus(); err == nil {
|
||||
status.RotatorGenius = rgStatus
|
||||
} else {
|
||||
log.Printf("Rotator Genius error: %v", err)
|
||||
}
|
||||
|
||||
// Solar Data (fetched every 15 minutes, cached)
|
||||
if solarData, err := dm.solarClient.GetSolarData(); err == nil {
|
||||
status.Solar = solarData
|
||||
} else {
|
||||
log.Printf("Solar data error: %v", err)
|
||||
}
|
||||
|
||||
// Weather Data (fetched every 10 minutes, cached)
|
||||
if weatherData, err := dm.weatherClient.GetWeatherData(); err == nil {
|
||||
status.Weather = weatherData
|
||||
} else {
|
||||
log.Printf("Weather data error: %v", err)
|
||||
}
|
||||
|
||||
// Update cached status
|
||||
dm.statusMu.Lock()
|
||||
dm.lastStatus = status
|
||||
dm.statusMu.Unlock()
|
||||
|
||||
// Broadcast to all connected clients
|
||||
if dm.hub != nil {
|
||||
dm.hub.BroadcastStatusUpdate(status)
|
||||
}
|
||||
}
|
||||
|
||||
func (dm *DeviceManager) GetStatus() *SystemStatus {
|
||||
dm.statusMu.RLock()
|
||||
defer dm.statusMu.RUnlock()
|
||||
|
||||
if dm.lastStatus == nil {
|
||||
return &SystemStatus{
|
||||
Timestamp: time.Now(),
|
||||
}
|
||||
}
|
||||
|
||||
return dm.lastStatus
|
||||
}
|
||||
|
||||
// Device control methods
|
||||
func (dm *DeviceManager) WebSwitch() *webswitch.Client {
|
||||
return dm.webSwitch
|
||||
}
|
||||
|
||||
func (dm *DeviceManager) PowerGenius() *powergenius.Client {
|
||||
return dm.powerGenius
|
||||
}
|
||||
|
||||
func (dm *DeviceManager) TunerGenius() *tunergenius.Client {
|
||||
return dm.tunerGenius
|
||||
}
|
||||
|
||||
func (dm *DeviceManager) AntennaGenius() *antennagenius.Client {
|
||||
return dm.antennaGenius
|
||||
}
|
||||
|
||||
func (dm *DeviceManager) RotatorGenius() *rotatorgenius.Client {
|
||||
return dm.rotatorGenius
|
||||
}
|
||||
Reference in New Issue
Block a user