Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
687a4ef
new changes
ariadnatp Mar 28, 2025
1da60c1
Merge branch 'control-station/gui-booster' of https://github.com/Hype…
andresdlt03 Apr 12, 2025
7ab5f1b
Logic version system, funcs
JESUSJH18 Apr 17, 2025
d1fc482
Comparing current,latest version + message
JESUSJH18 Apr 17, 2025
1eeede3
error panic with empty packets solved
JESUSJH18 Apr 17, 2025
b98801c
redesign and connections with back
ariadnatp Apr 18, 2025
abd8861
Update README.md
msanlli Apr 18, 2025
299b6b9
merge branch 'control-station/gui-booster' of https://github.com/Hype…
ariadnatp Apr 20, 2025
dae783f
error messages in english
JESUSJH18 Apr 20, 2025
65c21c6
fix: removed accidental git repo from adj
ariadnatp Apr 20, 2025
53a8e6d
Merge pull request #242 from HyperloopUPV-H8/backend/sender
g0nz4I0 Apr 28, 2025
d6cc4e0
exception no internet connection no panic
JESUSJH18 Apr 30, 2025
52931b5
new changes
ariadnatp Apr 30, 2025
10c2829
Merge branch 'develop' into control-station/gui-booster
ariadnatp Apr 30, 2025
948ae7c
Merge pull request #246 from HyperloopUPV-H8/control-station/gui-booster
ariadnatp Apr 30, 2025
e7b2e21
Invert folder order
JFisica May 4, 2025
0e474e5
Updater script
JESUSJH18 May 5, 2025
91f2b80
Update go.work and go.mod
JESUSJH18 May 5, 2025
e26cab9
Add board names to data
JFisica May 5, 2025
009286c
errors fixed
JESUSJH18 May 5, 2025
7852c4a
updater in main draft
JESUSJH18 May 6, 2025
32d0f99
Clone a temp ADJ to check accessibility to the repo
JFisica May 9, 2025
650999a
Add changes to pkg
JFisica May 9, 2025
efe7b7c
Check for backend address on data
JFisica May 9, 2025
d28757d
Delete tempPath instead of RepoPath
JFisica May 9, 2025
e5347ea
Update vite alias
JFisica May 9, 2025
381bcba
Merge pull request #254 from HyperloopUPV-H8/backend/logger-qol
JFisica May 9, 2025
8490aca
Merge pull request #253 from HyperloopUPV-H8/backend/adj-internet-con…
JFisica May 9, 2025
3aa7ca9
Merge pull request #255 from HyperloopUPV-H8/ethernet-view/vite-impor…
JFisica May 9, 2025
2138702
updater cases draft
JESUSJH18 May 10, 2025
1b59589
Fix updater execution paths and backend folder detection
JESUSJH18 May 10, 2025
8f51f31
currentVersion variable correction and func unused
JESUSJH18 May 10, 2025
a3ad1fa
VERSION.md
JESUSJH18 May 10, 2025
f308b7e
ensure to stop the backend before deleting it
JESUSJH18 May 10, 2025
a1c8dfa
version and better stop process response
JESUSJH18 May 10, 2025
6cd874f
ensure the process is stopped
JESUSJH18 May 10, 2025
87f5efb
Merge branch 'develop' into backend/version-system
JESUSJH18 May 10, 2025
014c5c3
Merge pull request #241 from HyperloopUPV-H8/backend/version-system
JESUSJH18 May 10, 2025
6679fe5
Merge pull request #256 from HyperloopUPV-H8/main
msanlli May 12, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,6 @@ The main project file is inside `backend/cmd`. Ensure you have the proper `confi

See [CONTRIBUTING.md](./CONTRIBUTING.md) for ways to contribute to the Control Station.

### Authors

- [Juan Martinez Alonso](https://github.com/jmaralo)
- [Marc Sanchis Llinares](https://github.com/msanlli)
- [Sergio Moreno Suay](https://github.com/smorsua)
- [Felipe Zaballa Martinez](https://github.com/lipezaballa)
- [Andrés de la Torre Mora](https://github.com/andresdlt03)
- [Alejandro Losa](https://github.com/Losina24)

### About

HyperloopUPV is a student team based at Universitat Politècnica de València (Spain), which works every year to develop the transport of the future, the hyperloop. Check out [our website](https://hyperloopupv.com/#/)
1 change: 1 addition & 0 deletions backend/cmd/VERSION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2.2.8
1 change: 1 addition & 0 deletions backend/cmd/adj
Submodule adj added at fd87ad
125 changes: 125 additions & 0 deletions backend/cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,24 @@ import (
"flag"
"fmt"

"encoding/json"
"log"
"net"
"net/http"
_ "net/http/pprof"
"os"
"os/exec"
"os/signal"
"path"
"path/filepath"
"runtime"
"runtime/pprof"

"strings"
"time"

"github.com/hashicorp/go-version"

adj_module "github.com/HyperloopUPV-H8/h9-backend/internal/adj"
"github.com/HyperloopUPV-H8/h9-backend/internal/common"
"github.com/HyperloopUPV-H8/h9-backend/internal/pod_data"
Expand Down Expand Up @@ -76,9 +82,25 @@ var enableSNTP = flag.Bool("sntp", false, "enables a simple SNTP server on port
var networkDevice = flag.Int("dev", -1, "index of the network device to use, overrides device prompt")
var blockprofile = flag.Int("blockprofile", 0, "number of block profiles to include")
var playbackFile = flag.String("playback", "", "")
var currentVersion string

func main() {

versionFile := "VERSION.md"
versionData, err := os.ReadFile(versionFile)
if err != nil {
fmt.Fprintf(os.Stderr, "Error reading version file (%s): %v\n", versionFile, err)
os.Exit(1)
}
currentVersion = strings.TrimSpace(string(versionData))

versionFlag := flag.Bool("version", false, "Show the backend version")
flag.Parse()
if *versionFlag {
fmt.Println("Hyperloop UPV Backend Version:", currentVersion)
os.Exit(0)
}

traceFile := initTrace(*traceLevel, *traceFile)
defer traceFile.Close()

Expand All @@ -99,6 +121,89 @@ func main() {
runtime.SetBlockProfileRate(*blockprofile)

config := getConfig("./config.toml")
latestVersionStr, err := getLatestVersionFromGitHub()
if err != nil {
fmt.Println("Warning:", err)
fmt.Println("Skipping version check. Proceeding with the current version:", currentVersion)
} else {
current, err := version.NewVersion(currentVersion)
if err != nil {
fmt.Println("Invalid current version:", err)
return
}

latest, err := version.NewVersion(latestVersionStr)
if err != nil {
fmt.Println("Invalid latest version:", err)
return
}

if latest.GreaterThan(current) {
fmt.Printf("There is a new version available: %s (current version: %s)\n", latest, current)
fmt.Print("Do you want to update? (y/n): ")

var response string
fmt.Scanln(&response)

if strings.ToLower(response) == "y" {
fmt.Println("Launching updater to update the backend...")

// Get the directory of the current executable
execPath, err := os.Executable()
if err != nil {
fmt.Fprintf(os.Stderr, "Error getting executable path: %v\n", err)
os.Exit(1)
}
execDir := filepath.Dir(execPath)

backendPath := filepath.Join(execDir, "..", "..", "backend")

if _, err := os.Stat(backendPath); err == nil {

fmt.Println("Backend folder detected. Building and launching updater...")

updaterPath := filepath.Join(execDir, "..", "..", "updater")

cmd := exec.Command("go", "build", "-o", filepath.Join(updaterPath, "updater.exe"), updaterPath)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
fmt.Fprintf(os.Stderr, "Error building updater: %v\n", err)
os.Exit(1)
}

updaterExe := filepath.Join(updaterPath, "updater.exe")
cmd = exec.Command(updaterExe)
cmd.Dir = updaterPath
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
fmt.Fprintf(os.Stderr, "Error launching updater: %v\n", err)
os.Exit(1)
}
} else {

fmt.Println("Backend folder not detected. Launching existing updater...")

updaterExe := filepath.Join(execDir, "updater.exe")
cmd := exec.Command(updaterExe)
cmd.Dir = filepath.Dir(updaterExe)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
fmt.Fprintf(os.Stderr, "Error launching updater: %v\n", err)
os.Exit(1)
}
}

os.Exit(0)
} else {
fmt.Println("Skipping update. Proceeding with the current version.")
}
} else {
fmt.Printf("You are using the latest version: %s\n", current)
}
}

// <--- ADJ --->

Expand Down Expand Up @@ -590,3 +695,23 @@ func getUDPFilter(addrs []net.IP, backendAddr net.IP, port uint16) string {

return fmt.Sprintf("(%s) and (%s) and (%s or (dst host %s))", udpPort, srcUdpAddrsStr, dstUdpAddrsStr, backendAddr)
}

type GitHubRelease struct {
TagName string `json:"tag_name"`
}

func getLatestVersionFromGitHub() (string, error) {
resp, err := http.Get("https://api.github.com/repos/HyperloopUPV-H8/software/releases/latest")
if err != nil {
return "", fmt.Errorf("unable to connect to the internet: %w", err)
}
defer resp.Body.Close()

var release GitHubRelease
if err := json.NewDecoder(resp.Body).Decode(&release); err != nil {
return "", fmt.Errorf("error decoding GitHub response: %w", err)
}

version := strings.TrimPrefix(release.TagName, "v")
return version, nil
}
3 changes: 2 additions & 1 deletion backend/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ require (
github.com/google/gopacket v1.1.19
github.com/google/uuid v1.3.0
github.com/gorilla/websocket v1.5.0
github.com/hashicorp/go-version v1.7.0
github.com/jmaralo/sntp v0.0.0-20240116111937-45a0a3419272
github.com/pelletier/go-toml/v2 v2.0.7
github.com/pin/tftp/v3 v3.0.0
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c
github.com/rs/zerolog v1.29.0
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1
)
Expand All @@ -29,7 +31,6 @@ require (
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
github.com/pjbgf/sha1cd v0.3.0 // indirect
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
github.com/skeema/knownhosts v1.2.2 // indirect
Expand Down
2 changes: 2 additions & 0 deletions backend/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY=
github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jmaralo/sntp v0.0.0-20240116111937-45a0a3419272 h1:dtQzdBn2P781UxyDPZd1tv4QE29ffpnmJ15qBkXHypY=
Expand Down
22 changes: 22 additions & 0 deletions backend/internal/adj/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package adj

import (
"os"
"path/filepath"

"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
Expand All @@ -21,6 +22,27 @@ func updateRepo(AdjBranch string) error {
SingleBranch: true,
Depth: 1,
}

// Try to clone the ADJ to a temp directory to check for accessibility to the repo (also checks internet connection)
tempPath := filepath.Join(os.TempDir(), "temp_adj")

// Remove previous failed cloning attempts
if err = os.RemoveAll(tempPath); err != nil {
return err
}

// Try to import the ADJ to the temp directory
_, err = git.PlainClone(tempPath, false, cloneOptions)
if err != nil {
// If the clone fails, work with the local ADJ
return nil
}

// If the clone is succesful, delete the temp files
if err = os.RemoveAll(tempPath); err != nil {
return err
}

if _, err = os.Stat(RepoPath); os.IsNotExist(err) {
_, err = git.PlainClone(RepoPath, false, cloneOptions)
if err != nil {
Expand Down
22 changes: 22 additions & 0 deletions backend/pkg/adj/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package adj

import (
"os"
"path/filepath"

"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
Expand All @@ -21,6 +22,27 @@ func updateRepo(AdjBranch string) error {
SingleBranch: true,
Depth: 1,
}

// Try to clone the ADJ to a temp directory to check for accessibility to the repo (also checks internet connection)
tempPath := filepath.Join(os.TempDir(), "temp_adj")

// Remove previous failed cloning attempts
if err = os.RemoveAll(tempPath); err != nil {
return err
}

// Try to import the ADJ to the temp directory
_, err = git.PlainClone(tempPath, false, cloneOptions)
if err != nil {
// If the clone fails, work with the local ADJ
return nil
}

// If the clone is succesful, delete the temp files
if err = os.RemoveAll(tempPath); err != nil {
return err
}

if _, err = os.Stat(RepoPath); os.IsNotExist(err) {
_, err = git.PlainClone(RepoPath, false, cloneOptions)
if err != nil {
Expand Down
3 changes: 2 additions & 1 deletion backend/pkg/logger/data/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,9 @@ func (sublogger *Logger) getFile(valueName data.ValueName) (*file.CSV, error) {

func (sublogger *Logger) createFile(valueName data.ValueName) (*os.File, error) {
filename := path.Join(
"logger", "data",
"logger",
loggerHandler.Timestamp.Format(loggerHandler.TimestampFormat),
"data",
fmt.Sprintf("%s.csv", valueName),
)

Expand Down
3 changes: 2 additions & 1 deletion backend/pkg/logger/order/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,9 @@ func (sublogger *Logger) Start() error {

func (sublogger *Logger) createFile() (*os.File, error) {
filename := path.Join(
"logger", "order",
"logger",
logger.Timestamp.Format(logger.TimestampFormat),
"order",
"order.csv",
)

Expand Down
3 changes: 2 additions & 1 deletion backend/pkg/logger/protection/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,9 @@ func (sublogger *Logger) createFile(boardId abstraction.BoardId) (*os.File, erro
}

filename := path.Join(
"logger", "protections",
"logger",
logger.Timestamp.Format(logger.TimestampFormat),
"protections",
fmt.Sprintf("%s.csv", boardName),
)

Expand Down
3 changes: 2 additions & 1 deletion backend/pkg/logger/state/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,9 @@ func (sublogger *Logger) PushRecord(record abstraction.LoggerRecord) error {

func (sublogger *Logger) createFile(timestamp time.Time) (*file.CSV, error) {
filename := path.Join(
"logger", "state",
"logger",
logger.Timestamp.Format(logger.TimestampFormat),
"state",
fmt.Sprintf("%s.csv", timestamp.Format(logger.TimestampFormat)),
)

Expand Down
21 changes: 19 additions & 2 deletions backend/pkg/vehicle/notification.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ func (vehicle *Vehicle) Notification(notification abstraction.TransportNotificat
}

func (vehicle *Vehicle) handlePacketNotification(notification transport.PacketNotification) error {
var from string
var to string

switch p := notification.Packet.(type) {
case *data.Packet:
Expand All @@ -53,10 +55,25 @@ func (vehicle *Vehicle) handlePacketNotification(notification transport.PacketNo
return errors.Join(fmt.Errorf("update data to frontend (data with id %d from %s to %s)", p.Id(), notification.From, notification.To), err)
}

from_ip := strings.Split(notification.From, ":")[0]
to_ip := strings.Split(notification.To, ":")[0]

if from_ip == "192.168.0.9" {
from = "backend"
} else {
from = vehicle.idToBoardName[uint16(vehicle.ipToBoardId[from_ip])]
}

if to_ip == "192.168.0.9" {
to = "backend"
} else {
to = vehicle.idToBoardName[uint16(vehicle.ipToBoardId[to_ip])]
}

err = vehicle.logger.PushRecord(&data_logger.Record{
Packet: p,
From: notification.From,
To: notification.To,
From: from,
To: to,
Timestamp: notification.Timestamp,
})

Expand Down
1 change: 1 addition & 0 deletions control-station/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const App = () => {
items={[
{ path: '/vehicle', icon: <Wheel /> },
{ path: '/cameras', icon: <Cameras /> },
{ path: '/guiBooster', icon: <Gui /> }
]}
/>
<Outlet />
Expand Down
Loading
Loading