feat: status bar added
This commit is contained in:
@@ -10,6 +10,7 @@ package pst
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -53,6 +54,59 @@ func (c *Client) Park() error {
|
||||
return c.send("<PST><PARK>1</PARK></PST>")
|
||||
}
|
||||
|
||||
// Heading queries PstRotator for the current azimuth. PstRotator's protocol:
|
||||
// send "<PST>AZ?</PST>" to the command port, and it reports the azimuth back
|
||||
// on UDP port+1. So we bind a listener on port+1 first, send the query, then
|
||||
// read the reply. Returns the raw reply too, for diagnostics. err is non-nil
|
||||
// on timeout (no reply) or an unparseable response.
|
||||
func (c *Client) Heading() (az int, raw string, err error) {
|
||||
// Listen on port+1 where PstRotator sends its position report.
|
||||
pc, err := net.ListenPacket("udp4", fmt.Sprintf(":%d", c.Port+1))
|
||||
if err != nil {
|
||||
return 0, "", fmt.Errorf("listen :%d for PstRotator reply: %w", c.Port+1, err)
|
||||
}
|
||||
defer pc.Close()
|
||||
|
||||
if err := c.send("<PST>AZ?</PST>"); err != nil {
|
||||
return 0, "", fmt.Errorf("query PstRotator: %w", err)
|
||||
}
|
||||
|
||||
_ = pc.SetReadDeadline(time.Now().Add(1500 * time.Millisecond))
|
||||
buf := make([]byte, 512)
|
||||
n, _, rerr := pc.ReadFrom(buf)
|
||||
if rerr != nil {
|
||||
return 0, "", fmt.Errorf("no reply on :%d: %w", c.Port+1, rerr)
|
||||
}
|
||||
raw = string(buf[:n])
|
||||
a, ok := parseAzimuth(raw)
|
||||
if !ok {
|
||||
return 0, raw, fmt.Errorf("no azimuth in reply %q", raw)
|
||||
}
|
||||
return a, raw, nil
|
||||
}
|
||||
|
||||
// parseAzimuth extracts the first integer found in a PstRotator reply
|
||||
// ("AZ:123", "123", "<PST><AZIMUTH>123</AZIMUTH></PST>", …) and normalises
|
||||
// it to [0,360).
|
||||
func parseAzimuth(s string) (int, bool) {
|
||||
i := 0
|
||||
for i < len(s) && (s[i] < '0' || s[i] > '9') {
|
||||
i++
|
||||
}
|
||||
if i >= len(s) {
|
||||
return 0, false
|
||||
}
|
||||
j := i
|
||||
for j < len(s) && s[j] >= '0' && s[j] <= '9' {
|
||||
j++
|
||||
}
|
||||
n, err := strconv.Atoi(s[i:j])
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
return ((n % 360) + 360) % 360, true
|
||||
}
|
||||
|
||||
func (c *Client) send(payload string) error {
|
||||
addr := fmt.Sprintf("%s:%d", c.Host, c.Port)
|
||||
conn, err := net.DialTimeout("udp", addr, 2*time.Second)
|
||||
|
||||
Reference in New Issue
Block a user