Browse Source

Updated.

develop
Mingcai SHEN 2 years ago
parent
commit
568ab2392f
7 changed files with 520 additions and 438 deletions
  1. +7
    -1
      go.mod
  2. +20
    -0
      go.sum
  3. +35
    -28
      helper.go
  4. +30
    -30
      http.go
  5. +37
    -33
      main.go
  6. +244
    -232
      recog.go
  7. +147
    -114
      scene.go

+ 7
- 1
go.mod View File

@ -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
)

+ 20
- 0
go.sum View File

@ -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=

+ 35
- 28
helper.go View File

@ -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)
}

+ 30
- 30
http.go View File

@ -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
}

+ 37
- 33
main.go View File

@ -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)
}
}

+ 244
- 232
recog.go View File

@ -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},
}
}

+ 147
- 114
scene.go View File

@ -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
}

Loading…
Cancel
Save