lockserver/httpserver/lock.go
Finn a26b9cc63e
All checks were successful
/ build-container (push) Successful in 8m14s
Show logs when editing a code
2024-11-24 16:08:06 -08:00

181 lines
4.7 KiB
Go

package httpserver
import (
"database/sql"
"errors"
"fmt"
"net/http"
"strconv"
"git.janky.solutions/finn/lockserver/db"
"git.janky.solutions/finn/lockserver/zwavejs"
echo "github.com/labstack/echo/v4"
"github.com/sirupsen/logrus"
)
func lockHandler(c echo.Context) error {
lockID, err := strconv.ParseInt(c.Param("lock"), 10, 32)
if err != nil {
return fmt.Errorf("invalid lock ID: %v", err)
}
ctx := c.Request().Context()
queries, dbc, err := db.Get()
if err != nil {
return err
}
defer dbc.Close()
lock, err := queries.GetLock(ctx, lockID)
if err != nil {
return err
}
codes, err := queries.GetAllLockCodesByLock(ctx, lockID)
if err != nil {
return err
}
return c.Render(http.StatusFound, "lock.html", map[string]interface{}{
"lock": lock,
"codes": codes,
})
}
func lockEditHandler(c echo.Context) error {
lockID, err := strconv.ParseInt(c.Param("lock"), 10, 32)
if err != nil {
return fmt.Errorf("invalid lock ID: %v", err)
}
ctx := c.Request().Context()
queries, dbc, err := db.Get()
if err != nil {
return err
}
defer dbc.Close()
if c.Request().Method == http.MethodGet {
lock, err := queries.GetLock(ctx, lockID)
if err != nil {
return err
}
// return frontend.Templates.ExecuteTemplate(c.Response(), "lock-edit.html", lock)
return c.Render(http.StatusFound, "lock-edit.html", lock)
}
err = queries.UpdateLockName(ctx, db.UpdateLockNameParams{
ID: lockID,
Name: c.FormValue("name"),
})
if err != nil {
return err
}
baseURL := c.Request().Header.Get("X-Ingress-Path")
return c.Redirect(http.StatusFound, fmt.Sprintf("%s/locks/%d", baseURL, lockID))
}
func lockCodeEditHandler(c echo.Context) error {
lockID, err := strconv.ParseInt(c.Param("lock"), 10, 32)
if err != nil {
return fmt.Errorf("invalid lock ID: %v", err)
}
slot, err := strconv.ParseInt(c.Param("slot"), 10, 32)
if err != nil {
return fmt.Errorf("invalid lock ID: %v", err)
}
ctx := c.Request().Context()
queries, dbc, err := db.Get()
if err != nil {
return err
}
defer dbc.Close()
code, err := queries.GetLockCodeBySlot(ctx, db.GetLockCodeBySlotParams{
Lock: lockID,
Slot: slot,
})
if err != nil {
return err
}
lock, err := queries.GetLock(ctx, lockID)
if err != nil {
return err
}
if c.Request().Method == http.MethodGet {
logrus.WithField("lock", lockID).WithField("code", code.ID).Debug("querying logs")
log, err := queries.GetLogForSlot(ctx, db.GetLogForSlotParams{
Lock: lockID,
Code: db.NullInt64(code.ID),
})
if err != nil && !errors.Is(err, sql.ErrNoRows) {
return err
}
return c.Render(http.StatusFound, "lock-code-edit.html", map[string]interface{}{
"lock": lock,
"code": code,
"log": log,
})
}
zwaveClient := c.Get(contextKeyZWaveClient).(*zwavejs.Client)
enabled := c.FormValue("enabled") == "on"
enabledInt := 0
if enabled {
enabledInt = 1
}
err = zwaveClient.SetNodeValue(ctx, int(lock.ZwaveDeviceID), zwavejs.NodeValue{
CCVersion: 1,
CommandClassName: zwavejs.CommandClassNameUserCode,
CommandClass: zwavejs.CommandClassUserCode,
Endpoint: 0,
Property: zwavejs.AnyType{Type: zwavejs.AnyTypeString, String: string(zwavejs.PropertyUserIDStatus)},
PropertyName: zwavejs.AnyType{Type: zwavejs.AnyTypeString, String: string(zwavejs.PropertyUserIDStatus)},
PropertyKey: zwavejs.AnyType{Type: zwavejs.AnyTypeInt, Int: int(slot)},
}, zwavejs.AnyType{Type: zwavejs.AnyTypeInt, Int: enabledInt})
if err != nil {
return fmt.Errorf("error pushing enabled state to lock %s (ZWaveDeviceID=%d ID=%d): %v", lock.Name, lock.ZwaveDeviceID, lock.ID, err)
}
newCode := "0000"
if enabled {
newCode = c.FormValue("code")
err = zwaveClient.SetNodeValue(ctx, int(lock.ZwaveDeviceID), zwavejs.NodeValue{
CCVersion: 1,
CommandClassName: zwavejs.CommandClassNameUserCode,
CommandClass: zwavejs.CommandClassUserCode,
Endpoint: 0,
Property: zwavejs.AnyType{Type: zwavejs.AnyTypeString, String: string(zwavejs.PropertyUserCode)},
PropertyName: zwavejs.AnyType{Type: zwavejs.AnyTypeString, String: string(zwavejs.PropertyUserCode)},
PropertyKey: zwavejs.AnyType{Type: zwavejs.AnyTypeInt, Int: int(slot)},
}, zwavejs.AnyType{Type: zwavejs.AnyTypeString, String: newCode})
if err != nil {
return fmt.Errorf("error pushing code to lock %s (ZWaveDeviceID=%d ID=%d): %v", lock.Name, lock.ZwaveDeviceID, lock.ID, err)
}
}
err = queries.UpdateCodeSlot(ctx, db.UpdateCodeSlotParams{
Lock: lockID,
Slot: slot,
Code: newCode,
Name: c.FormValue("name"),
Enabled: enabled,
})
if err != nil {
return err
}
baseURL := c.Request().Header.Get("X-Ingress-Path")
return c.Redirect(http.StatusFound, fmt.Sprintf("%s/locks/%d", baseURL, lockID))
}