From 9e312c3f405387f0e2069bb069d17d16e7ac4e9a Mon Sep 17 00:00:00 2001 From: Daniel Svitan Date: Sat, 31 May 2025 19:10:45 +0200 Subject: [PATCH] :sparkles: Adds lock and alert commands to admin --- admin/main.go | 153 ++++++++++++++++++++++++++++++++++++++++++++++++- circuit.cddx | Bin 2758 -> 2636 bytes circuit.png | Bin 16590 -> 16296 bytes server/main.go | 16 ++++-- 4 files changed, 163 insertions(+), 6 deletions(-) diff --git a/admin/main.go b/admin/main.go index 904bb01..5408c25 100644 --- a/admin/main.go +++ b/admin/main.go @@ -2,12 +2,14 @@ package main import ( "context" + "crypto/tls" "errors" "fmt" "io" "log" "net/http" "os" + "strconv" "github.com/spf13/viper" "github.com/urfave/cli/v3" @@ -85,6 +87,8 @@ func makeReqRet(method string, url string) ([]byte, error) { } func main() { + http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true} + cmd := &cli.Command{ Name: "doorctl", Usage: "door-alarm server administration tool", @@ -113,6 +117,46 @@ func main() { }, Action: get, }, + { + Name: "lock", + Usage: "change lock status", + Commands: []*cli.Command{ + { + Name: "do", + Usage: "lock the door", + Action: createManageLock(true), + }, + { + Name: "undo", + Usage: "unlock the door", + Action: createManageLock(false), + }, + }, + Action: getLock, + }, + { + Name: "alerts", + Usage: "change alerts status", + Commands: []*cli.Command{ + { + Name: "pause", + Usage: "pause alerts", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "for", + Usage: "pause for x seconds", + }, + }, + Action: createManageAlerts(true), + }, + { + Name: "resume", + Usage: "resume alerts", + Action: createManageAlerts(false), + }, + }, + Action: getAlerts, + }, }, } @@ -138,7 +182,7 @@ func get(ctx context.Context, cmd *cli.Command) error { return err } - opened, err := makeReqRet(http.MethodGet, "/read") + opened, err := makeReqRet(http.MethodGet, fmt.Sprintf("%s/read", server)) if err != nil { return err } @@ -146,7 +190,7 @@ func get(ctx context.Context, cmd *cli.Command) error { if cmd.Bool("raw") { fmt.Println(opened) } else { - if string(opened) == "true" { + if string(opened) == "true\n" { fmt.Println("door is open") } else { fmt.Println("door is closed") @@ -155,3 +199,108 @@ func get(ctx context.Context, cmd *cli.Command) error { return nil } + +func getLock(context.Context, *cli.Command) error { + err := load() + if err != nil { + return err + } + + locked, err := makeReqRet(http.MethodGet, fmt.Sprintf("%s/lock", server)) + if err != nil { + return err + } + + if string(locked) == "true\n" { + fmt.Println("door is locked") + } else { + fmt.Println("door is unlocked") + } + + return nil +} + +func createManageLock(do bool) func(context.Context, *cli.Command) error { + return func(ctx context.Context, cmd *cli.Command) error { + err := load() + if err != nil { + return err + } + + var actionShort string + var action string + if do { + actionShort = "do" + action = "lock" + } else { + actionShort = "undo" + action = "unlock" + } + + _, err = makeReqRet(http.MethodPost, fmt.Sprintf("%s/lock/%s", server, actionShort)) + if err != nil { + return err + } + + fmt.Printf("door was %sed\n", action) + return nil + } +} + +func getAlerts(context.Context, *cli.Command) error { + err := load() + if err != nil { + return err + } + + alert, err := makeReqRet(http.MethodGet, fmt.Sprintf("%s/alerts", server)) + if err != nil { + return err + } + + if string(alert) == "true\n" { + fmt.Println("alerts are active") + } else { + fmt.Println("alerts are paused") + } + + return nil +} + +func createManageAlerts(pause bool) func(context.Context, *cli.Command) error { + return func(ctx context.Context, cmd *cli.Command) error { + err := load() + if err != nil { + return err + } + + var action string + if pause { + action = "pause" + } else { + action = "resume" + } + + var rest string + var secs int + secsRaw := cmd.String("for") + if secsRaw != "" { + secs, err = strconv.Atoi(secsRaw) + if err != nil { + return err + } + rest = fmt.Sprintf("?for=%d", secs) + } + + _, err = makeReqRet(http.MethodPost, fmt.Sprintf("%s/alerts/%s%s", server, action, rest)) + if err != nil { + return err + } + + if secsRaw != "" { + rest = fmt.Sprintf(" for %d seconds", secs) + } + fmt.Printf("alerts were %sd%s\n", action, rest) + return nil + } +} diff --git a/circuit.cddx b/circuit.cddx index 7c19f432a81a9b05ef04362f40f683f6d27576f3..4dc76ef72720303346c41d06670893669b47456d 100644 GIT binary patch delta 1491 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 O(Ufkg%9kL`L;e?Y>t|O0 literal 16590 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 diff --git a/server/main.go b/server/main.go index 9ac3330..b44a9ab 100644 --- a/server/main.go +++ b/server/main.go @@ -103,7 +103,7 @@ func main() { } app.GET("/", func(c echo.Context) error { - return c.JSON(http.StatusOK, "Hello, World!") + return c.JSON(http.StatusOK, "Hello world!") }) app.GET("/read", authed(func(c echo.Context) error { @@ -143,7 +143,7 @@ func main() { return c.NoContent(http.StatusOK) })) - app.GET("/locked", authed(func(c echo.Context) error { + app.GET("/lock", authed(func(c echo.Context) error { mut.Lock() l := locked mut.Unlock() @@ -151,7 +151,7 @@ func main() { return c.JSON(http.StatusOK, l) })) - app.POST("/lock", authed(func(c echo.Context) error { + app.POST("/lock/do", authed(func(c echo.Context) error { mut.Lock() locked = true mut.Unlock() @@ -159,7 +159,7 @@ func main() { return c.NoContent(http.StatusOK) })) - app.POST("/unlock", authed(func(c echo.Context) error { + app.POST("/lock/undo", authed(func(c echo.Context) error { mut.Lock() locked = false mut.Unlock() @@ -167,6 +167,14 @@ func main() { return c.NoContent(http.StatusOK) })) + app.GET("/alerts", authed(func(c echo.Context) error { + mut.Lock() + a := alert + mut.Unlock() + + return c.JSON(http.StatusOK, a) + })) + app.POST("/alerts/pause", authed(func(c echo.Context) error { pauseForRaw := c.QueryParam("for") if pauseForRaw != "" {