update
This commit is contained in:
268
flexradio.go
Normal file
268
flexradio.go
Normal file
@ -0,0 +1,268 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var CommandNumber int = 1
|
||||
|
||||
type FlexSpot struct {
|
||||
ID int
|
||||
CommandNumber int
|
||||
FlexSpotNumber int
|
||||
DX string
|
||||
FrequencyMhz string
|
||||
FrequencyHz string
|
||||
Band string
|
||||
Mode string
|
||||
FlexMode string
|
||||
Source string
|
||||
SpotterCallsign string
|
||||
TimeStamp int64
|
||||
UTCTime string
|
||||
LifeTime string
|
||||
Priority string
|
||||
Comment string
|
||||
Color string
|
||||
BackgroundColor string
|
||||
NewDXCC bool
|
||||
NewBand bool
|
||||
NewMode bool
|
||||
Worked bool
|
||||
}
|
||||
|
||||
type FlexClient struct {
|
||||
Address string
|
||||
Port string
|
||||
Timeout time.Duration
|
||||
LogWriter *bufio.Writer
|
||||
Reader *bufio.Reader
|
||||
Writer *bufio.Writer
|
||||
Conn *net.TCPConn
|
||||
SpotChan chan TelnetSpot
|
||||
MsgChan chan string
|
||||
FlexSpotChan chan FlexSpot
|
||||
Repo FlexDXClusterRepository
|
||||
Log *log.Logger
|
||||
TCPServer TCPServer
|
||||
}
|
||||
|
||||
func NewFlexClient(repo FlexDXClusterRepository, TCPServer TCPServer, log *log.Logger) *FlexClient {
|
||||
return &FlexClient{
|
||||
Address: Cfg.Flex.IP,
|
||||
Port: "4992",
|
||||
SpotChan: make(chan TelnetSpot),
|
||||
FlexSpotChan: make(chan FlexSpot),
|
||||
MsgChan: TCPServer.MsgChan,
|
||||
Repo: repo,
|
||||
TCPServer: TCPServer,
|
||||
Log: log,
|
||||
}
|
||||
}
|
||||
|
||||
func (fc *FlexClient) StartFlexClient() {
|
||||
var err error
|
||||
|
||||
addr, err := net.ResolveTCPAddr("tcp", fc.Address+":"+fc.Port)
|
||||
if err != nil {
|
||||
fc.Log.Error("cannot resolve Telnet Client address:", err)
|
||||
}
|
||||
|
||||
fc.LogWriter = bufio.NewWriter(os.Stdout)
|
||||
|
||||
fc.Timeout = 600 * time.Second
|
||||
fc.Conn, err = net.DialTCP("tcp", nil, addr)
|
||||
if err != nil {
|
||||
fc.Log.Error("could not connect to flex radio, exiting...", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fc.Log.Infof("connected to flex radio at %s:%s", fc.Address, fc.Port)
|
||||
|
||||
go func() {
|
||||
for message := range fc.SpotChan {
|
||||
fc.SendSpottoFlex(message)
|
||||
}
|
||||
}()
|
||||
|
||||
fc.Reader = bufio.NewReader(fc.Conn)
|
||||
fc.Writer = bufio.NewWriter(fc.Conn)
|
||||
|
||||
err = fc.Conn.SetKeepAlive(true)
|
||||
if err != nil {
|
||||
fc.Log.Error("error while setting keep alive:", err)
|
||||
}
|
||||
|
||||
go fc.ReadLine()
|
||||
|
||||
subSpotAllCmd := fmt.Sprintf("C%v|sub spot all", CommandNumber)
|
||||
fc.Write(subSpotAllCmd)
|
||||
CommandNumber++
|
||||
|
||||
clrSpotAllCmd := fmt.Sprintf("C%v|spot clear", CommandNumber)
|
||||
fc.Write(clrSpotAllCmd)
|
||||
CommandNumber++
|
||||
|
||||
fc.Log.Debug("Subscribed to spot on FlexRadio and Deleted all spots from panadapter")
|
||||
}
|
||||
|
||||
func (fc *FlexClient) SendSpottoFlex(spot TelnetSpot) {
|
||||
|
||||
freq := FreqMhztoHz(spot.Frequency)
|
||||
|
||||
flexSpot := FlexSpot{
|
||||
CommandNumber: CommandNumber,
|
||||
DX: spot.DX,
|
||||
FrequencyMhz: freq,
|
||||
FrequencyHz: spot.Frequency,
|
||||
Band: spot.Band,
|
||||
Mode: spot.Mode,
|
||||
Source: "FlexDXCluster",
|
||||
SpotterCallsign: spot.Spotter,
|
||||
TimeStamp: time.Now().Unix(),
|
||||
UTCTime: spot.Time,
|
||||
LifeTime: Cfg.Flex.SpotLife,
|
||||
Comment: spot.Comment,
|
||||
Color: "#eaeaea",
|
||||
BackgroundColor: "#000000",
|
||||
Priority: "5",
|
||||
NewDXCC: spot.NewDXCC,
|
||||
NewBand: spot.NewBand,
|
||||
NewMode: spot.NewMode,
|
||||
Worked: spot.CallsignWorked,
|
||||
}
|
||||
|
||||
// If new DXCC
|
||||
if spot.NewDXCC {
|
||||
flexSpot.Color = "#3bf908"
|
||||
flexSpot.Priority = "1"
|
||||
flexSpot.BackgroundColor = "#000000"
|
||||
} else if spot.DX == Cfg.SQLite.Callsign {
|
||||
flexSpot.Color = "#ff0000"
|
||||
flexSpot.Priority = "1"
|
||||
flexSpot.BackgroundColor = "#000000"
|
||||
} else if spot.CallsignWorked {
|
||||
flexSpot.Color = "#000000"
|
||||
flexSpot.BackgroundColor = "#00c0c0"
|
||||
flexSpot.Priority = "5"
|
||||
} else if spot.NewMode {
|
||||
flexSpot.Color = "#f9a908"
|
||||
flexSpot.Priority = "1"
|
||||
flexSpot.BackgroundColor = "#000000"
|
||||
} else if spot.NewBand {
|
||||
flexSpot.Color = "#f9f508"
|
||||
flexSpot.Priority = "1"
|
||||
flexSpot.BackgroundColor = "#000000"
|
||||
} else if !spot.NewBand && !spot.NewMode && !spot.NewDXCC && !spot.CallsignWorked {
|
||||
flexSpot.Color = "#eaeaea"
|
||||
flexSpot.Priority = "5"
|
||||
flexSpot.BackgroundColor = "#000000"
|
||||
}
|
||||
|
||||
flexSpot.Comment = flexSpot.Comment + "[" + flexSpot.Mode + "] [" + flexSpot.SpotterCallsign + "]"
|
||||
flexSpot.Comment = strings.ReplaceAll(flexSpot.Comment, " ", "\u00A0")
|
||||
|
||||
srcFlexSpot, err := fc.Repo.FindDXSameBand(flexSpot)
|
||||
if err != nil {
|
||||
fc.Log.Error("could not find the DX in the database: ", err)
|
||||
}
|
||||
|
||||
// send FlexSpot to HTTP Server
|
||||
fc.FlexSpotChan <- flexSpot
|
||||
|
||||
var stringSpot string
|
||||
if srcFlexSpot.DX == "" {
|
||||
fc.Repo.CreateSpot(flexSpot)
|
||||
stringSpot = fmt.Sprintf("C%v|spot add rx_freq=%v callsign=%s mode=%s source=%s spotter_callsign=%s timestamp=%v lifetime_seconds=%s comment=%s color=%s background_color=%s priority=%s", flexSpot.CommandNumber, flexSpot.FrequencyMhz,
|
||||
flexSpot.DX, flexSpot.Mode, flexSpot.Source, flexSpot.SpotterCallsign, flexSpot.TimeStamp, flexSpot.LifeTime, flexSpot.Comment, flexSpot.Color, flexSpot.BackgroundColor, flexSpot.Priority)
|
||||
CommandNumber++
|
||||
|
||||
} else if srcFlexSpot.DX != "" && srcFlexSpot.Band == flexSpot.Band && srcFlexSpot.FrequencyMhz != flexSpot.FrequencyMhz {
|
||||
fc.Repo.UpdateSpotSameBand(flexSpot)
|
||||
stringSpot = fmt.Sprintf("C%v|spot set %v rx_freq=%v callsign=%s mode=%s source=%s spotter_callsign=%s timestamp=%v lifetime_seconds=%s comment=%s color=%s background_color=%s priority=%s", flexSpot.CommandNumber, srcFlexSpot.FlexSpotNumber, flexSpot.FrequencyMhz,
|
||||
flexSpot.DX, flexSpot.Mode, flexSpot.Source, flexSpot.SpotterCallsign, flexSpot.TimeStamp, flexSpot.LifeTime, flexSpot.Comment, flexSpot.Color, flexSpot.BackgroundColor, flexSpot.Priority)
|
||||
CommandNumber++
|
||||
|
||||
} else if srcFlexSpot.DX != "" && srcFlexSpot.Band != flexSpot.Band {
|
||||
fc.Repo.CreateSpot(flexSpot)
|
||||
stringSpot = fmt.Sprintf("C%v|spot add rx_freq=%v callsign=%s mode=%s source=%s spotter_callsign=%s timestamp=%v lifetime_seconds=%s comment=%s color=%s background_color=%s priority=%s", flexSpot.CommandNumber, flexSpot.FrequencyMhz,
|
||||
flexSpot.DX, flexSpot.Mode, flexSpot.Source, flexSpot.SpotterCallsign, flexSpot.TimeStamp, flexSpot.LifeTime, flexSpot.Comment, flexSpot.Color, flexSpot.BackgroundColor, flexSpot.Priority)
|
||||
CommandNumber++
|
||||
|
||||
}
|
||||
|
||||
if Cfg.General.FlexRadioSpot {
|
||||
fc.SendSpot(stringSpot)
|
||||
}
|
||||
}
|
||||
|
||||
func (fc *FlexClient) SendSpot(stringSpot string) {
|
||||
fc.Write(stringSpot)
|
||||
}
|
||||
|
||||
func (fc *FlexClient) ReadLine() {
|
||||
|
||||
for {
|
||||
message, err := fc.Reader.ReadString(byte('\n'))
|
||||
if err != nil {
|
||||
fc.Log.Errorf("error reading message from flexradio closing program: %s", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// fc.Log.Info(message)
|
||||
|
||||
regRespSpot := *regexp.MustCompile(`R(\d+)\|0\|(\d+)\n`)
|
||||
respSpot := regRespSpot.FindStringSubmatch(message)
|
||||
|
||||
if len(respSpot) > 0 {
|
||||
spot, _ := fc.Repo.FindSpotByCommandNumber(respSpot[1])
|
||||
_, err := fc.Repo.UpdateFlexSpotNumberByID(respSpot[2], *spot)
|
||||
if err != nil {
|
||||
fc.Log.Errorf("could not update flex spot number in database: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Response when a spot is clicked
|
||||
regTriggerSpot := *regexp.MustCompile(`.*spot (\d+) triggered.*\n`)
|
||||
respTrigger := regTriggerSpot.FindStringSubmatch(message)
|
||||
|
||||
if len(respTrigger) > 0 {
|
||||
spot, err := fc.Repo.FindSpotByFlexSpotNumber(respTrigger[1])
|
||||
if err != nil {
|
||||
fc.Log.Errorf("could not find spot by flex spot number in database: %s", err)
|
||||
}
|
||||
|
||||
msg := fmt.Sprintf(`To ALL de %s <%s> : Clicked on "%s" at %s`, Cfg.SQLite.Callsign, spot.UTCTime, spot.DX, spot.FrequencyHz)
|
||||
if len(fc.TCPServer.Clients) > 0 {
|
||||
fc.MsgChan <- msg
|
||||
fc.Log.Infof("%s clicked on spot \"%s\" at %s", Cfg.SQLite.Callsign, spot.DX, spot.FrequencyMhz)
|
||||
}
|
||||
}
|
||||
|
||||
// Status when a spot is deleted
|
||||
regSpotDeleted := *regexp.MustCompile(`S\d+\|spot (\d+) removed`)
|
||||
respDelete := regSpotDeleted.FindStringSubmatch(message)
|
||||
|
||||
if len(respDelete) > 0 {
|
||||
spot, _ := fc.Repo.FindSpotByFlexSpotNumber(respDelete[1])
|
||||
fc.Repo.DeleteSpotByFlexSpotNumber(respDelete[1])
|
||||
fc.Log.Infof("Spot: DX: %s - Spotter: %s - Freq: %s - Band: %s - FlexID: %v deleted from database", spot.DX, spot.SpotterCallsign, spot.FrequencyHz, spot.Band, respDelete[1])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Write sends raw data to remove telnet server
|
||||
func (fc *FlexClient) Write(data string) (n int, err error) {
|
||||
n, err = fc.Writer.Write([]byte(data + "\n"))
|
||||
if err == nil {
|
||||
err = fc.Writer.Flush()
|
||||
}
|
||||
return
|
||||
}
|
Reference in New Issue
Block a user