🔨 Replaces websockets with interval fetches
All checks were successful
Gitea Build Action / build-go (push) Successful in 36s
Gitea Build Action / build-nuxt (push) Successful in 10m7s

This commit is contained in:
2025-06-16 11:56:20 +02:00
parent 4b2248a6d7
commit d858b9e7c8
5 changed files with 55 additions and 74 deletions

View File

@@ -24,7 +24,6 @@ var token string
// the condition is: distance >= threshold (is door open)
var opened = false
var openedChange = make(chan any)
// is door locked
var locked = false
@@ -118,7 +117,6 @@ func main() {
app.GET("/", helloWorld)
app.GET("/opened", authed(getOpened))
app.GET("/opened/ws", authed(getOpenedWs))
app.POST("/opened", authed(setOpened))
app.GET("/locked", authed(getLocked))

View File

@@ -4,13 +4,10 @@ import (
"net/http"
"time"
"github.com/gorilla/websocket"
"github.com/labstack/echo/v4"
"github.com/labstack/gommon/log"
)
var upgrader = websocket.Upgrader{}
func helloWorld(c echo.Context) error {
return c.JSON(http.StatusOK, "Hello world!")
}
@@ -23,39 +20,6 @@ func getOpened(c echo.Context) error {
return c.JSON(http.StatusOK, o)
}
func getOpenedWs(c echo.Context) error {
ws, err := upgrader.Upgrade(c.Response(), c.Request(), nil)
if err != nil {
return err
}
defer func() { _ = ws.Close() }()
// empty the channel
emptied := false
for !emptied {
select {
case <-openedChange:
default:
emptied = true
}
}
for {
<-openedChange
mut.Lock()
err = ws.WriteJSON(opened)
mut.Unlock()
if err != nil {
log.Error(err)
break
}
}
return err
}
func setOpened(c echo.Context) error {
var data ChangeOpenReq
err := c.Bind(&data)
@@ -80,9 +44,6 @@ func setOpened(c echo.Context) error {
go sendAlert(action)
}
go func() {
openedChange <- 0
}()
mut.Unlock()
return c.NoContent(http.StatusOK)
}

View File

@@ -7,3 +7,9 @@
<style>
@import "assets/css/main.css";
</style>
<script lang="ts" setup>
useHead({
title: "Door alarm",
})
</script>

View File

@@ -1,5 +1,4 @@
import type { FetchResponse } from "ofetch"
import { AxiosError, type AxiosResponse } from "axios"
import { type AxiosResponse } from "axios"
export function useAPI(route: string = "/") {
return `https://api.door.svitan.dev${route}`

View File

@@ -4,11 +4,11 @@
>
<div class="flex items-center justify-center flex-col gap-y-2 w-32">
<div
:class="`flex items-center justify-center border-solid border-2 border-${open ? (locked ? 'error' : 'secondary') : 'primary'} rounded-lg w-full h-32`"
:class="`flex items-center justify-center border-solid border-2 border-${opened ? (locked ? 'error' : 'secondary') : 'primary'} rounded-lg w-full h-32`"
>
<UIcon
:name="
open
opened
? 'material-symbols:door-open'
: 'material-symbols:door-front'
"
@@ -17,9 +17,9 @@
</div>
<p
:class="`flex items-center justify-center text-${open ? (locked ? 'error' : 'secondary') : 'primary'} text-xl w-full h-10`"
:class="`flex items-center justify-center text-${opened ? (locked ? 'error' : 'secondary') : 'primary'} text-xl w-full h-10`"
>
{{ open ? "Opened" : "Closed" }}
{{ opened ? "Opened" : "Closed" }}
</p>
</div>
@@ -55,11 +55,11 @@
<div class="flex items-center justify-center flex-col gap-y-2 w-32">
<div
:class="`flex items-center justify-center border-solid border-2 border-${alert ? 'primary' : 'secondary'} rounded-lg w-full h-32`"
:class="`flex items-center justify-center border-solid border-2 border-${alerts ? 'primary' : 'secondary'} rounded-lg w-full h-32`"
>
<UIcon
:name="
alert
alerts
? 'material-symbols:volume-up'
: 'material-symbols:volume-off'
"
@@ -69,17 +69,17 @@
<UButton
:icon="
alert
alerts
? 'material-symbols:volume-off'
: 'material-symbols:volume-up'
"
size="xl"
:color="alert ? 'primary' : 'secondary'"
:color="alerts ? 'primary' : 'secondary'"
variant="solid"
class="flex items-center justify-center w-full h-10"
@click="toggleAlert"
>
{{ alert ? "Turn off" : "Turn on" }}
{{ alerts ? "Turn off" : "Turn on" }}
</UButton>
</div>
</main>
@@ -90,9 +90,9 @@ import axios from "axios"
const token = useToken()
const open = ref(true)
const opened = ref(true)
const locked = ref(true)
const alert = ref(false)
const alerts = ref(false)
const toast = useToast()
@@ -120,7 +120,7 @@ async function toggleLock() {
}
async function toggleAlert() {
const desired = !alert.value
const desired = !alerts.value
axios
.post(useAPI("/alerts"), { alert: desired }, { headers: useHeaders() })
.then((res) => {
@@ -128,7 +128,7 @@ async function toggleAlert() {
toast.add({
title: `Alerts were turned ${desired ? "on" : "off"}`,
})
alert.value = desired
alerts.value = desired
})
})
.catch(handleRequestError)
@@ -139,26 +139,43 @@ onMounted(() => {
return navigateTo("/token")
}
axios
.get<boolean>(useAPI("/locked"), {
headers: useHeaders(),
})
.then((res) => {
handleResponse(res, (res) => {
locked.value = res.data
setInterval(() => {
axios
.get<boolean>(useAPI("/opened"), {
headers: useHeaders(),
})
})
.catch(handleRequestError)
.then((res) => {
handleResponse(res, (res) => {
opened.value = res.data
})
})
.catch(handleRequestError)
}, 1000)
axios
.get<boolean>(useAPI("/alerts"), {
headers: useHeaders(),
})
.then((res) => {
handleResponse(res, (res) => {
alert.value = res.data
setInterval(() => {
axios
.get<boolean>(useAPI("/locked"), {
headers: useHeaders(),
})
})
.catch(handleRequestError)
.then((res) => {
handleResponse(res, (res) => {
locked.value = res.data
})
})
.catch(handleRequestError)
}, 1000)
setInterval(() => {
axios
.get<boolean>(useAPI("/alerts"), {
headers: useHeaders(),
})
.then((res) => {
handleResponse(res, (res) => {
alerts.value = res.data
})
})
.catch(handleRequestError)
}, 1000)
})
</script>