✨ Adds fetching and toggling alerts
This commit is contained in:
parent
ae7db8290c
commit
000c12845c
@ -9,6 +9,7 @@ require (
|
|||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/gorilla/websocket v1.5.3 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||||
|
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||||
github.com/labstack/echo/v4 v4.13.3 h1:pwhpCPrTl5qry5HRdM5FwdXnhXSLSY+WE+YQSeCaafY=
|
github.com/labstack/echo/v4 v4.13.3 h1:pwhpCPrTl5qry5HRdM5FwdXnhXSLSY+WE+YQSeCaafY=
|
||||||
|
119
server/main.go
119
server/main.go
@ -24,12 +24,13 @@ var token string
|
|||||||
|
|
||||||
// the condition is: distance >= threshold (is door open)
|
// the condition is: distance >= threshold (is door open)
|
||||||
var opened bool
|
var opened bool
|
||||||
|
var openedChange = make(chan bool)
|
||||||
|
|
||||||
// is door locked
|
// is door locked
|
||||||
var locked bool = false
|
var locked bool = false
|
||||||
|
|
||||||
// alert the user when door locked and but open?
|
// alerts the user when door locked and but open?
|
||||||
var alert bool = false
|
var alerts bool = false
|
||||||
var gotifyToken string
|
var gotifyToken string
|
||||||
var gotifyURL string
|
var gotifyURL string
|
||||||
|
|
||||||
@ -44,23 +45,23 @@ type ChangeLockReq struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ChangeAlertReq struct {
|
type ChangeAlertReq struct {
|
||||||
Alert bool `json:"alert"`
|
Alerts bool `json:"alerts"`
|
||||||
For int `json:"for"`
|
For int `json:"for"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
_ = godotenv.Load()
|
_ = godotenv.Load()
|
||||||
token = os.Getenv("TOKEN")
|
token = os.Getenv("TOKEN")
|
||||||
|
|
||||||
alertRaw := strings.ToLower(os.Getenv("USE_ALERTS"))
|
alertsRaw := strings.ToLower(os.Getenv("USE_ALERTS"))
|
||||||
alert = alertRaw == "true" || alertRaw == "t" || alertRaw == "1" || alertRaw == "y" || alertRaw == "yes"
|
alerts = alertsRaw == "true" || alertsRaw == "t" || alertsRaw == "1" || alertsRaw == "y" || alertsRaw == "yes"
|
||||||
|
|
||||||
gotifyToken = os.Getenv("GOTIFY_TOKEN")
|
gotifyToken = os.Getenv("GOTIFY_TOKEN")
|
||||||
gotifyURL = os.Getenv("GOTIFY_URL")
|
gotifyURL = os.Getenv("GOTIFY_URL")
|
||||||
if alert && gotifyToken == "" {
|
if alerts && gotifyToken == "" {
|
||||||
log.Fatal("GOTIFY_TOKEN can't be empty when alerts are enabled")
|
log.Fatal("GOTIFY_TOKEN can't be empty when alerts are enabled")
|
||||||
}
|
}
|
||||||
if alert && gotifyURL == "" {
|
if alerts && gotifyURL == "" {
|
||||||
log.Fatal("GOTIFY_URL can't be empty when alerts are enabled")
|
log.Fatal("GOTIFY_URL can't be empty when alerts are enabled")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,103 +115,17 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
app.GET("/", func(c echo.Context) error {
|
app.GET("/", helloWorld)
|
||||||
return c.JSON(http.StatusOK, "Hello world!")
|
|
||||||
})
|
|
||||||
|
|
||||||
app.GET("/open", authed(func(c echo.Context) error {
|
app.GET("/opened", authed(getOpened))
|
||||||
mut.Lock()
|
app.GET("/opened/ws", authed(getOpenedWs))
|
||||||
o := opened
|
app.POST("/opened", authed(setOpened))
|
||||||
mut.Unlock()
|
|
||||||
|
|
||||||
return c.JSON(http.StatusOK, o)
|
app.GET("/locked", authed(getLocked))
|
||||||
}))
|
app.POST("/locked", authed(setLocked))
|
||||||
|
|
||||||
app.POST("/open", authed(func(c echo.Context) error {
|
app.GET("/alerts", authed(getAlerts))
|
||||||
var data ChangeOpenReq
|
app.POST("/alerts", authed(setAlerts))
|
||||||
err := c.Bind(&data)
|
|
||||||
if err != nil {
|
|
||||||
return c.NoContent(http.StatusBadRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
if data.Opened == opened {
|
|
||||||
return c.NoContent(http.StatusOK)
|
|
||||||
}
|
|
||||||
|
|
||||||
mut.Lock()
|
|
||||||
opened = data.Opened
|
|
||||||
if locked && alert {
|
|
||||||
var action string
|
|
||||||
if opened {
|
|
||||||
action = "opened"
|
|
||||||
} else {
|
|
||||||
action = "closed"
|
|
||||||
}
|
|
||||||
|
|
||||||
go sendAlert(action)
|
|
||||||
}
|
|
||||||
|
|
||||||
mut.Unlock()
|
|
||||||
return c.NoContent(http.StatusOK)
|
|
||||||
}))
|
|
||||||
|
|
||||||
app.GET("/lock", authed(func(c echo.Context) error {
|
|
||||||
mut.Lock()
|
|
||||||
l := locked
|
|
||||||
mut.Unlock()
|
|
||||||
|
|
||||||
return c.JSON(http.StatusOK, l)
|
|
||||||
}))
|
|
||||||
|
|
||||||
app.POST("/lock", authed(func(c echo.Context) error {
|
|
||||||
var data ChangeLockReq
|
|
||||||
err := c.Bind(&data)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if data.Locked == locked {
|
|
||||||
return c.NoContent(http.StatusOK)
|
|
||||||
}
|
|
||||||
|
|
||||||
mut.Lock()
|
|
||||||
locked = data.Locked
|
|
||||||
mut.Unlock()
|
|
||||||
|
|
||||||
return c.NoContent(http.StatusOK)
|
|
||||||
}))
|
|
||||||
|
|
||||||
app.GET("/alert", authed(func(c echo.Context) error {
|
|
||||||
mut.Lock()
|
|
||||||
a := alert
|
|
||||||
mut.Unlock()
|
|
||||||
|
|
||||||
return c.JSON(http.StatusOK, a)
|
|
||||||
}))
|
|
||||||
|
|
||||||
app.POST("/alert", authed(func(c echo.Context) error {
|
|
||||||
var data ChangeAlertReq
|
|
||||||
err := c.Bind(&data)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if data.For > 0 {
|
|
||||||
go func() {
|
|
||||||
time.Sleep(time.Duration(data.For) * time.Second)
|
|
||||||
|
|
||||||
mut.Lock()
|
|
||||||
alert = !data.Alert
|
|
||||||
mut.Unlock()
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
mut.Lock()
|
|
||||||
alert = data.Alert
|
|
||||||
mut.Unlock()
|
|
||||||
|
|
||||||
return c.NoContent(http.StatusOK)
|
|
||||||
}))
|
|
||||||
|
|
||||||
log.Fatal(app.Start(":1323"))
|
log.Fatal(app.Start(":1323"))
|
||||||
}
|
}
|
||||||
|
110
server/routes.go
Normal file
110
server/routes.go
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func helloWorld(c echo.Context) error {
|
||||||
|
return c.JSON(http.StatusOK, "Hello world!")
|
||||||
|
}
|
||||||
|
|
||||||
|
func getOpened(c echo.Context) error {
|
||||||
|
mut.Lock()
|
||||||
|
o := opened
|
||||||
|
mut.Unlock()
|
||||||
|
|
||||||
|
return c.JSON(http.StatusOK, o)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getOpenedWs(c echo.Context) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func setOpened(c echo.Context) error {
|
||||||
|
var data ChangeOpenReq
|
||||||
|
err := c.Bind(&data)
|
||||||
|
if err != nil {
|
||||||
|
return c.NoContent(http.StatusBadRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
if data.Opened == opened {
|
||||||
|
return c.NoContent(http.StatusOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
mut.Lock()
|
||||||
|
opened = data.Opened
|
||||||
|
if locked && alerts {
|
||||||
|
var action string
|
||||||
|
if opened {
|
||||||
|
action = "opened"
|
||||||
|
} else {
|
||||||
|
action = "closed"
|
||||||
|
}
|
||||||
|
|
||||||
|
go sendAlert(action)
|
||||||
|
}
|
||||||
|
|
||||||
|
openedChange <- true
|
||||||
|
mut.Unlock()
|
||||||
|
return c.NoContent(http.StatusOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getLocked(c echo.Context) error {
|
||||||
|
mut.Lock()
|
||||||
|
l := locked
|
||||||
|
mut.Unlock()
|
||||||
|
|
||||||
|
return c.JSON(http.StatusOK, l)
|
||||||
|
}
|
||||||
|
|
||||||
|
func setLocked(c echo.Context) error {
|
||||||
|
var data ChangeLockReq
|
||||||
|
err := c.Bind(&data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if data.Locked == locked {
|
||||||
|
return c.NoContent(http.StatusOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
mut.Lock()
|
||||||
|
locked = data.Locked
|
||||||
|
mut.Unlock()
|
||||||
|
|
||||||
|
return c.NoContent(http.StatusOK)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAlerts(c echo.Context) error {
|
||||||
|
mut.Lock()
|
||||||
|
a := alerts
|
||||||
|
mut.Unlock()
|
||||||
|
|
||||||
|
return c.JSON(http.StatusOK, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
func setAlerts(c echo.Context) error {
|
||||||
|
var data ChangeAlertReq
|
||||||
|
err := c.Bind(&data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if data.For > 0 {
|
||||||
|
go func() {
|
||||||
|
time.Sleep(time.Duration(data.For) * time.Second)
|
||||||
|
|
||||||
|
mut.Lock()
|
||||||
|
alerts = !data.Alerts
|
||||||
|
mut.Unlock()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
mut.Lock()
|
||||||
|
alerts = data.Alerts
|
||||||
|
mut.Unlock()
|
||||||
|
|
||||||
|
return c.NoContent(http.StatusOK)
|
||||||
|
}
|
@ -13,8 +13,8 @@ FROM oven/bun:1
|
|||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY --from=build /app/.output .
|
COPY --from=build /app/.output .
|
||||||
|
|
||||||
ENV PORT 3000
|
ENV PORT=3000
|
||||||
ENV HOST 0.0.0.0
|
ENV HOST=0.0.0.0
|
||||||
|
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
CMD ["bun", "/app/server/index.mjs"]
|
CMD ["bun", "/app/server/index.mjs"]
|
||||||
|
@ -77,7 +77,7 @@
|
|||||||
:color="alert ? 'primary' : 'secondary'"
|
:color="alert ? 'primary' : 'secondary'"
|
||||||
variant="solid"
|
variant="solid"
|
||||||
class="flex items-center justify-center w-full h-10"
|
class="flex items-center justify-center w-full h-10"
|
||||||
@click="() => (alert = !alert)"
|
@click="toggleAlert"
|
||||||
>
|
>
|
||||||
{{ alert ? "Turn off" : "Turn on" }}
|
{{ alert ? "Turn off" : "Turn on" }}
|
||||||
</UButton>
|
</UButton>
|
||||||
@ -119,6 +119,21 @@ async function toggleLock() {
|
|||||||
.catch(handleRequestError)
|
.catch(handleRequestError)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function toggleAlert() {
|
||||||
|
const desired = !alert.value
|
||||||
|
axios
|
||||||
|
.post(useAPI("/alert"), { alert: desired }, { headers: useHeaders() })
|
||||||
|
.then((res) => {
|
||||||
|
handleResponse(res, () => {
|
||||||
|
toast.add({
|
||||||
|
title: `Alerts were turned ${desired ? "on" : "off"}`,
|
||||||
|
})
|
||||||
|
alert.value = desired
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch(handleRequestError)
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (!token.value) {
|
if (!token.value) {
|
||||||
return navigateTo("/token")
|
return navigateTo("/token")
|
||||||
@ -134,5 +149,16 @@ onMounted(() => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
.catch(handleRequestError)
|
.catch(handleRequestError)
|
||||||
|
|
||||||
|
axios
|
||||||
|
.get<boolean>(useAPI("/alert"), {
|
||||||
|
headers: useHeaders(),
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
handleResponse(res, (response) => {
|
||||||
|
alert.value = response.data
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch(handleRequestError)
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user