lockserver/httpserver/lock.go

182 lines
4.7 KiB
Go
Raw Normal View History

2024-04-24 07:15:12 +00:00
package httpserver
import (
2024-11-25 00:08:06 +00:00
"database/sql"
"errors"
2024-11-23 05:15:21 +00:00
"fmt"
"net/http"
"strconv"
2024-04-24 07:15:12 +00:00
2024-11-23 05:15:21 +00:00
"git.janky.solutions/finn/lockserver/db"
"git.janky.solutions/finn/lockserver/zwavejs"
2024-04-24 07:15:12 +00:00
echo "github.com/labstack/echo/v4"
2024-11-25 00:08:06 +00:00
"github.com/sirupsen/logrus"
2024-04-24 07:15:12 +00:00
)
func lockHandler(c echo.Context) error {
2024-11-23 05:15:21 +00:00
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
}
2024-11-23 09:50:46 +00:00
baseURL := c.Request().Header.Get("X-Ingress-Path")
return c.Redirect(http.StatusFound, fmt.Sprintf("%s/locks/%d", baseURL, lockID))
2024-11-23 05:15:21 +00:00
}
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
}
2024-11-23 07:12:26 +00:00
if c.Request().Method == http.MethodGet {
2024-11-25 00:08:06 +00:00
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
}
2024-11-23 07:12:26 +00:00
return c.Render(http.StatusFound, "lock-code-edit.html", map[string]interface{}{
"lock": lock,
"code": code,
2024-11-25 00:08:06 +00:00
"log": log,
2024-11-23 07:12:26 +00:00
})
}
2024-11-23 05:15:21 +00:00
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)
}
2024-11-23 07:01:26 +00:00
newCode := "0000"
if enabled {
2024-11-23 07:12:26 +00:00
newCode = c.FormValue("code")
2024-11-23 07:01:26 +00:00
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)
}
2024-11-23 05:15:21 +00:00
}
err = queries.UpdateCodeSlot(ctx, db.UpdateCodeSlotParams{
2024-11-23 05:15:21 +00:00
Lock: lockID,
Slot: slot,
Code: newCode,
Name: c.FormValue("name"),
Enabled: enabled,
2024-11-23 05:15:21 +00:00
})
if err != nil {
return err
}
2024-11-23 09:50:46 +00:00
baseURL := c.Request().Header.Get("X-Ingress-Path")
return c.Redirect(http.StatusFound, fmt.Sprintf("%s/locks/%d", baseURL, lockID))
2024-04-24 07:15:12 +00:00
}