This commit is contained in:
2026-08-27 19:41:00 +03:00
parent de0e8f8ad3
commit 0d80f575c1
389 changed files with 183499 additions and 0 deletions
+150
View File
@@ -0,0 +1,150 @@
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)
}