added encoding keycard copy for Salto locks
This commit is contained in:
parent
b303721a92
commit
5ce9fdcf0b
@ -10,11 +10,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Build key encoding request command for the Assa Abloy lock server.
|
// Build key encoding request command for the Assa Abloy lock server.
|
||||||
func (lock *AssaLockServer) BuildCommand(lockId string, checkIn, checkOut time.Time) error {
|
func (lock *AssaLockServer) BuildCommand(doorReq DoorCardRequest, checkIn, checkOut time.Time) error {
|
||||||
ci := checkIn.Format("200601021504")
|
ci := checkIn.Format("200601021504")
|
||||||
co := checkOut.Format("200601021504")
|
co := checkOut.Format("200601021504")
|
||||||
|
|
||||||
lock.command = fmt.Sprintf("CCA;EA%s;GR%s;CO%s;CI%s;AM1;\r\n", lock.encoderAddr, lockId, co, ci)
|
lock.command = fmt.Sprintf("CCA;EA%s;GR%s;CO%s;CI%s;AM1;\r\n", lock.encoderAddr, doorReq.RoomField, co, ci)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,14 @@ import (
|
|||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// DoorCardRequest is the JSON payload for /issue-door-card.
|
||||||
|
type DoorCardRequest struct {
|
||||||
|
RoomField string `json:"roomField"`
|
||||||
|
CheckinTime string `json:"checkinTime"`
|
||||||
|
CheckoutTime string `json:"checkoutTime"`
|
||||||
|
FollowStr string `json:"followStr"`
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
AssaAbloy = "assaabloy"
|
AssaAbloy = "assaabloy"
|
||||||
Omnitec = "omnitec"
|
Omnitec = "omnitec"
|
||||||
@ -20,7 +28,7 @@ const (
|
|||||||
|
|
||||||
type (
|
type (
|
||||||
LockServer interface {
|
LockServer interface {
|
||||||
BuildCommand(lockId string, checkIn, checkOut time.Time) error
|
BuildCommand(doorReq DoorCardRequest, checkIn, checkOut time.Time) error
|
||||||
LockSequence(conn net.Conn) error
|
LockSequence(conn net.Conn) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Build key encoding request command for the Omnitec lock server.
|
// Build key encoding request command for the Omnitec lock server.
|
||||||
func (lock *OmniLockServer) BuildCommand(lockId string, checkIn, checkOut time.Time) error {
|
func (lock *OmniLockServer) BuildCommand(doorReq DoorCardRequest, checkIn, checkOut time.Time) error {
|
||||||
const funcName = "OmniLockServer.BuildCommand"
|
const funcName = "OmniLockServer.BuildCommand"
|
||||||
hostname, err := os.Hostname()
|
hostname, err := os.Hostname()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -21,7 +21,7 @@ func (lock *OmniLockServer) BuildCommand(lockId string, checkIn, checkOut time.T
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Format lockId as 4-digit zero-padded string
|
// Format lockId as 4-digit zero-padded string
|
||||||
idInt, err := strconv.Atoi(lockId)
|
idInt, err := strconv.Atoi(doorReq.RoomField)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("[%s] failed to convert lockId to integer: %v", funcName, err)
|
return fmt.Errorf("[%s] failed to convert lockId to integer: %v", funcName, err)
|
||||||
}
|
}
|
||||||
|
@ -41,8 +41,9 @@ func stringJoin(parts []string, sep string) string {
|
|||||||
// BuildCommand builds a Salto card‑issuance command in the form:
|
// BuildCommand builds a Salto card‑issuance command in the form:
|
||||||
// STX|CN|<encoder addres>|E|<room>| | | | | |<start>|<expiry>|ETX|<LRC>
|
// STX|CN|<encoder addres>|E|<room>| | | | | |<start>|<expiry>|ETX|<LRC>
|
||||||
// where <start> and <expiry> are hhmmDDMMYY, and LRC is the XOR of all bytes
|
// where <start> and <expiry> are hhmmDDMMYY, and LRC is the XOR of all bytes
|
||||||
func (lock *SaltoLockServer) BuildCommand(lockId string, checkIn, checkOut time.Time) error {
|
func (lock *SaltoLockServer) BuildCommand(doorReq DoorCardRequest, checkIn, checkOut time.Time) error {
|
||||||
// format helper: hhmmDDMMYY
|
// format helper: hhmmDDMMYY
|
||||||
|
var command string
|
||||||
fmtStamp := func(t time.Time) string {
|
fmtStamp := func(t time.Time) string {
|
||||||
return fmt.Sprintf("%02d%02d%02d%02d%02d",
|
return fmt.Sprintf("%02d%02d%02d%02d%02d",
|
||||||
t.Hour(), t.Minute(), t.Day(), int(t.Month()), t.Year()%100)
|
t.Hour(), t.Minute(), t.Day(), int(t.Month()), t.Year()%100)
|
||||||
@ -51,9 +52,18 @@ func (lock *SaltoLockServer) BuildCommand(lockId string, checkIn, checkOut time.
|
|||||||
start := fmtStamp(checkIn)
|
start := fmtStamp(checkIn)
|
||||||
expiry := fmtStamp(checkOut)
|
expiry := fmtStamp(checkOut)
|
||||||
|
|
||||||
|
switch doorReq.FollowStr {
|
||||||
|
case "0":
|
||||||
|
command = "CN" // encode keycard
|
||||||
|
case "1":
|
||||||
|
command = "CC" // encode keycard copy
|
||||||
|
default:
|
||||||
|
command = "CN"
|
||||||
|
}
|
||||||
|
|
||||||
// the 12 fields between STX and ETX
|
// the 12 fields between STX and ETX
|
||||||
fields := []string{
|
fields := []string{
|
||||||
"CN", lock.encoderAddr, "E", lockId, "", "", "", "", "", "", start, expiry,
|
command, lock.encoderAddr, "E", doorReq.RoomField, "", "", "", "", "", "", start, expiry,
|
||||||
}
|
}
|
||||||
|
|
||||||
body := "|" + stringJoin(fields, "|") + "|" // leading/trailing pipes, so the ETX ends the last field
|
body := "|" + stringJoin(fields, "|") + "|" // leading/trailing pipes, so the ETX ends the last field
|
||||||
|
14
main.go
14
main.go
@ -30,7 +30,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
buildVersion = "1.0.4"
|
buildVersion = "1.0.5"
|
||||||
serviceName = "hardlink"
|
serviceName = "hardlink"
|
||||||
customLayout = "2006-01-02 15:04:05 -0700"
|
customLayout = "2006-01-02 15:04:05 -0700"
|
||||||
transactionUrl = "http://127.0.0.1:18181/start-transaction/"
|
transactionUrl = "http://127.0.0.1:18181/start-transaction/"
|
||||||
@ -49,13 +49,6 @@ type configRec struct {
|
|||||||
isPayment bool `yaml:"isPayment"`
|
isPayment bool `yaml:"isPayment"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// DoorCardRequest is the JSON payload for /issue-door-card.
|
|
||||||
type DoorCardRequest struct {
|
|
||||||
RoomField string `json:"roomField"`
|
|
||||||
CheckinTime string `json:"checkinTime"`
|
|
||||||
CheckoutTime string `json:"checkoutTime"`
|
|
||||||
FollowStr string `json:"followStr"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// App holds shared resources.
|
// App holds shared resources.
|
||||||
type App struct {
|
type App struct {
|
||||||
@ -179,6 +172,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create App and wire routes
|
// Create App and wire routes
|
||||||
|
// dispHandle := &serial.Port{} // Placeholder, replace with actual dispenser handle
|
||||||
app := newApp(dispHandle, lockConn, config)
|
app := newApp(dispHandle, lockConn, config)
|
||||||
|
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
@ -323,7 +317,7 @@ func (app *App) startTransaction(w http.ResponseWriter, r *http.Request) {
|
|||||||
func (app *App) issueDoorCard(w http.ResponseWriter, r *http.Request) {
|
func (app *App) issueDoorCard(w http.ResponseWriter, r *http.Request) {
|
||||||
const op = logging.Op("issueDoorCard")
|
const op = logging.Op("issueDoorCard")
|
||||||
var (
|
var (
|
||||||
doorReq DoorCardRequest
|
doorReq lockserver.DoorCardRequest
|
||||||
theResponse cmstypes.StatusRec
|
theResponse cmstypes.StatusRec
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -384,7 +378,7 @@ func (app *App) issueDoorCard(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// build lock server command
|
// build lock server command
|
||||||
app.lockserver.BuildCommand(doorReq.RoomField, checkIn, checkOut)
|
app.lockserver.BuildCommand(doorReq, checkIn, checkOut)
|
||||||
|
|
||||||
// lock server sequence
|
// lock server sequence
|
||||||
err = app.lockserver.LockSequence(app.lockConn)
|
err = app.lockserver.LockSequence(app.lockConn)
|
||||||
|
@ -2,9 +2,11 @@
|
|||||||
|
|
||||||
builtVersion is a const in main.go
|
builtVersion is a const in main.go
|
||||||
|
|
||||||
#### 1.0.1 - 22 July 2024
|
#### 1.0.5 - 24 July 2024
|
||||||
added salto lock server and implemented workflow for Salto
|
added encoding keycard copy for Salto locks
|
||||||
|
|
||||||
|
#### 1.0.4 - 22 July 2024
|
||||||
|
added salto lock server and implemented workflow for Salto
|
||||||
|
|
||||||
#### 1.0.0 - 30 June 2024
|
#### 1.0.0 - 30 June 2024
|
||||||
added creditcall payment method
|
added creditcall payment method
|
||||||
|
Loading…
x
Reference in New Issue
Block a user