diff --git a/plc/plc.go b/plc/plc.go index 337cb98d..ba877def 100644 --- a/plc/plc.go +++ b/plc/plc.go @@ -18,8 +18,6 @@ type Plc interface { SetAddress(address string) IsEnabled() bool IsHealthy() bool - SetAlternateIOStopState(input int, state bool) - ResetEstops() IoChangeNotifier() *websocket.Notifier Run() GetArmorBlockStatuses() map[string]bool @@ -42,6 +40,9 @@ type Plc interface { SetSubwooferCountdown(redState, blueState bool) SetAmpLights(redLow, redHigh, redCoop, blueLow, blueHigh, blueCoop bool) SetPostMatchSubwooferLights(state bool) + //Freezy Arena + SetAlternateIOStopState(input int, state bool) + ResetEstops() } type ModbusPlc struct { @@ -166,25 +167,6 @@ func (plc *ModbusPlc) SetAddress(address string) { } } -func (plc *ModbusPlc) ResetEstops(){ - plc.inputs[red1EStop] = true - plc.inputs[red2EStop] = true - plc.inputs[red3EStop] = true - plc.inputs[blue1EStop] = true - plc.inputs[blue2EStop] = true - plc.inputs[blue3EStop] = true - plc.inputs[red1AStop] = true - plc.inputs[red2AStop] = true - plc.inputs[red3AStop] = true - plc.inputs[blue1AStop] = true - plc.inputs[blue2AStop] = true - plc.inputs[blue3AStop] = true -} - -// used for Alternate IO stops -func (plc *ModbusPlc) SetAlternateIOStopState(input int, state bool){ - plc.inputs[input] = state -} // Returns true if the PLC is enabled in the configurations. func (plc *ModbusPlc) IsEnabled() bool { return plc.address != "" @@ -527,3 +509,24 @@ func boolToByte(bools []bool) []byte { } return bytes } + +func (plc *ModbusPlc) ResetEstops(){ + plc.inputs[fieldEStop] = true + plc.inputs[red1EStop] = true + plc.inputs[red2EStop] = true + plc.inputs[red3EStop] = true + plc.inputs[blue1EStop] = true + plc.inputs[blue2EStop] = true + plc.inputs[blue3EStop] = true + plc.inputs[red1AStop] = true + plc.inputs[red2AStop] = true + plc.inputs[red3AStop] = true + plc.inputs[blue1AStop] = true + plc.inputs[blue2AStop] = true + plc.inputs[blue3AStop] = true +} + +// used for Alternate IO stops +func (plc *ModbusPlc) SetAlternateIOStopState(input int, state bool){ + plc.inputs[input] = state +} \ No newline at end of file diff --git a/web/alternateIO.go b/web/alternateIO.go new file mode 100644 index 00000000..d9a8deaf --- /dev/null +++ b/web/alternateIO.go @@ -0,0 +1,46 @@ +// Copyright 2018 Team 254. All Rights Reserved. +// Author: pat@patfairbank.com (Patrick Fairbank) +// +// Web handlers for the field monitor display showing robot connection status. + +package web + +import ( + //"github.com/Team254/cheesy-arena/game" + //"github.com/Team254/cheesy-arena/model" + "encoding/json" + "net/http" + +) + + +// RequestPayload represents the structure of the incoming POST data. +type RequestPayload struct { + Channel int `json:"channel"` + State bool `json:"state"` +} + +// Renders the field monitor display. +func (web *Web) eStopStatePostHandler(w http.ResponseWriter, r *http.Request) { + // Ensure the request is a POST request. + if r.Method != http.MethodPost { + http.Error(w, "Invalid request method", http.StatusMethodNotAllowed) + return + } + + // Parse the request body. + var payload []RequestPayload + if err := json.NewDecoder(r.Body).Decode(&payload); err != nil { + http.Error(w, "Invalid request payload", http.StatusBadRequest) + return + } + + for _, item := range payload { + web.arena.Plc.SetAlternateIOStopState(item.Channel, item.State) + } + + // Respond with success. + w.WriteHeader(http.StatusOK) + w.Write([]byte("eStop state updated successfully.")) + +} diff --git a/web/api.go b/web/api.go index 6cf4c0e0..cc080439 100644 --- a/web/api.go +++ b/web/api.go @@ -180,31 +180,6 @@ func (web *Web) rankingsApiHandler(w http.ResponseWriter, r *http.Request) { } } - -// Generates a JSON dump of the arenaStatus, primarily for use by the stack Lights. -func (web *Web) allianceStatusApiHandler(w http.ResponseWriter, r *http.Request) { - // Preload the JSON as a string - var allianceStations = web.arena.AllianceStations - - // Iterate through the slice of AllianceStation structs - for i := range allianceStations { - // If the struct has a Team field, remove or clear it - allianceStations[i].Team = nil // Remove Team information - } - jsonData, err := json.Marshal(allianceStations) - if err != nil { - handleWebErr(w, err) - return - } - - w.Header().Set("Content-Type", "application/json") - _, err = w.Write(jsonData) - if err != nil { - handleWebErr(w, err) - return - } -} - // Generates a JSON dump of the alliances. func (web *Web) alliancesApiHandler(w http.ResponseWriter, r *http.Request) { alliances, err := web.arena.Database.GetAllAlliances() @@ -361,3 +336,31 @@ func (web *Web) generateBracketSvg(w io.Writer, activeMatch *model.Match) error }{bracketType, matchups} return template.ExecuteTemplate(w, "bracket", data) } + +// Generates a JSON dump of the arenaStatus, primarily for use by the stack Lights. +func (web *Web) allianceStatusApiHandler(w http.ResponseWriter, r *http.Request) { + // Preload the JSON as a string + var allianceStations = web.arena.AllianceStations + + // Iterate through the slice of AllianceStation structs + for i := range allianceStations { + // If the struct has a Team field, remove or clear it + allianceStations[i].Team = nil // Remove Team information + } + jsonData, err := json.Marshal(allianceStations) + if err != nil { + handleWebErr(w, err) + return + } + + w.Header().Set("Content-Type", "application/json") + _, err = w.Write(jsonData) + if err != nil { + handleWebErr(w, err) + return + } +} + +func (web *Web) eStopApiHandler(w http.ResponseWriter, r *http.Request) { + +} diff --git a/web/web.go b/web/web.go index e9d4837b..fd497b85 100644 --- a/web/web.go +++ b/web/web.go @@ -136,11 +136,9 @@ func (web *Web) newHandler() http.Handler { mux.HandleFunc("GET /api/bracket/svg", web.bracketSvgApiHandler) mux.HandleFunc("GET /api/matches/{type}", web.matchesApiHandler) mux.HandleFunc("GET /api/rankings", web.rankingsApiHandler) - mux.HandleFunc("GET /api/allianceStatus", web.allianceStatusApiHandler) mux.HandleFunc("GET /api/sponsor_slides", web.sponsorSlidesApiHandler) mux.HandleFunc("GET /api/teams/{teamId}/avatar", web.teamAvatarsApiHandler) mux.HandleFunc("GET /display", web.placeholderDisplayHandler) - mux.HandleFunc("GET /field_monitor_help", web.fieldMonitorDisplayHelpHandler) mux.HandleFunc("GET /display/websocket", web.placeholderDisplayWebsocketHandler) mux.HandleFunc("GET /displays/alliance_station", web.allianceStationDisplayHandler) mux.HandleFunc("GET /displays/alliance_station/websocket", web.allianceStationDisplayWebsocketHandler) @@ -230,6 +228,10 @@ func (web *Web) newHandler() http.Handler { mux.HandleFunc("GET /setup/teams/generate_wpa_keys", web.teamsGenerateWpaKeysHandler) mux.HandleFunc("GET /setup/teams/progress", web.teamsUpdateProgressBarHandler) mux.HandleFunc("GET /setup/teams/refresh", web.teamsRefreshHandler) + //Freezy Arena + mux.HandleFunc("GET /api/allianceStatus", web.allianceStatusApiHandler) + mux.HandleFunc("GET /field_monitor_help", web.fieldMonitorDisplayHelpHandler) + mux.HandleFunc("POST /freezy/eStopState", web.eStopStatePostHandler) return mux }