151 lines
3.9 KiB
Go
151 lines
3.9 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"context"
|
|
"flag"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"spektr/internal/config"
|
|
"spektr/internal/discovery"
|
|
grpcclient "spektr/internal/grpc"
|
|
pb "spektr/internal/grpc/pb"
|
|
)
|
|
|
|
func main() {
|
|
configPath := flag.String("config", "configs/config.yaml", "path to config file")
|
|
addrOverride := flag.String("addr", "192.168.1.10:50051", "explicit gRPC address")
|
|
flag.Parse()
|
|
|
|
cfg, err := config.Load(*configPath)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
scanner := bufio.NewScanner(os.Stdin)
|
|
for {
|
|
addr := resolveAddr(cfg, *addrOverride)
|
|
client, err := waitForClient(addr)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
fmt.Println("Подключено к", addr)
|
|
printHelp()
|
|
|
|
lostConnection := false
|
|
for {
|
|
fmt.Print("> ")
|
|
if !scanner.Scan() {
|
|
_ = client.Close()
|
|
return
|
|
}
|
|
|
|
line := strings.TrimSpace(scanner.Text())
|
|
switch {
|
|
case line == "", line == "help":
|
|
printHelp()
|
|
case line == "exit":
|
|
_ = client.Close()
|
|
return
|
|
case line == "av":
|
|
lostConnection = !sendAndPrint(client, &pb.ClientMessage{RequestId: requestID(), Payload: &pb.ClientMessage_Av{Av: &pb.AvCommand{}}})
|
|
case line == "get":
|
|
lostConnection = !sendAndPrint(client, &pb.ClientMessage{RequestId: requestID(), Payload: &pb.ClientMessage_GetFrequency{GetFrequency: &pb.GetFrequencyCommand{}}})
|
|
case strings.HasPrefix(line, "af "):
|
|
value := strings.TrimSpace(strings.TrimPrefix(line, "af "))
|
|
mhz, err := strconv.ParseUint(value, 10, 32)
|
|
if err != nil {
|
|
fmt.Println("invalid frequency")
|
|
continue
|
|
}
|
|
lostConnection = !sendAndPrint(client, &pb.ClientMessage{RequestId: requestID(), Payload: &pb.ClientMessage_SetFrequency{SetFrequency: &pb.SetFrequencyCommand{Frequency: uint32(mhz)}}})
|
|
default:
|
|
fmt.Println("unknown command")
|
|
}
|
|
|
|
if lostConnection {
|
|
_ = client.Close()
|
|
fmt.Println("Соединение потеряно, ожидаю демон...")
|
|
time.Sleep(2 * time.Second)
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func resolveAddr(cfg config.Config, override string) string {
|
|
if override != "" {
|
|
return override
|
|
}
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
|
|
defer cancel()
|
|
|
|
discovered, err := discovery.Discover(ctx, cfg.DiscoveryPort)
|
|
if err == nil && discovered != "" {
|
|
return discovered
|
|
}
|
|
|
|
return cfg.GRPCAdvertiseAddr
|
|
}
|
|
|
|
func waitForClient(addr string) (*grpcclient.Client, error) {
|
|
for {
|
|
dialCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
client, err := grpcclient.Dial(dialCtx, addr)
|
|
cancel()
|
|
if err == nil {
|
|
return client, nil
|
|
}
|
|
|
|
fmt.Println("Демон недоступен, жду подключение...")
|
|
time.Sleep(2 * time.Second)
|
|
}
|
|
}
|
|
|
|
func printHelp() {
|
|
fmt.Println("Доступные команды:")
|
|
fmt.Println(" av - проверить связь с устройством")
|
|
fmt.Println(" af <мгц> - установить частоту, например: af 1880")
|
|
fmt.Println(" get - показать текущую частоту")
|
|
fmt.Println(" help - показать список команд")
|
|
fmt.Println(" exit - выйти из CLI")
|
|
}
|
|
|
|
func sendAndPrint(client *grpcclient.Client, msg *pb.ClientMessage) bool {
|
|
resp, err := client.Send(msg)
|
|
if err != nil {
|
|
fmt.Println("error:", err)
|
|
return false
|
|
}
|
|
|
|
switch payload := resp.GetPayload().(type) {
|
|
case *pb.ServerMessage_Av:
|
|
fmt.Printf("HW: %s FW: %s\n", payload.Av.GetHw(), payload.Av.GetSw())
|
|
case *pb.ServerMessage_SetFrequency:
|
|
fmt.Println("ok")
|
|
case *pb.ServerMessage_GetFrequency:
|
|
fmt.Printf("%s\n", formatFrequencyResponse(payload.GetFrequency.GetFrequency()))
|
|
case *pb.ServerMessage_Error:
|
|
fmt.Println("error:", payload.Error.GetMessage())
|
|
default:
|
|
fmt.Println("unknown response")
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func requestID() string {
|
|
return strconv.FormatInt(time.Now().UnixNano(), 10)
|
|
}
|
|
|
|
func formatFrequencyResponse(freq uint32) string {
|
|
return fmt.Sprintf("f%07d", freq*100)
|
|
}
|