From 38caf711440af5e44e4a2606065e6ab36ab5608e Mon Sep 17 00:00:00 2001 From: alex Date: Mon, 9 Oct 2023 23:16:38 +0200 Subject: [PATCH] job handling --- modules/cache/robots.go | 8 +-- modules/structs/robot.go | 5 ++ routers/api/v1/control/control.go | 96 ++++++++++++++++++++++++- routers/api/v1/permitjoin/permitjoin.go | 2 + routers/api/v1/robot/robot.go | 6 ++ routers/router/router.go | 1 + testclient/testrobot.py | 19 ++++- 7 files changed, 128 insertions(+), 9 deletions(-) diff --git a/modules/cache/robots.go b/modules/cache/robots.go index c48f9b5..78e3ed3 100644 --- a/modules/cache/robots.go +++ b/modules/cache/robots.go @@ -48,17 +48,17 @@ func IsRobotInList(robotId string) bool { return false } -func GetRobotByName(robotId string) structs.Robot { +func GetRobotByName(robotName string) *structs.Robot { rMu.RLock() defer rMu.RUnlock() for _, r := range robots { - if r.Id == robotId { - return *r + if r.Name == robotName { + return r } } - return structs.Robot{} + return nil } func RemoveRobotById(robotId string) { diff --git a/modules/structs/robot.go b/modules/structs/robot.go index 8c20574..5f9801f 100644 --- a/modules/structs/robot.go +++ b/modules/structs/robot.go @@ -10,6 +10,7 @@ type Robot struct { Address string `gorm:"-"` CurrentJobId string CurrentTask string + LastTaskAt time.Time `gorm:"-"` ConnectedAt time.Time `gorm:"-"` CreatedAt time.Time } @@ -48,3 +49,7 @@ type GetRobotsResponse struct { type RobotIdParams struct { RobotId string } + +type RobotNameParams struct { + RobotName string +} diff --git a/routers/api/v1/control/control.go b/routers/api/v1/control/control.go index 2dfac1a..c29f9a2 100644 --- a/routers/api/v1/control/control.go +++ b/routers/api/v1/control/control.go @@ -1,9 +1,10 @@ package control import ( + "encoding/json" "fmt" + "jannex/robot-control-manager/modules/cache" "jannex/robot-control-manager/modules/structs" - "time" "git.ex.umbach.dev/Alex/roese-utils/rsutils" "github.com/gofiber/fiber/v2" @@ -30,6 +31,10 @@ func ControlRex(c *fiber.Ctx) error { // responses: // "200": // description: Control Rex + // "400": + // description: Invalid request body + // "422": + // description: Robot not found log.Info().Msgf("body %v", string(c.Body())) @@ -47,7 +52,94 @@ func ControlRex(c *fiber.Ctx) error { fmt.Printf("y-value: %d\n", *body.Task.Y) } - time.Sleep(10 * time.Second) + robot := cache.GetRobotByName(body.RobotName) + + if robot.Id == "" { + return c.SendStatus(fiber.StatusUnprocessableEntity) + } + + log.Info().Msgf("robot %v", robot) + + // wait until the robot finished the job + + for robot.CurrentJobId != "" { + robot.CurrentJobId = body.JobId + log.Debug().Msgf("robot is free %v", body.JobId) + + controlRexRequest(robot.Address, body) + break + } + + return c.SendStatus(fiber.StatusOK) +} + +func controlRexRequest(address string, body any) { + a := fiber.AcquireAgent() + + // TODO: port only for testing - remove it + url := "http://" + address + ":5000" + "/api/v1/control" + + req := a.Request() + req.Header.SetMethod(fiber.MethodPost) + req.SetRequestURI(url) + req.Header.SetContentType("application/json") + + log.Info().Msgf("url %s", url) + + reqestBodyBytes, err := json.Marshal(body) + + if err != nil { + log.Error().Msgf("Failed to marshal request body, err: %s", err) + return + } + + req.SetBody(reqestBodyBytes) + + if err := a.Parse(); err != nil { + log.Error().Msgf("Failed to parse request, err: %s", err) + return + } + + code, body, _ := a.Bytes() + + log.Info().Msgf("code %v body %v", code, body) +} + +func FinishControlRex(c *fiber.Ctx) error { + // swagger:operation POST /control/0/finish/{robotName} control finishControlRex + // --- + // summary: Finish control Rex. + // description: | + // This is used to finish control Rex. + // consumes: + // - application/json + // produces: + // - application/json + // responses: + // "200": + // description: Finish control Rex + // "400": + // description: Invalid robot name + // "422": + // description: Robot not found + + var params structs.RobotNameParams + + if err := rsutils.ParamsParserHelper(c, ¶ms); err != nil { + return c.SendStatus(fiber.StatusBadRequest) + } + + log.Debug().Msgf("before finish control robot %v", cache.GetRobotByName(params.RobotName).CurrentJobId) + + robot := cache.GetRobotByName(params.RobotName) + + if robot.Id == "" { + return c.SendStatus(fiber.StatusUnprocessableEntity) + } + + robot.CurrentJobId = "" + + log.Debug().Msgf("finish control robot %v", cache.GetRobotByName(params.RobotName).CurrentJobId) return c.SendStatus(fiber.StatusOK) } diff --git a/routers/api/v1/permitjoin/permitjoin.go b/routers/api/v1/permitjoin/permitjoin.go index 8f3d207..0ffa04b 100644 --- a/routers/api/v1/permitjoin/permitjoin.go +++ b/routers/api/v1/permitjoin/permitjoin.go @@ -27,6 +27,8 @@ func SetPermitJoin(c *fiber.Ctx) error { // responses: // "200": // description: Permit join set + // "400": + // description: Invalid request body var params structs.PermitJoinParam diff --git a/routers/api/v1/robot/robot.go b/routers/api/v1/robot/robot.go index 85095d2..62655d9 100644 --- a/routers/api/v1/robot/robot.go +++ b/routers/api/v1/robot/robot.go @@ -36,6 +36,10 @@ func FirstRequest(c *fiber.Ctx) error { // description: Robot identified // schema: // "$ref": "#/definitions/StatusResponse" + // "400": + // description: Invalid request body + // "403": + // description: Permit join is enabled var body structs.FirstRequestBody @@ -118,6 +122,8 @@ func AuthorizeRobot(c *fiber.Ctx) error { // responses: // "200": // description: Robot authorized + // "400": + // description: Invalid robot id // "422": // description: Robot not found diff --git a/routers/router/router.go b/routers/router/router.go index 7770e35..72d0ca0 100644 --- a/routers/router/router.go +++ b/routers/router/router.go @@ -23,6 +23,7 @@ func SetupRoutes(app *fiber.App) { c := v1.Group("/control") c.Post("/0", control.ControlRex) + c.Post("/0/finish/:robotName", control.FinishControlRex) pj := v1.Group("/permitjoin") pj.Post("/:enabled", permitjoin.SetPermitJoin) diff --git a/testclient/testrobot.py b/testclient/testrobot.py index 5d433a4..14fdca5 100644 --- a/testclient/testrobot.py +++ b/testclient/testrobot.py @@ -2,6 +2,7 @@ from flask import Flask, request, jsonify import requests +import time robot_control_server_url = 'http://localhost:50055/v1' @@ -9,6 +10,7 @@ class RexRobot: def __init__(self): self.id = "B24" self.version = "0.0.1" + self.currentJobId = "" # connecting with robot server print("connecting with robot server") @@ -20,13 +22,24 @@ class RexRobot: print("permit join disabled") exit(1) # esp should here restart -RexRobot() + def setCurrentJobId(self, jobId): + self.currentJobId = jobId + +rex = RexRobot() app = Flask(__name__) -@app.route('/api/control', methods=['POST']) +@app.route('/api/v1/control', methods=['POST']) def hello(): - print("Hallo, Welt!") + body = request.get_json() + + print("controlling robot", body) + + time.sleep(15) + + + print("robot controlled") + return jsonify({'status': 'ok'}) if __name__ == '__main__':