corrected autotrack still working when deactivated

change track to radio
This commit is contained in:
2026-01-12 21:36:01 +01:00
parent 414d802d37
commit 431c17347d
4 changed files with 87 additions and 271 deletions

View File

@@ -20,10 +20,6 @@ type Client struct {
connMu sync.Mutex // For connection management
writeMu sync.Mutex // For writing to connection (separate from reads)
interlockID string
interlockName string
interlockMu sync.RWMutex
lastStatus *Status
statusMu sync.RWMutex
@@ -34,27 +30,20 @@ type Client struct {
stopChan chan struct{}
// Callbacks
checkTransmitAllowed func() bool
onFrequencyChange func(freqMHz float64)
onFrequencyChange func(freqMHz float64)
}
func New(host string, port int, interlockName string) *Client {
return &Client{
host: host,
port: port,
interlockName: interlockName,
stopChan: make(chan struct{}),
host: host,
port: port,
stopChan: make(chan struct{}),
lastStatus: &Status{
Connected: false,
},
}
}
// SetTransmitCheckCallback sets the callback function to check if transmit is allowed
func (c *Client) SetTransmitCheckCallback(callback func() bool) {
c.checkTransmitAllowed = callback
}
// SetFrequencyChangeCallback sets the callback function called when frequency changes
func (c *Client) SetFrequencyChangeCallback(callback func(freqMHz float64)) {
c.onFrequencyChange = callback
@@ -104,10 +93,11 @@ func (c *Client) Start() error {
// Start message listener
go c.messageLoop()
// Create interlock (no sleep needed, connection is synchronous)
if err := c.createInterlock(); err != nil {
log.Printf("FlexRadio: Failed to create interlock: %v", err)
return err
// Subscribe to slice updates for frequency tracking
log.Println("FlexRadio: Subscribing to slice updates...")
_, err := c.sendCommand("sub slice all")
if err != nil {
log.Printf("FlexRadio: Warning - failed to subscribe to slices: %v", err)
}
return nil
@@ -223,7 +213,6 @@ func (c *Client) messageLoop() {
continue
}
log.Printf("FlexRadio RX: %s", line)
c.handleMessage(line)
}
@@ -233,7 +222,6 @@ func (c *Client) messageLoop() {
func (c *Client) handleMessage(msg string) {
// Response format: R<seq>|<status>|<data>
if strings.HasPrefix(msg, "R") {
c.handleResponse(msg)
return
}
@@ -256,36 +244,6 @@ func (c *Client) handleMessage(msg string) {
}
}
func (c *Client) handleResponse(msg string) {
// Format: R<seq>|<status>|<data>
parts := strings.SplitN(msg, "|", 3)
if len(parts) < 2 {
return
}
status := parts[1]
if status != "0" {
log.Printf("FlexRadio: Command error: status=%s", status)
return
}
// Check if this is interlock create response
if len(parts) >= 3 && parts[2] != "" {
// This is likely the interlock ID
interlockID := parts[2]
c.interlockMu.Lock()
c.interlockID = interlockID
c.interlockMu.Unlock()
log.Printf("FlexRadio: Interlock created with ID: %s", interlockID)
c.statusMu.Lock()
c.lastStatus.InterlockID = interlockID
c.lastStatus.InterlockState = InterlockStateReady
c.statusMu.Unlock()
}
}
func (c *Client) handleStatus(msg string) {
// Format: S<handle>|<key>=<value> ...
parts := strings.SplitN(msg, "|", 2)
@@ -306,10 +264,6 @@ func (c *Client) handleStatus(msg string) {
}
}
// Check for interlock state changes
if state, ok := statusMap["state"]; ok && strings.Contains(msg, "interlock") {
c.handleInterlockState(state, statusMap)
}
// Check for slice updates (frequency changes)
if strings.Contains(msg, "slice") {
if rfFreq, ok := statusMap["RF_frequency"]; ok {
@@ -334,75 +288,6 @@ func (c *Client) handleStatus(msg string) {
}
}
func (c *Client) handleInterlockState(state string, statusMap map[string]string) {
log.Printf("FlexRadio: Interlock state changed to: %s", state)
c.statusMu.Lock()
c.lastStatus.InterlockState = state
c.statusMu.Unlock()
// Handle PTT_REQUESTED - this is where we decide to allow or block transmit
if state == "PTT_REQUESTED" {
c.handlePTTRequest()
}
}
func (c *Client) handlePTTRequest() {
log.Println("FlexRadio: PTT requested, checking if transmit is allowed...")
c.interlockMu.RLock()
interlockID := c.interlockID
c.interlockMu.RUnlock()
if interlockID == "" {
log.Println("FlexRadio: No interlock ID, cannot respond to PTT request")
return
}
// Check if transmit is allowed via callback
allowed := true
if c.checkTransmitAllowed != nil {
allowed = c.checkTransmitAllowed()
}
if allowed {
log.Println("FlexRadio: Transmit ALLOWED - sending ready")
c.sendCommand(fmt.Sprintf("interlock ready %s", interlockID))
// Update state immediately for UI
c.statusMu.Lock()
c.lastStatus.InterlockState = InterlockStateReady
c.statusMu.Unlock()
} else {
log.Println("FlexRadio: Transmit BLOCKED - sending not_ready")
c.sendCommand(fmt.Sprintf("interlock not_ready %s", interlockID))
// Update state immediately for UI
c.statusMu.Lock()
c.lastStatus.InterlockState = InterlockStateNotReady
c.statusMu.Unlock()
}
}
func (c *Client) createInterlock() error {
log.Printf("FlexRadio: Creating interlock with name: %s", c.interlockName)
// Format: interlock create type=ant name=<name> serial=<serial>
cmd := fmt.Sprintf("interlock create type=ant name=%s serial=ShackMaster", c.interlockName)
_, err := c.sendCommand(cmd)
if err != nil {
return fmt.Errorf("failed to create interlock: %w", err)
}
// Subscribe to slice updates for frequency tracking
log.Println("FlexRadio: Subscribing to slice updates...")
_, err = c.sendCommand("sub slice all")
if err != nil {
log.Printf("FlexRadio: Warning - failed to subscribe to slices: %v", err)
}
return nil
}
func (c *Client) GetStatus() (*Status, error) {
c.statusMu.RLock()
defer c.statusMu.RUnlock()
@@ -419,32 +304,3 @@ func (c *Client) GetStatus() (*Status, error) {
return &status, nil
}
// ForceInterlockState proactively sends ready/not_ready to the radio
// This is used when external conditions change (e.g., antenna motors start/stop)
func (c *Client) ForceInterlockState(allowed bool) {
c.interlockMu.RLock()
interlockID := c.interlockID
c.interlockMu.RUnlock()
if interlockID == "" {
log.Println("FlexRadio: No interlock ID, cannot force state")
return
}
if allowed {
log.Println("FlexRadio: PROACTIVE - Sending ready (motors stopped)")
c.sendCommand(fmt.Sprintf("interlock ready %s", interlockID))
// Update state immediately for UI
c.statusMu.Lock()
c.lastStatus.InterlockState = InterlockStateReady
c.statusMu.Unlock()
} else {
log.Println("FlexRadio: PROACTIVE - Sending not_ready (motors moving)")
c.sendCommand(fmt.Sprintf("interlock not_ready %s", interlockID))
// Update state immediately for UI
c.statusMu.Lock()
c.lastStatus.InterlockState = InterlockStateNotReady
c.statusMu.Unlock()
}
}