From 568ab2392f3415505c0bad2662ff3688d147d6d5 Mon Sep 17 00:00:00 2001 From: Mingcai SHEN Date: Thu, 15 Sep 2022 18:38:55 +0800 Subject: [PATCH] Updated. --- go.mod | 8 +- go.sum | 20 +++ helper.go | 63 ++++---- http.go | 60 +++---- main.go | 70 ++++---- recog.go | 476 ++++++++++++++++++++++++++++-------------------------- scene.go | 261 +++++++++++++++++------------- 7 files changed, 520 insertions(+), 438 deletions(-) diff --git a/go.mod b/go.mod index fcd15a1..80e192d 100644 --- a/go.mod +++ b/go.mod @@ -3,14 +3,20 @@ module sport_rec_demo go 1.18 require ( + github.com/aler9/gortsplib v0.0.0-20220829125132-e99f799c07e7 // indirect github.com/andybalholm/brotli v1.0.4 // indirect github.com/gofiber/fiber/v2 v2.30.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/klauspost/compress v1.15.0 // indirect + github.com/pion/randutil v0.1.0 // indirect + github.com/pion/rtcp v1.2.9 // indirect + github.com/pion/rtp v1.7.13 // indirect + github.com/pion/sdp/v3 v3.0.5 // indirect github.com/spf13/cobra v1.4.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasthttp v1.34.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect - golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 // indirect + golang.org/x/net v0.0.0-20220526153639-5463443f8c37 // indirect + golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect ) diff --git a/go.sum b/go.sum index b2aa05c..ca997d0 100644 --- a/go.sum +++ b/go.sum @@ -1,17 +1,32 @@ +github.com/aler9/gortsplib v0.0.0-20220829125132-e99f799c07e7 h1:1Q/To1zwfq1ikeenR67sEroWcHG0tlZGy0EjTzDhaaA= +github.com/aler9/gortsplib v0.0.0-20220829125132-e99f799c07e7/go.mod h1:BOWNZ/QBkY/eVcRqUzJbPFEsRJshwxaxBT01K260Jeo= github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/gofiber/fiber/v2 v2.30.0 h1:R928kgJICQkcfIzAjMIQ+U0uOpa0+vTCZLLODeo4M14= github.com/gofiber/fiber/v2 v2.30.0/go.mod h1:1Ega6O199a3Y7yDGuM9FyXDPYQfv+7/y48wl6WCwUF4= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/klauspost/compress v1.15.0 h1:xqfchp4whNFxn5A4XFyyYtitiWI8Hy5EW59jEwcyL6U= github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA= +github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8= +github.com/pion/rtcp v1.2.9 h1:1ujStwg++IOLIEoOiIQ2s+qBuJ1VN81KW+9pMPsif+U= +github.com/pion/rtcp v1.2.9/go.mod h1:qVPhiCzAm4D/rxb6XzKeyZiQK69yJpbUDJSF7TgrqNo= +github.com/pion/rtp v1.7.13 h1:qcHwlmtiI50t1XivvoawdCGTP4Uiypzfrsap+bijcoA= +github.com/pion/rtp v1.7.13/go.mod h1:bDb5n+BFZxXx0Ea7E5qe+klMuqiBrP+w8XSjiWtCUko= +github.com/pion/sdp/v3 v3.0.5 h1:ouvI7IgGl+V4CrqskVtr3AaTrPvPisEOxwgpdktctkU= +github.com/pion/sdp/v3 v3.0.5/go.mod h1:iiFWFpQO8Fy3S5ldclBkpXqmWy02ns78NOKoLLL0YQw= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q= github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.34.0 h1:d3AAQJ2DRcxJYHm7OXNXtXt2as1vMDfxeIcFvhmGGm4= @@ -21,12 +36,16 @@ github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7Fw golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220526153639-5463443f8c37 h1:lUkvobShwKsOesNfWWlCS5q7fnbG1MEliIzwu886fn8= +golang.org/x/net v0.0.0-20220526153639-5463443f8c37/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 h1:nhht2DYV/Sn3qOayu8lM+cU1ii9sTLUeBQwQQfUHtrs= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -34,3 +53,4 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/helper.go b/helper.go index 8448cb6..be698c4 100644 --- a/helper.go +++ b/helper.go @@ -1,47 +1,54 @@ package main import ( - "github.com/gofiber/fiber/v2" - "log" - "time" + "github.com/gofiber/fiber/v2" + "log" + "time" ) type StatusResult struct { - Code string `json:"code"` - Message string `json:"msg"` - Timestamp int64 `json:"timestamp"` + Code string `json:"code"` + Message string `json:"msg"` + Timestamp int64 `json:"timestamp"` } type StatusResultEx struct { - StatusResult - Scene string `json:"scene"` - SequenceId int64 `json:"sequenceId"` + StatusResult + Scene string `json:"scene"` + SequenceId int64 `json:"sequenceId"` } func failureResponse(ctx *fiber.Ctx, code string, msg string, stat int) error { - log.Println("failureResponse:> ", ctx.Request().URI(), msg) - ctx.Response().SetStatusCode(stat) - var ret = make(map[string]interface{}) - ret["status"] = StatusResult{Code: code, Message: msg, Timestamp: time.Now().Unix()} - return ctx.JSON(ret) + log.Println("failureResponse:> ", ctx.Request().URI(), msg) + ctx.Response().SetStatusCode(stat) + var ret = make(map[string]interface{}) + ret["status"] = StatusResult{Code: code, Message: msg, Timestamp: time.Now().Unix()} + return ctx.JSON(ret) } func successResponse(ctx *fiber.Ctx, msg string) error { - var ret = make(map[string]interface{}) - ret["status"] = StatusResult{Code: "0", Message: msg, Timestamp: time.Now().Unix()} - return ctx.JSON(ret) + var ret = make(map[string]interface{}) + ret["status"] = StatusResult{Code: "0", Message: msg, Timestamp: time.Now().Unix()} + return ctx.JSON(ret) +} + +func successResponseData(ctx *fiber.Ctx, msg string, data interface{}) error { + var ret = make(map[string]interface{}) + ret["status"] = StatusResult{Code: "0", Message: msg, Timestamp: time.Now().Unix()} + ret["data"] = data + return ctx.JSON(ret) } func successResponseEx(ctx *fiber.Ctx, msg string, scene string, seq int64) error { - var ret = make(map[string]interface{}) - ret["status"] = StatusResultEx{ - StatusResult: StatusResult{ - Code: "0", - Message: msg, - Timestamp: time.Now().Unix(), - }, - SequenceId: seq, - Scene: scene, - } - return ctx.JSON(ret) + var ret = make(map[string]interface{}) + ret["status"] = StatusResultEx{ + StatusResult: StatusResult{ + Code: "0", + Message: msg, + Timestamp: time.Now().Unix(), + }, + SequenceId: seq, + Scene: scene, + } + return ctx.JSON(ret) } diff --git a/http.go b/http.go index cf938c6..944f520 100644 --- a/http.go +++ b/http.go @@ -1,49 +1,49 @@ package main import ( - "bytes" - "encoding/json" - "errors" - "log" - "net/http" - "time" + "bytes" + "encoding/json" + "errors" + "log" + "net/http" + "time" ) var httpClient *http.Client var fakeClient = false func httpPost(url string, data interface{}) error { - log.Println("httpPost:url>", url) - if fakeClient { - log.Println("httpPost:data>", data) - return nil - } - if bs, e := json.Marshal(data); nil != e { - return e - } else if resp, e := httpClient.Post(url, "application/json", bytes.NewBuffer(bs)); nil != e { - return e - } else if resp.StatusCode != http.StatusOK { - return errors.New("invalid resp status: " + resp.Status) - } else { - return nil - } + log.Println("httpPost:url>", url) + if fakeClient { + log.Println("httpPost:data> fake client ") + return nil + } + if bs, e := json.Marshal(data); nil != e { + return e + } else if resp, e := httpClient.Post(url, "application/json", bytes.NewBuffer(bs)); nil != e { + return e + } else if resp.StatusCode != http.StatusOK { + return errors.New("invalid resp status: " + resp.Status) + } else { + return nil + } } func httpGet(url string, resp interface{}) error { - return nil + return nil } func httpPostEx(url string, data interface{}, retries int) { - for i := 0; i < retries; i++ { - if e := httpPost(url, data); nil != e { - log.Println(">>>", e) - time.Sleep(3 * time.Second) - } else { - return - } - } + for i := 0; i < retries; i++ { + if e := httpPost(url, data); nil != e { + log.Println(">>>", e) + time.Sleep(3 * time.Second) + } else { + return + } + } } func init() { - httpClient = http.DefaultClient + httpClient = http.DefaultClient } diff --git a/main.go b/main.go index aae57c9..d485883 100644 --- a/main.go +++ b/main.go @@ -1,26 +1,26 @@ package main import ( - "fmt" - "github.com/gofiber/fiber/v2" - "github.com/spf13/cobra" - "log" - "os" + "fmt" + "github.com/gofiber/fiber/v2" + "github.com/spf13/cobra" + "log" + "os" ) var listenAddr = ":3000" var rootCmd = &cobra.Command{ - Use: "sport_rec", - Short: "Sport Recognition Demo", - Long: "Sport Recognition Demo", + Use: "sport_rec", + Short: "Sport Recognition Demo", + Long: "Sport Recognition Demo", } func init() { - cobra.OnInitialize(initConfig) - rootCmd.PersistentFlags().StringVarP(&listenAddr, "listen", "L", ":3000", "Service listen address") - rootCmd.PersistentFlags().BoolVarP(&fakeClient, "fake", "F", false, "Fake HTP client instead of pushing") - rootCmd.AddCommand(serveCmd) + cobra.OnInitialize(initConfig) + rootCmd.PersistentFlags().StringVarP(&listenAddr, "listen", "L", ":3000", "Service listen address") + rootCmd.PersistentFlags().BoolVarP(&fakeClient, "fake", "F", false, "Fake HTP client instead of pushing") + rootCmd.AddCommand(serveCmd) } func initConfig() { @@ -28,28 +28,32 @@ func initConfig() { } var serveCmd = &cobra.Command{ - Use: "run", - Short: "Run service", - Run: func(cmd *cobra.Command, args []string) { - app := fiber.New() - - app.Get("/", func(c *fiber.Ctx) error { - return c.SendString("Hello, World!") - }) - - app.Post("/api/v1/setScene", setScene) - app.Post("/api/v1/setTestCmd", setTestCmd) - // app.Post("/api/v1/eventHandle") - app.Post("/api/v1/stopScene", stopScene) - app.Get("/api/v1/getStatus", getStatus) - - log.Fatal(app.Listen(listenAddr)) - }, + Use: "run", + Short: "Run service", + Run: func(cmd *cobra.Command, args []string) { + app := fiber.New() + + app.Get("/", func(c *fiber.Ctx) error { + return c.SendString("Hello, World!") + }) + + app.Post("/api/v1/setScene", setScene) + app.Post("/api/v1/setTestCmd", setTestCmd) + // app.Post("/api/v1/eventHandle") + app.Post("/api/v1/areaConfig", setAreaConfig) + app.Get("/api/v1/areaConfig", getAreaConfig) + app.Post("/api/v1/stopScene", stopScene) + app.Get("/api/v1/stopScene", stopScene) + app.Get("/api/v1/getStatus", getStatus) + app.Get("/api/v1/getTestStatus", getStatus) + + log.Fatal(app.Listen(listenAddr)) + }, } func main() { - if err := rootCmd.Execute(); err != nil { - fmt.Println(err) - os.Exit(1) - } + if err := rootCmd.Execute(); err != nil { + fmt.Println(err) + os.Exit(1) + } } diff --git a/recog.go b/recog.go index b2001b3..ae950ad 100644 --- a/recog.go +++ b/recog.go @@ -1,38 +1,38 @@ package main import ( - "errors" - "github.com/gofiber/fiber/v2" - "log" - "math/rand" - "time" + "errors" + "github.com/gofiber/fiber/v2" + "log" + "math/rand" + "time" ) type TestCommand struct { - Command string `json:"cmd"` - SequenceId int64 `json:"sequenceId"` + Command string `json:"cmd"` + SequenceId int64 `json:"sequenceId"` } type TestData struct { - State string `json:"state"` - ExceptionType int `json:"exceptionType,omitempty"` - ExceptionDesc string `json:"exceptionDesc,omitempty"` - Image string `json:"image,omitempty"` - DistanceCM int `json:"distanceCM,omitempty"` - Counts int `json:"counts,omitempty"` - DurationSec float32 `json:"durationSec,omitempty"` + State string `json:"state"` + ExceptionType int `json:"exceptionType,omitempty"` + ExceptionDesc string `json:"exceptionDesc,omitempty"` + Image string `json:"image,omitempty"` + DistanceCM int `json:"distanceCM,omitempty"` + Counts int `json:"counts,omitempty"` + DurationSec float32 `json:"durationSec,omitempty"` } type TestStat struct { - Scene string `json:"scene"` - Timestamp int64 `json:"timestamp"` - SequenceId int64 `json:"sequenceId"` - TestData TestData `json:"sceneData"` + Scene string `json:"scene"` + Timestamp int64 `json:"timestamp"` + SequenceId int64 `json:"sequenceId"` + TestData TestData `json:"sceneData"` } type TestException struct { - Type int - Desc string + Type int + Desc string } var currentTest *TestCommand @@ -43,241 +43,253 @@ var testStopChannel chan bool var testDurations map[string][2]int func setTestCmd(c *fiber.Ctx) error { - var testCmd TestCommand - if err := c.BodyParser(&testCmd); nil != err { - log.Println("ERROR:", c.Body()) - return failureResponse(c, "-1", err.Error(), 200) - } else if nil == currentScene { - return failureResponse(c, "1", "not in a working scene", 200) - } else { - switch testCmd.Command { - case "START": - log.Println("START ...") - if nil != currentTest { - return failureResponse(c, "2", "A test already started", 200) - } - if e := recogTaskProc(&testCmd); nil != e { - return failureResponse(c, "3", e.Error(), 200) - } - case "STOP": - if nil != testStopChannel { - testStopChannel <- true - log.Println("STOP ...") - } + var testCmd TestCommand + if err := c.BodyParser(&testCmd); nil != err { + log.Println("ERROR:", c.Body()) + return failureResponse(c, "-1", err.Error(), 200) + } else if nil == currentScene { + return failureResponse(c, "1", "not in a working scene", 200) + } else { + switch testCmd.Command { + case "START": + log.Println("START ...") + if nil != currentTest { + return failureResponse(c, "2", "A test already started", 200) + } + if e := recogTaskProc(&testCmd); nil != e { + return failureResponse(c, "3", e.Error(), 200) + } + case "STOP": + if nil != testStopChannel { + testStopChannel <- true + log.Println("STOP ...") + } - case "CANCEL": - if nil != testStopChannel { - testStopChannel <- true - log.Println("CANCEL ...") - } - default: - log.Println("UNKNOWN ...") - } - return successResponse(c, "Updated successfully.") - } + case "CANCEL": + if nil != testStopChannel { + testStopChannel <- true + log.Println("CANCEL ...") + } + default: + log.Println("UNKNOWN ...") + } + return successResponse(c, "Updated successfully.") + } } func pullUpTask(seq int64) error { - var tk = time.NewTicker(time.Millisecond * 200) - defer func() { - tk.Stop() - }() - time.Sleep(time.Millisecond * 300) - go pushEvent(currentScene.PushUrl, currentScene.Scene, currentTest.SequenceId, "TEST READY", false, false) - var started = false - for { - select { - case <-testStopChannel: - go pushEvent(currentScene.PushUrl, currentScene.Scene, seq, "TEST END", true, true) - return nil - case except := <-testExceptChannel: - if except.Type != 0 { - go pushException(currentScene.PushUrl, currentScene.Scene, currentTest.SequenceId, except.Type, except.Desc, true) - } - case <-tk.C: - log.Println("===") - if !started { - go pushEvent(currentScene.PushUrl, currentScene.Scene, seq, "START", true, true) - started = true - } else { - go pushEvent(currentScene.PushUrl, currentScene.Scene, seq, "COUNT", true, true) - } - } - } + var tk = time.NewTicker(time.Millisecond * time.Duration(1500+random.Intn(800))) + defer func() { + tk.Stop() + }() + time.Sleep(time.Millisecond * 1300) + total := random.Intn(10) + n := 0 + go pushEvent(currentScene.PushUrl, currentScene.Scene, currentTest.SequenceId, "TEST READY", false) + var started = false + for { + select { + case <-testStopChannel: + go pushEvent(currentScene.PushUrl, currentScene.Scene, seq, "TEST END", true, n) + return nil + case except := <-testExceptChannel: + if except.Type != 0 { + go pushException(currentScene.PushUrl, currentScene.Scene, currentTest.SequenceId, except.Type, except.Desc, true) + } + case <-tk.C: + log.Println("===") + if !started { + go pushEvent(currentScene.PushUrl, currentScene.Scene, seq, "START", true, n) + started = true + } else if n >= total { + go pushEvent(currentScene.PushUrl, currentScene.Scene, seq, "TEST END", true, n) + return nil + } else { + n += 1 + go pushEvent(currentScene.PushUrl, currentScene.Scene, seq, "COUNT", true, n) + } + } + } } func standJumpTask(seq int64) error { - var tk = time.NewTicker(time.Millisecond * 100) - defer func() { - tk.Stop() - }() - time.Sleep(time.Millisecond * 500) - go pushEvent(currentScene.PushUrl, currentScene.Scene, currentTest.SequenceId, "TEST READY", false, false) - var started = false - for { - select { - case <-testStopChannel: - go pushEvent(currentScene.PushUrl, currentScene.Scene, seq, "TEST END", true, true) - return nil - case except := <-testExceptChannel: - if except.Type != 0 { - go pushException(currentScene.PushUrl, currentScene.Scene, currentTest.SequenceId, except.Type, except.Desc, true) - } - case <-tk.C: - log.Println("===") - if !started { - go pushEvent(currentScene.PushUrl, currentScene.Scene, seq, "START", true, true) - started = true - } - } - } + var tk = time.NewTicker(time.Millisecond * 400) + defer func() { + tk.Stop() + }() + time.Sleep(time.Millisecond * 500) + go pushEvent(currentScene.PushUrl, currentScene.Scene, currentTest.SequenceId, "TEST READY", false) + var started = false + for { + select { + case <-testStopChannel: + go pushEvent(currentScene.PushUrl, currentScene.Scene, seq, "TEST END", true, 1000+random.Intn(1000)) + return nil + case except := <-testExceptChannel: + if except.Type != 0 { + go pushException(currentScene.PushUrl, currentScene.Scene, currentTest.SequenceId, except.Type, except.Desc, true) + } + case <-tk.C: + log.Println("===") + if !started { + go pushEvent(currentScene.PushUrl, currentScene.Scene, seq, "START", true) + started = true + } + } + } } func sitUpsTask(seq int64) error { - var tk = time.NewTicker(time.Millisecond * 200) - defer func() { - tk.Stop() - }() - time.Sleep(time.Millisecond * 600) - go pushEvent(currentScene.PushUrl, currentScene.Scene, currentTest.SequenceId, "TEST READY", false, false) - var started = false - for { - select { - case <-testStopChannel: - go pushEvent(currentScene.PushUrl, currentScene.Scene, seq, "TEST END", true, true) - return nil - case except := <-testExceptChannel: - if except.Type != 0 { - go pushException(currentScene.PushUrl, currentScene.Scene, currentTest.SequenceId, except.Type, except.Desc, true) - } - case <-tk.C: - log.Println("===") - if !started { - go pushEvent(currentScene.PushUrl, currentScene.Scene, seq, "START", true, true) - started = true - } else { - go pushEvent(currentScene.PushUrl, currentScene.Scene, seq, "COUNT", true, true) - } - } - } + var tk = time.NewTicker(time.Millisecond * 500) + defer func() { + tk.Stop() + }() + time.Sleep(time.Millisecond * 600) + total := 40 + random.Intn(20) + n := 0 + go pushEvent(currentScene.PushUrl, currentScene.Scene, currentTest.SequenceId, "TEST READY", false) + var started = false + for { + select { + case <-testStopChannel: + go pushEvent(currentScene.PushUrl, currentScene.Scene, seq, "TEST END", true, n) + return nil + case except := <-testExceptChannel: + if except.Type != 0 { + go pushException(currentScene.PushUrl, currentScene.Scene, currentTest.SequenceId, except.Type, except.Desc, true) + } + case <-tk.C: + log.Println("===") + if !started { + go pushEvent(currentScene.PushUrl, currentScene.Scene, seq, "START", true, n) + started = true + } else if n >= total { + go pushEvent(currentScene.PushUrl, currentScene.Scene, seq, "TEST END", true, n) + return nil + } else { + n += 1 + go pushEvent(currentScene.PushUrl, currentScene.Scene, seq, "COUNT", true, n) + } + } + } } func raceTask(seq int64) error { - var tk = time.NewTicker(time.Millisecond * 100) - defer func() { - tk.Stop() - }() - time.Sleep(time.Millisecond * 800) - go pushEvent(currentScene.PushUrl, currentScene.Scene, currentTest.SequenceId, "TEST READY", false, false) - var started = false - for { - select { - case <-testStopChannel: - go pushEvent(currentScene.PushUrl, currentScene.Scene, currentTest.SequenceId, "TEST END", true, true) - return nil - case except := <-testExceptChannel: - if except.Type != 0 { - go pushException(currentScene.PushUrl, currentScene.Scene, currentTest.SequenceId, except.Type, except.Desc, true) - } - case <-tk.C: - log.Println("===") - if !started { - go pushEvent(currentScene.PushUrl, currentScene.Scene, seq, "START", true, true) - started = true - } - } - } + var tk = time.NewTicker(time.Millisecond * 800) + defer func() { + tk.Stop() + }() + time.Sleep(time.Millisecond * 800) + go pushEvent(currentScene.PushUrl, currentScene.Scene, currentTest.SequenceId, "TEST READY", false) + var started = false + for { + select { + case <-testStopChannel: + go pushEvent(currentScene.PushUrl, currentScene.Scene, currentTest.SequenceId, "TEST END", true, random.Intn(40)+100) + return nil + case except := <-testExceptChannel: + if except.Type != 0 { + go pushException(currentScene.PushUrl, currentScene.Scene, currentTest.SequenceId, except.Type, except.Desc, true) + } + case <-tk.C: + log.Println("===") + if !started { + go pushEvent(currentScene.PushUrl, currentScene.Scene, seq, "START", true) + started = true + } + } + } } func pushException(url string, scene string, seq int64, tp int, desc string, img bool) { - var st = TestStat{ - Scene: scene, - Timestamp: time.Now().Unix(), - SequenceId: seq, - TestData: TestData{ - State: "EXCEPT", - ExceptionType: tp, - ExceptionDesc: desc, - }, - } - if img { - st.TestData.Image = IMAGES[random.Intn(len(IMAGES))] - } - httpPostEx(url, st, 3) + var st = TestStat{ + Scene: scene, + Timestamp: time.Now().Unix(), + SequenceId: seq, + TestData: TestData{ + State: "EXCEPT", + ExceptionType: tp, + ExceptionDesc: desc, + }, + } + if img { + st.TestData.Image = IMAGES[random.Intn(len(IMAGES))] + } + httpPostEx(url, st, 3) } -func pushEvent(url string, scene string, seq int64, state string, img bool, val bool) { - var st = TestStat{ - Scene: scene, - Timestamp: time.Now().Unix(), - SequenceId: seq, - TestData: TestData{ - State: state, - }, - } - if img { - st.TestData.Image = IMAGES[random.Intn(len(IMAGES))] - } - if val { - switch scene { - case "pullUp": - st.TestData.Counts = random.Intn(20) - case "standJump": - st.TestData.DistanceCM = random.Intn(300) - case "sitUps": - st.TestData.Counts = random.Intn(20) - case "race": - st.TestData.DurationSec = random.Float32() - default: +func pushEvent(url string, scene string, seq int64, state string, img bool, vals ...int) { + var st = TestStat{ + Scene: scene, + Timestamp: time.Now().Unix(), + SequenceId: seq, + TestData: TestData{ + State: state, + }, + } + if img { + st.TestData.Image = IMAGES1[random.Intn(len(IMAGES1))] + } + if len(vals) > 0 { + switch scene { + case "pullUp": + st.TestData.Counts = vals[0] + case "standJump": + st.TestData.DistanceCM = vals[0] + case "sitUps": + st.TestData.Counts = vals[0] + case "race": + st.TestData.DurationSec = float32(vals[0]) / 10.0 + default: - } - } - httpPostEx(url, st, 3) + } + } + httpPostEx(url, st, 3) } func recogTaskProc(cmd *TestCommand) error { - testStopChannel = make(chan bool) - testExceptChannel = make(chan TestException) - random = rand.New(rand.NewSource(time.Now().UnixNano())) - if nil == currentScene { - return errors.New("invalid scene state") - } - if nil == currentScene.proc { - return errors.New("invalid scene mode processor") - } - currentTest = cmd - go func() { - defer func() { - close(testStopChannel) - close(testExceptChannel) - testStopChannel = nil - testExceptChannel = nil - currentTest = nil - }() - if e := currentScene.proc(cmd.SequenceId); nil != e { - log.Println(">>>>", e) - } - }() - go func() { - var min = testDurations[currentScene.Scene][0] - var max = testDurations[currentScene.Scene][1] - for i := 0; i < random.Intn(max-min)+min; i++ { - time.Sleep(time.Second) - } - testStopChannel <- true - }() - return nil + testStopChannel = make(chan bool) + testExceptChannel = make(chan TestException) + random = rand.New(rand.NewSource(time.Now().UnixNano())) + if nil == currentScene { + return errors.New("invalid scene state") + } + if nil == currentScene.proc { + return errors.New("invalid scene mode processor") + } + currentTest = cmd + go func() { + defer func() { + close(testStopChannel) + close(testExceptChannel) + testStopChannel = nil + testExceptChannel = nil + currentTest = nil + }() + if e := currentScene.proc(cmd.SequenceId); nil != e { + log.Println(">>>>", e) + } + }() + go func() { + var min = testDurations[currentScene.Scene][0] + var max = testDurations[currentScene.Scene][1] + for i := 0; i < random.Intn(max-min)+min; i++ { + time.Sleep(time.Second) + } + testStopChannel <- true + }() + return nil } func init() { - random = rand.New(rand.NewSource(time.Now().UnixNano())) - currentTest = nil - testExceptChannel = nil - testStopChannel = nil - testDurations = map[string][2]int{ - "pullUp": [2]int{30, 80}, - "standJump": [2]int{10, 30}, - "sitUps": [2]int{60, 70}, - "race": [2]int{9, 15}, - } + random = rand.New(rand.NewSource(time.Now().UnixNano())) + currentTest = nil + testExceptChannel = nil + testStopChannel = nil + testDurations = map[string][2]int{ + "pullUp": [2]int{30, 80}, + "standJump": [2]int{10, 30}, + "sitUps": [2]int{60, 70}, + "race": [2]int{9, 15}, + } } diff --git a/scene.go b/scene.go index 7199fcd..15d6e5c 100644 --- a/scene.go +++ b/scene.go @@ -1,148 +1,181 @@ package main import ( - "errors" - "github.com/gofiber/fiber/v2" - "log" - "net/url" - "time" + "errors" + "github.com/gofiber/fiber/v2" + "log" + "net/url" + "time" ) type SceneCommand struct { - Scene string `json:"scene"` - PushUrl string `json:"pushUrl"` - CameraUrls []string `json:"cameraURls"` - proc func(int64) error + Scene string `json:"scene"` + PushUrl string `json:"pushUrl"` + CameraUrls []string `json:"cameraURls"` + proc func(int64) error + areaConfigs []AreaConfig `json:"-"` } type SceneData struct { - State string `json:"state"` - LiveUrl []string `json:"liveUrl"` + State string `json:"state"` + LiveUrl []string `json:"liveUrl"` +} + +type Pointer struct { + Id string `json:"id"` + PercentX float32 `json:"percentX"` + PercentY float32 `json:"percentY"` +} + +type AreaConfig struct { + AreaId string `json:"areaId"` + PointersNum int `json:"pointersNum"` + Pointers []Pointer `json:"pointers"` } type SceneReadyResponse struct { - Scene string `json:"scene"` - Timestamp int64 `json:"timestamp"` - SceneData SceneData `json:"sceneData"` + Scene string `json:"scene"` + Timestamp int64 `json:"timestamp"` + SceneData SceneData `json:"sceneData"` } var currentScene *SceneCommand var sceneStopChannel chan bool func validateSceneCmd(cmd SceneCommand) error { - switch cmd.Scene { - case "pullUp", "standJump", "sitUps": - if len(cmd.CameraUrls) < 1 { - return errors.New("cameraUrls can not less than 1") - } - case "race": - if len(cmd.CameraUrls) < 2 { - return errors.New("cameraUrls can not less than 2") - } - default: - return errors.New("unknown scene type:" + cmd.Scene) - } - if u, e := url.Parse(cmd.PushUrl); nil != e { - return errors.New("invalid pushUrl:" + e.Error()) - } else if u.Scheme != "http" && u.Scheme != "https" { - return errors.New("can not support pushUrl with " + u.Scheme) - } - return nil + switch cmd.Scene { + case "pullUp", "standJump", "sitUps": + if len(cmd.CameraUrls) < 1 { + return errors.New("cameraUrls can not less than 1") + } + case "race": + if len(cmd.CameraUrls) < 2 { + return errors.New("cameraUrls can not less than 2") + } + default: + return errors.New("unknown scene type:" + cmd.Scene) + } + if u, e := url.Parse(cmd.PushUrl); nil != e { + return errors.New("invalid pushUrl:" + e.Error()) + } else if u.Scheme != "http" && u.Scheme != "https" { + return errors.New("can not support pushUrl with " + u.Scheme) + } + return nil } func setScene(c *fiber.Ctx) error { - var sceneCmd SceneCommand - if err := c.BodyParser(&sceneCmd); nil != err { - log.Println("ERROR:", c.Body()) - return failureResponse(c, "-1", err.Error(), 200) - } else if nil != currentScene { - return failureResponse(c, "1", "A working scene is started", 200) - } else if err = validateSceneCmd(sceneCmd); nil != err { - return failureResponse(c, "2", err.Error(), 200) - } else { - // currentScene = &sceneCmd - log.Println("Starting scene ...") - log.Println(sceneCmd) - if e := sceneTaskProc(&sceneCmd); nil != e { - return failureResponse(c, "3", err.Error(), 200) - } else { - return successResponse(c, "Updated successfully.") - } - } + var sceneCmd SceneCommand + if err := c.BodyParser(&sceneCmd); nil != err { + log.Println("ERROR:", c.Body()) + return failureResponse(c, "-1", err.Error(), 200) + } else if nil != currentScene { + return failureResponse(c, "1", "A working scene is started", 200) + } else if err = validateSceneCmd(sceneCmd); nil != err { + return failureResponse(c, "2", err.Error(), 200) + } else { + // currentScene = &sceneCmd + log.Println("Starting scene ...") + log.Println(sceneCmd) + if e := sceneTaskProc(&sceneCmd); nil != e { + return failureResponse(c, "3", err.Error(), 200) + } else { + return successResponse(c, "Updated successfully.") + } + } +} + +func setAreaConfig(c *fiber.Ctx) error { + var cfg []AreaConfig + if e := c.BodyParser(&cfg); nil != e { + log.Println("ERROR:", c.Body()) + return failureResponse(c, "-1", e.Error(), 200) + } else if nil == currentScene { + return failureResponse(c, "1", "No working scene is started", 200) + } + currentScene.areaConfigs = cfg + return successResponse(c, "Updated successfully.") +} + +func getAreaConfig(c *fiber.Ctx) error { + if nil == currentScene { + return failureResponse(c, "1", "No working scene is started", 200) + } else { + return successResponseData(c, "success", currentScene.areaConfigs) + } } func stopScene(c *fiber.Ctx) error { - if nil != testStopChannel { - testStopChannel <- true - } - if nil != sceneStopChannel { - sceneStopChannel <- true - } - return successResponse(c, "Updated successfully.") + if nil != testStopChannel { + testStopChannel <- true + } + if nil != sceneStopChannel { + sceneStopChannel <- true + } + return successResponse(c, "Updated successfully.") } func getStatus(c *fiber.Ctx) error { - var scene = "" - var seq int64 = 0 - if nil != currentScene { - scene = currentScene.Scene - } - if nil != currentTest { - seq = currentTest.SequenceId - } - return successResponseEx(c, "success", scene, seq) + var scene = "" + var seq int64 = 0 + if nil != currentScene { + scene = currentScene.Scene + } + if nil != currentTest { + seq = currentTest.SequenceId + } + return successResponseEx(c, "success", scene, seq) } func sceneTaskProc(cmd *SceneCommand) error { - var f func(int64) error = nil - switch cmd.Scene { - case "pullUp": - f = pullUpTask - case "standJump": - f = standJumpTask - case "sitUps": - f = sitUpsTask - case "race": - f = raceTask - default: - return errors.New("unknown scene type:" + cmd.Scene) - } - sceneStopChannel = make(chan bool) - var tk = time.NewTicker(time.Second * 3) - go func() { - defer func() { - tk.Stop() - close(sceneStopChannel) - sceneStopChannel = nil - }() - currentScene = cmd - currentScene.proc = f - time.Sleep(time.Second) - var st = SceneReadyResponse{ - Scene: cmd.Scene, - Timestamp: time.Now().Unix(), - SceneData: SceneData{ - State: "SCENE READY", - LiveUrl: cmd.CameraUrls, - }, - } - go httpPostEx(cmd.PushUrl, st, 3) - for { - select { - case <-tk.C: - // log.Println(" ...") - case <-sceneStopChannel: - log.Println("Scene Stopping...") - go pushEvent(cmd.PushUrl, cmd.Scene, 0, "SCENE END", false, false) - currentScene = nil - return - } - } - }() - return nil + var f func(int64) error = nil + switch cmd.Scene { + case "pullUp": + f = pullUpTask + case "standJump": + f = standJumpTask + case "sitUps": + f = sitUpsTask + case "race": + f = raceTask + default: + return errors.New("unknown scene type:" + cmd.Scene) + } + sceneStopChannel = make(chan bool) + var tk = time.NewTicker(time.Second * 3) + go func() { + defer func() { + tk.Stop() + close(sceneStopChannel) + sceneStopChannel = nil + }() + currentScene = cmd + currentScene.proc = f + time.Sleep(time.Second) + var st = SceneReadyResponse{ + Scene: cmd.Scene, + Timestamp: time.Now().Unix(), + SceneData: SceneData{ + State: "SCENE READY", + LiveUrl: cmd.CameraUrls, + }, + } + go httpPostEx(cmd.PushUrl, st, 3) + for { + select { + case <-tk.C: + // log.Println(" ...") + case <-sceneStopChannel: + log.Println("Scene Stopping...") + go pushEvent(cmd.PushUrl, cmd.Scene, 0, "SCENE END", false) + currentScene = nil + return + } + } + }() + return nil } func init() { - currentScene = nil - sceneStopChannel = nil + currentScene = nil + sceneStopChannel = nil }