connecting robot

main
alex 2023-10-09 20:22:02 +02:00
parent 0ce099c0b1
commit aa85119dad
21 changed files with 881 additions and 44 deletions

2
go.mod
View File

@ -3,7 +3,7 @@ module jannex/robot-control-manager
go 1.21.0
require (
git.ex.umbach.dev/Alex/roese-utils v1.0.8
git.ex.umbach.dev/Alex/roese-utils v1.0.10
github.com/gofiber/fiber/v2 v2.49.2
github.com/joho/godotenv v1.5.1
gorm.io/driver/mysql v1.5.1

4
go.sum
View File

@ -1,5 +1,9 @@
git.ex.umbach.dev/Alex/roese-utils v1.0.8 h1:ph18N52R9UsJ0AsJW95W6afa9qKlMDMh60xE4wlfFi8=
git.ex.umbach.dev/Alex/roese-utils v1.0.8/go.mod h1:tjq6m6lNFo0TzAvq8jHhlK48IGxi+SrlrQwf9WYg408=
git.ex.umbach.dev/Alex/roese-utils v1.0.9 h1:MshCYgFc22t4h9KjfE4hvuHbUcrqkbzxC3J4nqGoyuk=
git.ex.umbach.dev/Alex/roese-utils v1.0.9/go.mod h1:tjq6m6lNFo0TzAvq8jHhlK48IGxi+SrlrQwf9WYg408=
git.ex.umbach.dev/Alex/roese-utils v1.0.10 h1:pAtvtWrDSuVKGyusKPG093+DsnNc2ek/6k/9Qgz7acE=
git.ex.umbach.dev/Alex/roese-utils v1.0.10/go.mod h1:tjq6m6lNFo0TzAvq8jHhlK48IGxi+SrlrQwf9WYg408=
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=

View File

@ -16,6 +16,7 @@ package main
import (
"fmt"
"jannex/robot-control-manager/modules/cache"
"jannex/robot-control-manager/modules/config"
"jannex/robot-control-manager/modules/database"
"jannex/robot-control-manager/modules/utils"
@ -28,6 +29,8 @@ import (
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/cors"
"github.com/gofiber/fiber/v2/middleware/logger"
rcmlogger "jannex/robot-control-manager/modules/logger"
)
func init() {
@ -68,5 +71,10 @@ func main() {
router.SetupRoutes(app)
// TODO: Remove this
cache.SetPermitJoin(true)
rcmlogger.AddSystemLog("Server started")
app.Listen(config.Cfg.Host + ":" + config.Cfg.Port)
}

20
modules/cache/permitjoin.go vendored Normal file
View File

@ -0,0 +1,20 @@
package cache
import "sync"
var permitJoin bool
var pjMu sync.RWMutex
func SetPermitJoin(pj bool) {
pjMu.Lock()
defer pjMu.Unlock()
permitJoin = pj
}
func IsPermitJoinEnabled() bool {
pjMu.RLock()
defer pjMu.RUnlock()
return permitJoin
}

View File

@ -5,19 +5,65 @@ import (
"sync"
)
var robots []*structs.Robot
var robots = make(map[string]*structs.Robot)
var rMu sync.RWMutex
func AddRobot(robot *structs.Robot) {
rMu.Lock()
defer rMu.Unlock()
robots = append(robots, robot)
robots[robot.Id] = robot
}
func GetRobots() []*structs.Robot {
func GetRobots() map[string]*structs.Robot {
rMu.RLock()
defer rMu.RUnlock()
return robots
}
func GetAllRobots() []structs.Robot {
rMu.RLock()
defer rMu.RUnlock()
var r []structs.Robot
for _, v := range robots {
r = append(r, *v)
}
return r
}
func IsRobotInList(robotId string) bool {
rMu.RLock()
defer rMu.RUnlock()
for _, r := range robots {
if r.Id == robotId {
return true
}
}
return false
}
func GetRobotByName(robotId string) structs.Robot {
rMu.RLock()
defer rMu.RUnlock()
for _, r := range robots {
if r.Id == robotId {
return *r
}
}
return structs.Robot{}
}
func RemoveRobotById(robotId string) {
rMu.Lock()
defer rMu.Unlock()
delete(robots, robotId)
}

71
modules/cache/unauthorizedrobots.go vendored Normal file
View File

@ -0,0 +1,71 @@
package cache
import (
"jannex/robot-control-manager/modules/structs"
"sync"
)
// list of robots that are connected for the first time
// to this server and are not yet in the database (authorized)
var unauthorizedRobots = make(map[string]*structs.UnauthorizedRobot)
var urMu sync.RWMutex
func AddUnauthorizedRobot(robot *structs.UnauthorizedRobot) {
urMu.Lock()
defer urMu.Unlock()
unauthorizedRobots[robot.Id] = robot
}
func GetUnauthorizedRobots() map[string]*structs.UnauthorizedRobot {
urMu.RLock()
defer urMu.RUnlock()
return unauthorizedRobots
}
func GetAllUnauthorizedRobots() []structs.UnauthorizedRobot {
urMu.RLock()
defer urMu.RUnlock()
var r []structs.UnauthorizedRobot
for _, v := range unauthorizedRobots {
r = append(r, *v)
}
return r
}
func IsUnauthorizedRobotInList(robotId string) bool {
urMu.RLock()
defer urMu.RUnlock()
for _, r := range unauthorizedRobots {
if r.Id == robotId {
return true
}
}
return false
}
func GetUnauthorizedRobotById(robotId string) structs.UnauthorizedRobot {
urMu.RLock()
defer urMu.RUnlock()
for _, r := range unauthorizedRobots {
if r.Id == robotId {
return *r
}
}
return structs.UnauthorizedRobot{}
}
func RemoveUnauthorizedRobotById(robotId string) {
urMu.Lock()
defer urMu.Unlock()
delete(unauthorizedRobots, robotId)
}

View File

@ -36,10 +36,11 @@ func LoadConfig() {
}
Cfg = Config{
Debug: os.Getenv("DEBUG") == "true",
ColorizedOutput: os.Getenv("COLORIZED_OUTPUT") == "true",
Host: os.Getenv("HOST"),
Port: os.Getenv("PORT"),
Debug: os.Getenv("DEBUG") == "true",
ColorizedOutput: os.Getenv("COLORIZED_OUTPUT") == "true",
Host: os.Getenv("HOST"),
Port: os.Getenv("PORT"),
LogManagerServerUrl: os.Getenv("LOG_MANAGER_SERVER_URL"),
MariaDB: MariaDB{
Hostname: os.Getenv("MARIADB_HOSTNAME"),
Port: os.Getenv("MARIADB_PORT"),

View File

@ -3,6 +3,7 @@ package database
import (
"fmt"
"jannex/robot-control-manager/modules/config"
"jannex/robot-control-manager/modules/structs"
"gorm.io/driver/mysql"
"gorm.io/gorm"
@ -33,4 +34,6 @@ func InitDatabase() {
}
DB = db
db.AutoMigrate(&structs.Robot{})
}

View File

@ -6,16 +6,19 @@ import (
"git.ex.umbach.dev/Alex/roese-utils/rslogger"
"github.com/gofiber/fiber/v2"
"github.com/rs/zerolog/log"
)
func AddSystemLog(format string, v ...any) {
go rslogger.LogManagerRequestClient(fiber.MethodPost, config.Cfg.LogManagerServerUrl+"/v1/log", rslogger.LogManagerRequestBody{
Type: "robots",
log.Info().Msgf("serverurl %v", config.Cfg.LogManagerServerUrl)
go rslogger.LogManagerRequestClient(fiber.MethodPost, rslogger.LogManagerRequestBody{
Type: "robot-control-manager",
Logs: []string{"I " + rslogger.GetTime() + fmt.Sprintf(format, v...)}})
}
func AddRexLog(format string, v ...any) {
go rslogger.LogManagerRequestClient(fiber.MethodPost, config.Cfg.LogManagerServerUrl+"/v1/log", rslogger.LogManagerRequestBody{
Type: "rex",
func AddRexLog(rexId, format string, v ...any) {
go rslogger.LogManagerRequestClient(fiber.MethodPost, rslogger.LogManagerRequestBody{
Type: "rex-" + rexId,
Logs: []string{"I " + rslogger.GetTime() + fmt.Sprintf(format, v...)}})
}

View File

@ -0,0 +1,16 @@
package structs
// swagger:model ControlBody
type ControlBody struct {
RobotName string
JobId string
JobName string
Task ControlTask
}
type ControlTask struct {
X *int `json:",omitempty"`
Y *int `json:",omitempty"`
Z *int `json:",omitempty"`
ConnectedModule *int `json:",omitempty"`
}

View File

@ -0,0 +1,5 @@
package structs
type PermitJoinParam struct {
Enabled uint8
}

View File

@ -4,21 +4,32 @@ import "time"
type Robot struct {
Id string
Type uint8 // robot type (0 = rex, 1 = yeet)
Type uint8
Name string
Status uint8
Address string
Address string `gorm:"-"`
CurrentJobId string
CurrentTask string
ConnectedAt time.Time
ConnectedAt time.Time `gorm:"-"`
CreatedAt time.Time
}
type UnauthorizedRobot struct {
Id string
Type uint8
Address string
ConnectedAt time.Time
CreatedAt time.Time
}
// swagger:model FirstRequestBody
type FirstRequestBody struct {
// robot id
Id string
// robot type (0 = rex, 1 = yeet)
// robot type
Type uint8
// used firmware version of the robot
FirmwareVersion string
// connected modul like a gripper
//ConnectedModul uint8
}
@ -27,3 +38,13 @@ type FirstRequestBody struct {
type StatusResponse struct {
Status string
}
// swagger:model GetRobotsResponse
type GetRobotsResponse struct {
Robots []Robot
UnauthorizedRobots []UnauthorizedRobot
}
type RobotIdParams struct {
RobotId string
}

View File

@ -6,3 +6,19 @@ const (
RobotStatusError
RobotStatusOffline
)
const (
RobotTypeRex uint8 = iota
RobotTypeYeet
)
func GetRobotTypeString(t uint8) string {
switch t {
case RobotTypeRex:
return "rex"
case RobotTypeYeet:
return "yeet"
default:
return "unknown"
}
}

View File

@ -16,9 +16,8 @@
"host": "jannex",
"basePath": "/v1",
"paths": {
"/robots": {
"post": {
"description": "This is the first request from the robot. It will be used to identify the robot.\n",
"/api/v1/robots": {
"get": {
"consumes": [
"application/json"
],
@ -28,8 +27,94 @@
"tags": [
"robots"
],
"summary": "Get all robots",
"operationId": "getRobots",
"responses": {
"200": {
"description": "",
"schema": {
"$ref": "#/definitions/GetRobotsResponse"
}
}
}
}
},
"/control/0": {
"post": {
"description": "This is used to control Rex.\n",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"control"
],
"summary": "Control Rex.",
"operationId": "controlRex",
"parameters": [
{
"description": "Control Rex body.",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/ControlBody"
}
}
],
"responses": {
"200": {
"description": "Control Rex"
}
}
}
},
"/permitjoin/{enabled}": {
"post": {
"description": "This is used to enable or disable permit join.\n",
"tags": [
"permitjoin"
],
"summary": "Set permit join.",
"operationId": "setPermitJoin",
"parameters": [
{
"description": "Enable or disable permit join. 0 = disable, 1 = enable.",
"name": "enabled",
"in": "path",
"required": true,
"schema": {
"type": "integer",
"enum": [
0,
1
]
}
}
],
"responses": {
"200": {
"description": "Permit join set"
}
}
}
},
"/robot": {
"post": {
"description": "This is the first request from the robot. It will be used to identify the robot.\n",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"robot"
],
"summary": "First request from robot.",
"operationId": "robotsFirstRequest",
"operationId": "robotFirstRequest",
"parameters": [
{
"description": "First request body.",
@ -43,32 +128,233 @@
],
"responses": {
"200": {
"description": "OK",
"description": "Robot identified",
"schema": {
"$ref": "#/definitions/SuccessResponse"
"$ref": "#/definitions/StatusResponse"
}
}
}
}
},
"/robot/authorize/{robotId}": {
"post": {
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"robot"
],
"summary": "Authorize robot.",
"operationId": "robotAuthorize",
"parameters": [
{
"description": "Robot id.",
"name": "robotId",
"in": "params",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Robot authorized"
},
"422": {
"description": "Robot not found"
}
}
}
},
"/robot/deny/{robotId}": {
"delete": {
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"robot"
],
"summary": "Deny unauthorized robot.",
"operationId": "robotDenyUnauthorizedRobot",
"parameters": [
{
"description": "Robot id.",
"name": "robotId",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Robot denied"
},
"400": {
"description": "Invalid robot id"
}
}
}
},
"/robot/{robotId}": {
"delete": {
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"robot"
],
"summary": "Delete robot.",
"operationId": "robotDelete",
"parameters": [
{
"description": "Robot id.",
"name": "robotId",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Robot deleted"
},
"400": {
"description": "Invalid robot id"
}
}
}
}
},
"definitions": {
"ControlBody": {
"type": "object",
"properties": {
"JobId": {
"type": "string"
},
"JobName": {
"type": "string"
},
"RobotName": {
"type": "string"
},
"Task": {
"$ref": "#/definitions/ControlTask"
}
},
"x-go-package": "jannex/robot-control-manager/modules/structs"
},
"ControlTask": {
"type": "object",
"properties": {
"ConnectedModule": {
"type": "integer",
"format": "int64"
},
"X": {
"type": "integer",
"format": "int64"
},
"Y": {
"type": "integer",
"format": "int64"
},
"Z": {
"type": "integer",
"format": "int64"
}
},
"x-go-package": "jannex/robot-control-manager/modules/structs"
},
"FirstRequestBody": {
"type": "object",
"properties": {
"FirmwareVersion": {
"description": "used firmware version of the robot",
"type": "string"
},
"Id": {
"description": "robot id",
"type": "string"
},
"Type": {
"description": "robot type (0 = rex, 1 = yeet)",
"description": "robot type",
"type": "integer",
"format": "uint8"
}
},
"x-go-package": "jannex/robot-control-manager/modules/structs"
},
"SuccessResponse": {
"GetRobotsResponse": {
"type": "object",
"properties": {
"Robots": {
"type": "array",
"items": {
"$ref": "#/definitions/Robot"
}
},
"UnauthorizedRobots": {
"type": "array",
"items": {
"$ref": "#/definitions/UnauthorizedRobot"
}
}
},
"x-go-package": "jannex/robot-control-manager/modules/structs"
},
"Robot": {
"type": "object",
"properties": {
"Address": {
"type": "string"
},
"ConnectedAt": {
"type": "string",
"format": "date-time"
},
"CreatedAt": {
"type": "string",
"format": "date-time"
},
"CurrentJobId": {
"type": "string"
},
"CurrentTask": {
"type": "string"
},
"Id": {
"type": "string"
},
"Name": {
"type": "string"
},
"Status": {
"type": "integer",
"format": "uint8"
},
"Type": {
"type": "integer",
"format": "uint8"
}
},
"x-go-package": "jannex/robot-control-manager/modules/structs"
},
"StatusResponse": {
"type": "object",
"properties": {
"Status": {
@ -76,6 +362,30 @@
}
},
"x-go-package": "jannex/robot-control-manager/modules/structs"
},
"UnauthorizedRobot": {
"type": "object",
"properties": {
"Address": {
"type": "string"
},
"ConnectedAt": {
"type": "string",
"format": "date-time"
},
"CreatedAt": {
"type": "string",
"format": "date-time"
},
"Id": {
"type": "string"
},
"Type": {
"type": "integer",
"format": "uint8"
}
},
"x-go-package": "jannex/robot-control-manager/modules/structs"
}
}
}

View File

@ -1,14 +1,53 @@
package control
import (
"fmt"
"jannex/robot-control-manager/modules/structs"
"time"
"git.ex.umbach.dev/Alex/roese-utils/rsutils"
"github.com/gofiber/fiber/v2"
"github.com/rs/zerolog/log"
)
func Move(c *fiber.Ctx) error {
func ControlRex(c *fiber.Ctx) error {
// swagger:operation POST /control/0 control controlRex
// ---
// summary: Control Rex.
// description: |
// This is used to control Rex.
// consumes:
// - application/json
// produces:
// - application/json
// parameters:
// - in: body
// name: body
// description: Control Rex body.
// required: true
// schema:
// "$ref": "#/definitions/ControlBody"
// responses:
// "200":
// description: Control Rex
log.Info().Msgf("body %v", string(c.Body()))
var body structs.ControlBody
if err := rsutils.BodyParserHelper(c, &body); err != nil {
return c.SendStatus(fiber.StatusBadRequest)
}
log.Info().Msgf("ControlRex: %v", body)
if body.Task.Y == nil {
fmt.Println("y not sent")
} else {
fmt.Printf("y-value: %d\n", *body.Task.Y)
}
time.Sleep(10 * time.Second)
return c.JSON(structs.StatusResponse{Status: "ok"})
return c.SendStatus(fiber.StatusOK)
}

View File

@ -0,0 +1,52 @@
package permitjoin
import (
"jannex/robot-control-manager/modules/cache"
"jannex/robot-control-manager/modules/logger"
"jannex/robot-control-manager/modules/structs"
"git.ex.umbach.dev/Alex/roese-utils/rsutils"
"github.com/gofiber/fiber/v2"
"github.com/rs/zerolog/log"
)
func SetPermitJoin(c *fiber.Ctx) error {
// swagger:operation POST /permitjoin/{enabled} permitjoin setPermitJoin
// ---
// summary: Set permit join.
// description: |
// This is used to enable or disable permit join.
// parameters:
// - in: path
// name: enabled
// description: Enable or disable permit join. 0 = disable, 1 = enable.
// required: true
// schema:
// type: integer
// enum: [0, 1]
// responses:
// "200":
// description: Permit join set
var params structs.PermitJoinParam
if err := rsutils.ParamsParserHelper(c, &params); err != nil {
return c.SendStatus(fiber.StatusBadRequest)
}
if params.Enabled == 0 {
cache.SetPermitJoin(false)
log.Debug().Msgf("Permit join disabled")
logger.AddSystemLog("Permit join disabled")
} else {
cache.SetPermitJoin(true)
log.Debug().Msgf("Permit join enabled")
logger.AddSystemLog("Permit join enabled")
}
return c.SendStatus(fiber.StatusOK)
}

View File

@ -2,16 +2,20 @@ package robot
import (
"jannex/robot-control-manager/modules/cache"
"jannex/robot-control-manager/modules/database"
"jannex/robot-control-manager/modules/logger"
"jannex/robot-control-manager/modules/structs"
"jannex/robot-control-manager/modules/utils"
"time"
"git.ex.umbach.dev/Alex/roese-utils/rsutils"
"github.com/gofiber/fiber/v2"
"github.com/google/uuid"
"github.com/rs/zerolog/log"
)
func FirstRequest(c *fiber.Ctx) error {
// swagger:operation POST /robots robots robotsFirstRequest
// swagger:operation POST /robot robot robotFirstRequest
// ---
// summary: First request from robot.
// description: |
@ -29,7 +33,7 @@ func FirstRequest(c *fiber.Ctx) error {
// "$ref": "#/definitions/FirstRequestBody"
// responses:
// "200":
// description: OK
// description: Robot identified
// schema:
// "$ref": "#/definitions/StatusResponse"
@ -39,14 +43,187 @@ func FirstRequest(c *fiber.Ctx) error {
return c.SendStatus(fiber.StatusBadRequest)
}
cache.AddRobot(&structs.Robot{
Id: body.Id,
Type: body.Type,
Address: c.IP(),
ConnectedAt: time.Now(),
})
var foundRobot structs.Robot
log.Info().Msgf("Added robot %s (%v). Robots %v", body.Id, body.Type, cache.GetRobots())
database.DB.First(&foundRobot, "id = ?", body.Id)
if !cache.IsPermitJoinEnabled() && foundRobot.Id == "" {
log.Info().Msgf("Permit join is enabled")
logger.AddSystemLog("Unauthorized robot tried to connect with id %v and type %v", body.Id, utils.GetRobotTypeString(body.Type))
return c.SendStatus(fiber.StatusForbidden)
}
if foundRobot.Id == "" {
now := time.Now()
newUnauthorizedRobot := structs.UnauthorizedRobot{
Id: body.Id,
Type: body.Type,
Address: c.IP(),
ConnectedAt: now,
CreatedAt: now,
}
cache.AddUnauthorizedRobot(&newUnauthorizedRobot)
log.Debug().Msgf("Added unauthorized robot %s (%v)", body.Id, body.Type)
logger.AddSystemLog("Unauthorized robot connected with id %v and type %v", body.Id, utils.GetRobotTypeString(body.Type))
// TODO: send robot to sse
} else {
newRobot := structs.Robot{
Id: body.Id,
Type: body.Type,
Name: foundRobot.Name,
Status: utils.RobotStatusIdle,
Address: c.IP(),
CurrentJobId: "",
CurrentTask: "",
ConnectedAt: time.Now(),
CreatedAt: foundRobot.CreatedAt,
}
cache.AddRobot(&newRobot)
log.Debug().Msgf("Added robot %s (%v)", body.Id, body.Type)
logger.AddSystemLog("Robot connected with id %v and type %v", body.Id, utils.GetRobotTypeString(body.Type))
// TODO: send robot to sse
}
log.Debug().Msgf("robots %v", cache.GetUnauthorizedRobots())
return c.JSON(structs.StatusResponse{Status: "ok"})
}
func AuthorizeRobot(c *fiber.Ctx) error {
// swagger:operation POST /robot/authorize/{robotId} robot robotAuthorize
// ---
// summary: Authorize robot.
// consumes:
// - application/json
// produces:
// - application/json
// parameters:
// - in: params
// name: robotId
// description: Robot id.
// required: true
// schema:
// type: string
// responses:
// "200":
// description: Robot authorized
// "422":
// description: Robot not found
var params structs.RobotIdParams
if err := rsutils.ParamsParserHelper(c, &params); err != nil {
return c.SendStatus(fiber.StatusBadRequest)
}
if !cache.IsUnauthorizedRobotInList(params.RobotId) {
return c.SendStatus(fiber.StatusUnprocessableEntity)
}
unauthorizedRobot := cache.GetUnauthorizedRobotById(params.RobotId)
if unauthorizedRobot.Id == "" {
return c.SendStatus(fiber.StatusUnprocessableEntity)
}
newRobot := structs.Robot{
Id: params.RobotId,
Type: unauthorizedRobot.Type,
Name: uuid.New().String(),
Address: unauthorizedRobot.Address,
Status: utils.RobotStatusIdle,
ConnectedAt: unauthorizedRobot.ConnectedAt,
CreatedAt: unauthorizedRobot.CreatedAt,
}
cache.AddRobot(&newRobot)
database.DB.Create(&newRobot)
cache.RemoveUnauthorizedRobotById(params.RobotId)
log.Info().Msgf("Authorize robot %s", params.RobotId)
logger.AddSystemLog("Robot authorized with id %v and type %v", params.RobotId, utils.GetRobotTypeString(unauthorizedRobot.Type))
return c.SendStatus(fiber.StatusOK)
}
func DeleteRobot(c *fiber.Ctx) error {
// swagger:operation DELETE /robot/{robotId} robot robotDelete
// ---
// summary: Delete robot.
// consumes:
// - application/json
// produces:
// - application/json
// parameters:
// - in: path
// name: robotId
// description: Robot id.
// required: true
// schema:
// type: string
// responses:
// "200":
// description: Robot deleted
// "400":
// description: Invalid robot id
var params structs.RobotIdParams
if err := rsutils.ParamsParserHelper(c, &params); err != nil {
return c.SendStatus(fiber.StatusBadRequest)
}
database.DB.Delete(&structs.Robot{}, "id = ?", params.RobotId)
cache.RemoveRobotById(params.RobotId)
logger.AddSystemLog("Robot deleted with id %v", params.RobotId)
return c.SendStatus(fiber.StatusOK)
}
func DenyUnauthorizedRobot(c *fiber.Ctx) error {
// swagger:operation DELETE /robot/deny/{robotId} robot robotDenyUnauthorizedRobot
// ---
// summary: Deny unauthorized robot.
// consumes:
// - application/json
// produces:
// - application/json
// parameters:
// - in: path
// name: robotId
// description: Robot id.
// required: true
// schema:
// type: string
// responses:
// "200":
// description: Robot denied
// "400":
// description: Invalid robot id
var params structs.RobotIdParams
if err := rsutils.ParamsParserHelper(c, &params); err != nil {
return c.SendStatus(fiber.StatusBadRequest)
}
cache.RemoveUnauthorizedRobotById(params.RobotId)
logger.AddSystemLog("Unauthorized robot denied with id %v", params.RobotId)
return c.SendStatus(fiber.StatusOK)
}

View File

@ -0,0 +1,26 @@
package robots
import (
"jannex/robot-control-manager/modules/cache"
"jannex/robot-control-manager/modules/structs"
"github.com/gofiber/fiber/v2"
)
func GetRobots(c *fiber.Ctx) error {
// swagger:operation GET /api/v1/robots robots getRobots
// ---
// summary: Get all robots
// consumes:
// - application/json
// produces:
// - application/json
// responses:
// "200":
// schema:
// "$ref": "#/definitions/GetRobotsResponse"
return c.JSON(structs.GetRobotsResponse{
Robots: cache.GetAllRobots(),
UnauthorizedRobots: cache.GetAllUnauthorizedRobots()})
}

View File

@ -2,7 +2,9 @@ package router
import (
"jannex/robot-control-manager/routers/api/v1/control"
"jannex/robot-control-manager/routers/api/v1/permitjoin"
"jannex/robot-control-manager/routers/api/v1/robot"
"jannex/robot-control-manager/routers/api/v1/robots"
"github.com/gofiber/fiber/v2"
)
@ -12,9 +14,18 @@ func SetupRoutes(app *fiber.App) {
r := v1.Group("/robot")
r.Post("/", robot.FirstRequest)
r.Post("/authorize/:robotId", robot.AuthorizeRobot)
r.Delete("/:robotId", robot.DeleteRobot)
r.Delete("/deny/:robotId", robot.DenyUnauthorizedRobot)
rs := v1.Group("/robots")
rs.Get("/", robots.GetRobots)
c := v1.Group("/control")
c.Post("/move", control.Move)
c.Post("/0", control.ControlRex)
pj := v1.Group("/permitjoin")
pj.Post("/:enabled", permitjoin.SetPermitJoin)
app.Static("/", "./public/")
}

0
testclient/activate.sh Normal file → Executable file
View File

View File

@ -3,23 +3,31 @@
from flask import Flask, request, jsonify
import requests
url = 'http://localhost:50055/v1'
robot_control_server_url = 'http://localhost:50055/v1'
class RexRobot:
def __init__(self, id):
self.id = id
def __init__(self):
self.id = "B24"
self.version = "0.0.1"
requests.api.post(url + "/robots", json={'id': self.id})
# connecting with robot server
print("connecting with robot server")
res = requests.api.post(robot_control_server_url + "/robot",
json={'id': self.id, 'type': 0, 'version': self.version})
RexRobot("1")
if res.status_code == 403:
print("permit join disabled")
exit(1) # esp should here restart
RexRobot()
app = Flask(__name__)
@app.route('/api/hello', methods=['GET'])
@app.route('/api/control', methods=['POST'])
def hello():
print("Hallo, Welt!")
return jsonify({'message': 'Hallo, Welt!'})
return jsonify({'status': 'ok'})
if __name__ == '__main__':
app.run(debug=False)