Make PLC inputs/outputs on field setup page update in realtime.

This commit is contained in:
Patrick Fairbank
2018-08-18 21:01:42 -07:00
parent 11b1b6a943
commit 347ad04885
5 changed files with 115 additions and 23 deletions

View File

@@ -9,6 +9,7 @@ import (
"github.com/Team254/cheesy-arena/field"
"github.com/Team254/cheesy-arena/led"
"github.com/Team254/cheesy-arena/model"
"log"
"net/http"
"strconv"
)
@@ -28,17 +29,13 @@ func (web *Web) fieldGetHandler(w http.ResponseWriter, r *http.Request) {
data := struct {
*model.EventSettings
AllianceStationDisplays map[string]string
Inputs []bool
InputNames []string
Registers []uint16
RegisterNames []string
Coils []bool
CoilNames []string
CurrentLedMode led.Mode
LedModeNames map[led.Mode]string
}{web.arena.EventSettings, web.arena.AllianceStationDisplays, plc.Inputs[:], plc.GetInputNames(), plc.Registers[:],
plc.GetRegisterNames(), plc.Coils[:], plc.GetCoilNames(), web.arena.ScaleLeds.GetCurrentMode(),
led.ModeNames}
}{web.arena.EventSettings, web.arena.AllianceStationDisplays, plc.GetInputNames(), plc.GetRegisterNames(),
plc.GetCoilNames(), web.arena.ScaleLeds.GetCurrentMode(), led.ModeNames}
err = template.ExecuteTemplate(w, "base", data)
if err != nil {
handleWebErr(w, err)
@@ -88,3 +85,54 @@ func (web *Web) fieldTestPostHandler(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/setup/field", 303)
}
// The websocket endpoint for sending realtime updates to the field setup page.
func (web *Web) fieldWebsocketHandler(w http.ResponseWriter, r *http.Request) {
if !web.userIsAdmin(w, r) {
return
}
websocket, err := NewWebsocket(w, r)
if err != nil {
handleWebErr(w, err)
return
}
defer websocket.Close()
plcIoChangeListener := web.arena.Plc.IoChangeNotifier.Listen()
defer close(plcIoChangeListener)
// Send the PLC status immediately upon connection.
data := struct {
Inputs []bool
Registers []uint16
Coils []bool
}{web.arena.Plc.Inputs[:], web.arena.Plc.Registers[:], web.arena.Plc.Coils[:]}
err = websocket.Write("plcIoChange", data)
if err != nil {
log.Printf("Websocket error: %s", err)
return
}
for {
var messageType string
var message interface{}
select {
case _, ok := <-plcIoChangeListener:
if !ok {
return
}
messageType = "plcIoChange"
message = struct {
Inputs []bool
Registers []uint16
Coils []bool
}{web.arena.Plc.Inputs[:], web.arena.Plc.Registers[:], web.arena.Plc.Coils[:]}
}
err = websocket.Write(messageType, message)
if err != nil {
// The client has probably closed the connection; nothing to do here.
return
}
}
}