Add support for editing individual lock code slots
Some checks failed
/ build-container (push) Has been cancelled
Some checks failed
/ build-container (push) Has been cancelled
This commit is contained in:
parent
6ec7434ab6
commit
cafbd63f98
7 changed files with 44 additions and 8 deletions
|
@ -130,7 +130,7 @@ func (q *Queries) GetLockCodesByCode(ctx context.Context, code string) ([]LockCo
|
||||||
}
|
}
|
||||||
|
|
||||||
const upsertCodeSlot = `-- name: UpsertCodeSlot :exec
|
const upsertCodeSlot = `-- name: UpsertCodeSlot :exec
|
||||||
INSERT INTO lock_code_slots (lock, slot, code, enabled, name) VALUES (?, ?, ?, ?, "") ON CONFLICT (lock, slot) DO UPDATE SET code=excluded.code, enabled=excluded.enabled
|
INSERT INTO lock_code_slots (lock, slot, code, enabled, name) VALUES (?, ?, ?, ?, ?) ON CONFLICT (lock, slot) DO UPDATE SET code=excluded.code, enabled=excluded.enabled, name=excluded.name
|
||||||
`
|
`
|
||||||
|
|
||||||
type UpsertCodeSlotParams struct {
|
type UpsertCodeSlotParams struct {
|
||||||
|
@ -138,6 +138,7 @@ type UpsertCodeSlotParams struct {
|
||||||
Slot int64
|
Slot int64
|
||||||
Code string
|
Code string
|
||||||
Enabled bool
|
Enabled bool
|
||||||
|
Name string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Queries) UpsertCodeSlot(ctx context.Context, arg UpsertCodeSlotParams) error {
|
func (q *Queries) UpsertCodeSlot(ctx context.Context, arg UpsertCodeSlotParams) error {
|
||||||
|
@ -146,6 +147,7 @@ func (q *Queries) UpsertCodeSlot(ctx context.Context, arg UpsertCodeSlotParams)
|
||||||
arg.Slot,
|
arg.Slot,
|
||||||
arg.Code,
|
arg.Code,
|
||||||
arg.Enabled,
|
arg.Enabled,
|
||||||
|
arg.Name,
|
||||||
)
|
)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
-- name: UpsertCodeSlot :exec
|
-- name: UpsertCodeSlot :exec
|
||||||
INSERT INTO lock_code_slots (lock, slot, code, enabled, name) VALUES (?, ?, ?, ?, "") ON CONFLICT (lock, slot) DO UPDATE SET code=excluded.code, enabled=excluded.enabled;
|
INSERT INTO lock_code_slots (lock, slot, code, enabled, name) VALUES (?, ?, ?, ?, ?) ON CONFLICT (lock, slot) DO UPDATE SET code=excluded.code, enabled=excluded.enabled, name=excluded.name;
|
||||||
|
|
||||||
-- name: GetLockCodeBySlot :one
|
-- name: GetLockCodeBySlot :one
|
||||||
SELECT * FROM lock_code_slots WHERE lock = ? AND slot = ?;
|
SELECT * FROM lock_code_slots WHERE lock = ? AND slot = ?;
|
||||||
|
|
|
@ -10,4 +10,5 @@
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="wrapper">
|
<div id="wrapper">
|
||||||
|
<a href="/">Home</a>
|
||||||
<div id="main">
|
<div id="main">
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
{{ template "header.html" . }}
|
{{ template "header.html" . }}
|
||||||
<header>Rename {{ if eq .Data.Name "" }}Lock #{{ .Data.ID }}{{ else }}{{ .Data.Name }}{{ end }}</header>
|
<header>{{ if eq .Data.Name "" }}Lock #{{ .Data.ID }}{{ else }}{{ .Data.Name }}{{ end }}</header>
|
||||||
<form method="post">
|
<form method="post">
|
||||||
|
Code: <input type="text" name="code" value="{{ .Data.Code }}" /><br />
|
||||||
Name: <input type="text" name="name" value="{{ .Data.Name }}" /><br />
|
Name: <input type="text" name="name" value="{{ .Data.Name }}" /><br />
|
||||||
|
Enabled: <input type="checkbox" name="enabled" {{ if .Data.Enabled }}checked{{ end }} /><br />
|
||||||
|
<br />
|
||||||
<input type="submit" value="save" />
|
<input type="submit" value="save" />
|
||||||
</form>
|
</form>
|
||||||
{{ template "footer.html" }}
|
{{ template "footer.html" }}
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
{{ template "header.html" . }}
|
{{ template "header.html" . }}
|
||||||
<header>{{ if eq .Data.lock.Name "" }}Lock #{{ .Data.lock.ID }}{{ else }}{{ .Data.lock.Name }}{{ end }}</header>
|
<header>{{ if eq .Data.lock.Name "" }}Lock #{{ .Data.lock.ID }}{{ else }}{{ .Data.lock.Name }}{{ end }}</header>
|
||||||
[ <a href="/locks/{{ .Data.lock.ID }}/edit">rename</a> ]
|
[ <a href="/locks/{{ .Data.lock.ID }}/edit">rename</a> ]<br />
|
||||||
<br />
|
<br />
|
||||||
<table border="1">
|
<table border="1">
|
||||||
<tr>
|
<tr>
|
||||||
<td>Slot</td>
|
<td>Slot</td>
|
||||||
|
<td>Name</td>
|
||||||
<td>Code</td>
|
<td>Code</td>
|
||||||
<td>Enabled?</td>
|
<td>Enabled?</td>
|
||||||
<td>Actions</td>
|
<td>Actions</td>
|
||||||
|
@ -12,6 +13,7 @@
|
||||||
{{ range $_, $code := .Data.codes }}
|
{{ range $_, $code := .Data.codes }}
|
||||||
<tr class="code-{{ if $code.Enabled }}enabled{{ else }}disabled{{ end }}">
|
<tr class="code-{{ if $code.Enabled }}enabled{{ else }}disabled{{ end }}">
|
||||||
<td>{{ $code.Slot }}</td>
|
<td>{{ $code.Slot }}</td>
|
||||||
|
<td>{{ $code.Name }}</td>
|
||||||
<td>{{ $code.Code }}</td>
|
<td>{{ $code.Code }}</td>
|
||||||
<td>{{ if $code.Enabled }}enabled{{ else }}disabled{{ end }}</td>
|
<td>{{ if $code.Enabled }}enabled{{ else }}disabled{{ end }}</td>
|
||||||
<td>[ <a href="/locks/{{ $.Data.lock.ID }}/codes/{{ $code.Slot }}">edit</a> ]</td>
|
<td>[ <a href="/locks/{{ $.Data.lock.ID }}/codes/{{ $code.Slot }}">edit</a> ]</td>
|
||||||
|
|
|
@ -111,9 +111,27 @@ func lockCodeEditHandler(c echo.Context) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
newCode := c.FormValue("code")
|
|
||||||
|
|
||||||
zwaveClient := c.Get(contextKeyZWaveClient).(*zwavejs.Client)
|
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 := c.FormValue("code")
|
||||||
err = zwaveClient.SetNodeValue(ctx, int(lock.ZwaveDeviceID), zwavejs.NodeValue{
|
err = zwaveClient.SetNodeValue(ctx, int(lock.ZwaveDeviceID), zwavejs.NodeValue{
|
||||||
CCVersion: 1,
|
CCVersion: 1,
|
||||||
CommandClassName: zwavejs.CommandClassNameUserCode,
|
CommandClassName: zwavejs.CommandClassNameUserCode,
|
||||||
|
@ -131,7 +149,8 @@ func lockCodeEditHandler(c echo.Context) error {
|
||||||
Lock: lockID,
|
Lock: lockID,
|
||||||
Slot: slot,
|
Slot: slot,
|
||||||
Code: newCode,
|
Code: newCode,
|
||||||
Enabled: true,
|
Name: c.FormValue("name"),
|
||||||
|
Enabled: enabled,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -43,8 +43,10 @@ func (c *Client) DialAndListen(ctx context.Context) {
|
||||||
|
|
||||||
for {
|
for {
|
||||||
logrus.WithField("server", c.Server).Info("connecting to zwave-js server")
|
logrus.WithField("server", c.Server).Info("connecting to zwave-js server")
|
||||||
|
ctxWithTimeout, cancel := context.WithTimeout(ctx, time.Second*5)
|
||||||
|
defer cancel()
|
||||||
conn, err := failsafe.Get(func() (*websocket.Conn, error) {
|
conn, err := failsafe.Get(func() (*websocket.Conn, error) {
|
||||||
conn, _, err := websocket.DefaultDialer.DialContext(ctx, c.Server, nil)
|
conn, _, err := websocket.DefaultDialer.DialContext(ctxWithTimeout, c.Server, nil)
|
||||||
return conn, err
|
return conn, err
|
||||||
}, connectRetryPolicy)
|
}, connectRetryPolicy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -63,6 +65,7 @@ func (c *Client) DialAndListen(ctx context.Context) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
_ = c.conn.Close()
|
_ = c.conn.Close()
|
||||||
|
cancel()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,6 +237,8 @@ func (c *Client) handleCallback(messageID string, result Result) error {
|
||||||
c.callbacksLock.Lock()
|
c.callbacksLock.Lock()
|
||||||
defer c.callbacksLock.Unlock()
|
defer c.callbacksLock.Unlock()
|
||||||
|
|
||||||
|
logrus.WithField("message_id", messageID).Debug(fmt.Sprintf("%+v", result))
|
||||||
|
|
||||||
cb, ok := c.callbacks[messageID]
|
cb, ok := c.callbacks[messageID]
|
||||||
if !ok {
|
if !ok {
|
||||||
logrus.WithField("message_id", messageID).Warn("got response to a message we didn't send")
|
logrus.WithField("message_id", messageID).Warn("got response to a message we didn't send")
|
||||||
|
@ -255,6 +260,10 @@ func (c *Client) sendMessage(message OutgoingMessageIface) (Result, error) {
|
||||||
c.callbacks[messageID] = ch
|
c.callbacks[messageID] = ch
|
||||||
c.callbacksLock.Unlock()
|
c.callbacksLock.Unlock()
|
||||||
|
|
||||||
|
// w := logrus.WithField("message_id", messageID).Writer()
|
||||||
|
// json.NewEncoder(w).Encode(message)
|
||||||
|
// w.Close()
|
||||||
|
|
||||||
if err := c.conn.WriteJSON(message); err != nil {
|
if err := c.conn.WriteJSON(message); err != nil {
|
||||||
return Result{}, err
|
return Result{}, err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue