181 lines
4.7 KiB
Go
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))
|
|
}
|