Skip to content

Commit

Permalink
Merge branch 'Team254:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
ejordan376 authored Nov 5, 2023
2 parents 4f6d2b0 + f80283f commit e122c97
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 16 deletions.
47 changes: 39 additions & 8 deletions field/arena.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package field
import (
"fmt"
"log"
"reflect"
"time"

"github.com/Team254/cheesy-arena/game"
Expand Down Expand Up @@ -82,6 +83,7 @@ type Arena struct {
matchAborted bool
soundsPlayed map[*game.MatchSound]struct{}
breakDescription string
preloadedTeams *[6]*model.Team
}

type AllianceStation struct {
Expand Down Expand Up @@ -176,6 +178,7 @@ func (arena *Arena) LoadSettings() error {
}

arena.accessPoint.SetSettings(
1,
settings.ApType == "vivid",
settings.ApAddress,
settings.ApUsername,
Expand All @@ -185,6 +188,7 @@ func (arena *Arena) LoadSettings() error {
accessPoint1WifiStatuses,
)
arena.accessPoint2.SetSettings(
2,
settings.ApType == "vivid",
settings.Ap2Address,
settings.Ap2Username,
Expand Down Expand Up @@ -311,9 +315,17 @@ func (arena *Arena) LoadMatch(match *model.Match) error {
return err
}

arena.setupNetwork([6]*model.Team{arena.AllianceStations["R1"].Team, arena.AllianceStations["R2"].Team,
arena.AllianceStations["R3"].Team, arena.AllianceStations["B1"].Team, arena.AllianceStations["B2"].Team,
arena.AllianceStations["B3"].Team})
arena.setupNetwork(
[6]*model.Team{
arena.AllianceStations["R1"].Team,
arena.AllianceStations["R2"].Team,
arena.AllianceStations["R3"].Team,
arena.AllianceStations["B1"].Team,
arena.AllianceStations["B2"].Team,
arena.AllianceStations["B3"].Team,
},
false,
)
}

// Reset the arena state and realtime scores.
Expand Down Expand Up @@ -404,9 +416,17 @@ func (arena *Arena) SubstituteTeams(red1, red2, red3, blue1, blue2, blue3 int) e
arena.CurrentMatch.Blue1 = blue1
arena.CurrentMatch.Blue2 = blue2
arena.CurrentMatch.Blue3 = blue3
arena.setupNetwork([6]*model.Team{arena.AllianceStations["R1"].Team, arena.AllianceStations["R2"].Team,
arena.AllianceStations["R3"].Team, arena.AllianceStations["B1"].Team, arena.AllianceStations["B2"].Team,
arena.AllianceStations["B3"].Team})
arena.setupNetwork(
[6]*model.Team{
arena.AllianceStations["R1"].Team,
arena.AllianceStations["R2"].Team,
arena.AllianceStations["R3"].Team,
arena.AllianceStations["B1"].Team,
arena.AllianceStations["B2"].Team,
arena.AllianceStations["B3"].Team,
},
false,
)
arena.MatchLoadNotifier.Notify()

if arena.CurrentMatch.Type != model.Test {
Expand Down Expand Up @@ -790,11 +810,22 @@ func (arena *Arena) preLoadNextMatch() {
log.Printf("Failed to get model for Team %d while pre-loading next match: %s", teamId, err.Error())
}
}
arena.setupNetwork(teams)
arena.setupNetwork(teams, true)
}

// Asynchronously reconfigures the networking hardware for the new set of teams.
func (arena *Arena) setupNetwork(teams [6]*model.Team) {
func (arena *Arena) setupNetwork(teams [6]*model.Team, isPreload bool) {
if isPreload {
arena.preloadedTeams = &teams
} else if arena.preloadedTeams != nil {
preloadedTeams := *arena.preloadedTeams
arena.preloadedTeams = nil
if reflect.DeepEqual(teams, preloadedTeams) {
// Skip configuring the network; this is the same set of teams that was preloaded.
return
}
}

if arena.EventSettings.NetworkSecurityEnabled {
if arena.EventSettings.Ap2TeamChannel == 0 {
// Only one AP is being used.
Expand Down
21 changes: 13 additions & 8 deletions network/access_point.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const (
var accessPointInfoLines = []string{"ESSID: ", "Mode: ", "Tx-Power: ", "Signal: ", "Bit Rate: "}

type AccessPoint struct {
apNumber int
isVividType bool
address string
username string
Expand All @@ -57,12 +58,14 @@ type sshOutput struct {
}

func (ap *AccessPoint) SetSettings(
apNumber int,
isVividType bool,
address, username, password string,
teamChannel int,
networkSecurityEnabled bool,
wifiStatuses [6]*TeamWifiStatus,
) {
ap.apNumber = apNumber
ap.isVividType = isVividType
ap.address = address
ap.username = username
Expand Down Expand Up @@ -145,15 +148,15 @@ func (ap *AccessPoint) configureTeams(teams [6]*model.Team) {
for teamIndex < 6 {
config, err := ap.generateTeamAccessPointConfig(teams[teamIndex], teamIndex+1)
if err != nil {
log.Printf("Failed to generate WiFi configuration: %v", err)
log.Printf("Failed to generate WiFi configuration for AP %d: %v", ap.apNumber, err)
}

command := addConfigurationHeader(config)
log.Printf("Configuring access point with command: %s\n", command)
log.Printf("Configuring AP %d with command: %s\n", ap.apNumber, command)

_, err = ap.runCommand(command)
if err != nil {
log.Printf("Error writing team configuration to AP: %v", err)
log.Printf("Error writing team configuration to AP %d: %v", ap.apNumber, err)
retryCount++
time.Sleep(time.Second * accessPointConfigRetryIntervalSec)
continue
Expand All @@ -171,10 +174,12 @@ func (ap *AccessPoint) configureTeams(teams [6]*model.Team) {
}
err := ap.updateTeamWifiStatuses()
if err == nil && ap.configIsCorrectForTeams(teams) {
log.Printf("Successfully configured WiFi after %d attempts.", retryCount)
log.Printf("Successfully configured AP %d Wi-Fi after %d attempts.", ap.apNumber, retryCount)
break
}
log.Printf("WiFi configuration still incorrect after %d attempts; trying again.", retryCount)
log.Printf(
"WiFi configuration still incorrect on AP %d after %d attempts; trying again.", ap.apNumber, retryCount,
)
}
}

Expand Down Expand Up @@ -209,7 +214,7 @@ func (ap *AccessPoint) updateTeamWifiStatuses() error {

output, err := ap.runCommand("iwinfo")
if err == nil {
logWifiInfo(output)
ap.logWifiInfo(output)
err = ap.decodeWifiInfo(output)
}

Expand Down Expand Up @@ -291,7 +296,7 @@ func (ap *AccessPoint) generateTeamAccessPointConfig(team *model.Team, position
}

// Filters the given output from the "iwiinfo" command on the AP and logs the relevant parts.
func logWifiInfo(wifiInfo string) {
func (ap *AccessPoint) logWifiInfo(wifiInfo string) {
lines := strings.Split(wifiInfo, "\n")
var filteredLines []string
for _, line := range lines {
Expand All @@ -302,7 +307,7 @@ func logWifiInfo(wifiInfo string) {
}
}
}
log.Printf("Access point status:\n%s\n", strings.Join(filteredLines, "\n"))
log.Printf("AP %d status:\n%s\n", ap.apNumber, strings.Join(filteredLines, "\n"))
}

// Parses the given output from the "iwinfo" command on the AP and updates the given status structure with the result.
Expand Down
7 changes: 7 additions & 0 deletions partner/nexus.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@ func (client *NexusClient) GetLineup(tbaMatchKey model.TbaMatchKey) (*[6]int, er
lineup[4], _ = strconv.Atoi(nexusLineup.Blue[1])
lineup[5], _ = strconv.Atoi(nexusLineup.Blue[2])

// Check that each spot is filled with a valid team number; otherwise return an error.
for _, team := range lineup {
if team == 0 {
return nil, fmt.Errorf("Lineup not yet submitted")
}
}

return &lineup, err
}

Expand Down
18 changes: 18 additions & 0 deletions partner/nexus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ func TestGetLineup(t *testing.T) {
assert.Contains(t, r.URL.String(), "/v1/my_event_code/")
if strings.Contains(r.URL.String(), "/v1/my_event_code/p1/lineup") {
w.Write([]byte("{\"red\":[\"101\",\"102\",\"103\"],\"blue\":[\"104\",\"105\",\"106\"]}"))
} else if strings.Contains(r.URL.String(), "/v1/my_event_code/p2/lineup") {
w.Write([]byte("{\"blue\":[\"104\",\"105\",\"106\"]}"))
} else if strings.Contains(r.URL.String(), "/v1/my_event_code/p3/lineup") {
w.Write([]byte("{}"))
} else {
http.Error(w, "Match not found", 404)
}
Expand All @@ -38,4 +42,18 @@ func TestGetLineup(t *testing.T) {
if assert.NotNil(t, err) {
assert.Contains(t, err.Error(), "Match not found")
}

tbaMatchKey = model.TbaMatchKey{CompLevel: "p", SetNumber: 0, MatchNumber: 2}
lineup, err = client.GetLineup(tbaMatchKey)
assert.Nil(t, lineup)
if assert.NotNil(t, err) {
assert.Contains(t, err.Error(), "Lineup not yet submitted")
}

tbaMatchKey = model.TbaMatchKey{CompLevel: "p", SetNumber: 0, MatchNumber: 3}
lineup, err = client.GetLineup(tbaMatchKey)
assert.Nil(t, lineup)
if assert.NotNil(t, err) {
assert.Contains(t, err.Error(), "Lineup not yet submitted")
}
}

0 comments on commit e122c97

Please sign in to comment.