release version 1.1.0
This commit is contained in:
parent
9f0a9c939f
commit
4a255c06ed
@ -3,6 +3,8 @@ package dispenser
|
|||||||
import (
|
import (
|
||||||
// "encoding/hex"
|
// "encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
// "log"
|
// "log"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -69,9 +71,7 @@ var (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func checkStatus(statusResp []byte) (string, error) {
|
func logStatus(statusBytes []byte) {
|
||||||
if len(statusResp) > 3 {
|
|
||||||
statusBytes := statusResp[7:11] // Extract the relevant bytes from the response
|
|
||||||
// For each position, get the ASCII character, hex value, and mapped meaning.
|
// For each position, get the ASCII character, hex value, and mapped meaning.
|
||||||
posStatus := []struct {
|
posStatus := []struct {
|
||||||
pos int
|
pos int
|
||||||
@ -84,29 +84,65 @@ func checkStatus(statusResp []byte) (string, error) {
|
|||||||
{pos: 4, value: statusBytes[3], mapper: statusPos3},
|
{pos: 4, value: statusBytes[3], mapper: statusPos3},
|
||||||
}
|
}
|
||||||
|
|
||||||
result := ""
|
var result strings.Builder
|
||||||
for _, p := range posStatus {
|
for _, p := range posStatus {
|
||||||
statusMsg, exists := p.mapper[p.value]
|
statusMsg, exists := p.mapper[p.value]
|
||||||
if !exists {
|
if !exists {
|
||||||
statusMsg = "Unknown status"
|
statusMsg = fmt.Sprintf("Unknown status 0x%X;", p.value)
|
||||||
}
|
}
|
||||||
if p.value != 0x30 {
|
if p.value != 0x30 {
|
||||||
result += fmt.Sprintf("Status: %s; ", statusMsg)
|
result.WriteString(statusMsg + "; ")
|
||||||
}
|
|
||||||
if p.pos == 4 && p.value == 0x38 {
|
|
||||||
return result, fmt.Errorf("Card well empty")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result, nil
|
|
||||||
|
|
||||||
} else {
|
log.Infof("Dispenser status: %s", result.String())
|
||||||
if len(statusResp) == 3 && statusResp[0] == ACK && statusResp[1] == Address[0] && statusResp[2] == Address[1] {
|
|
||||||
return "active;", nil
|
|
||||||
} else if len(statusResp) > 0 && statusResp[0] == NAK {
|
|
||||||
return "", fmt.Errorf("negative response from dispenser")
|
|
||||||
} else {
|
|
||||||
return "", fmt.Errorf("unexpected response status: % X", statusResp)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isAtEncoderPosition(statusBytes []byte) bool {
|
||||||
|
if statusBytes == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
switch statusBytes[3] {
|
||||||
|
case 0x33: // Card at encoder position
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false // Not at encoder position
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func stockTake(statusBytes []byte) string {
|
||||||
|
status := ""
|
||||||
|
if statusBytes == nil {
|
||||||
|
return status
|
||||||
|
}
|
||||||
|
if statusBytes[2] != 0x30 {
|
||||||
|
status = statusPos2[statusBytes[2]]
|
||||||
|
}
|
||||||
|
if statusBytes[3] == 0x38 { // Card well empty
|
||||||
|
status = statusPos3[statusBytes[3]]
|
||||||
|
}
|
||||||
|
return status
|
||||||
|
}
|
||||||
|
|
||||||
|
func isCardWellEmpty(statusBytes []byte) bool {
|
||||||
|
if statusBytes == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
switch statusBytes[3] {
|
||||||
|
case 0x38: // Card well empty
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkACK(statusResp []byte) error {
|
||||||
|
if len(statusResp) == 3 && statusResp[0] == ACK && statusResp[1] == Address[0] && statusResp[2] == Address[1] {
|
||||||
|
return nil
|
||||||
|
} else if len(statusResp) > 0 && statusResp[0] == NAK {
|
||||||
|
return fmt.Errorf("negative response from dispenser")
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("unexpected response status: % X", statusResp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,47 +207,130 @@ func InitializeDispenser() (*serial.Port, error) {
|
|||||||
return port, nil
|
return port, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func DispenserSequence(port *serial.Port) (string, error) {
|
func DispenserPrepare(port *serial.Port) (string, error) {
|
||||||
const funcName = "dispenserSequence"
|
const funcName = "dispenserSequence"
|
||||||
var result string
|
stockStatus := ""
|
||||||
|
|
||||||
// Check dispenser status
|
// Check dispenser status
|
||||||
status, err := CheckDispenserStatus(port)
|
status, err := CheckDispenserStatus(port)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return status, fmt.Errorf("[%s] error checking dispenser status: %v", funcName, err)
|
return stockStatus, fmt.Errorf("[%s] error checking dispenser status: %v", funcName, err)
|
||||||
|
}
|
||||||
|
logStatus(status)
|
||||||
|
stockStatus = stockTake(status)
|
||||||
|
if isCardWellEmpty(status) {
|
||||||
|
return stockStatus, nil
|
||||||
}
|
}
|
||||||
result += status
|
|
||||||
|
|
||||||
|
if isAtEncoderPosition(status) {
|
||||||
|
return stockStatus, nil
|
||||||
|
}
|
||||||
// Send card to encoder position
|
// Send card to encoder position
|
||||||
status, err = CardToEncoderPosition(port)
|
err = CardToEncoderPosition(port)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return status, fmt.Errorf("[%s] error sending card to encoder position: %v", funcName, err)
|
return stockStatus, fmt.Errorf("[%s] error sending card to encoder position: %v", funcName, err)
|
||||||
}
|
}
|
||||||
result += "; " + status
|
|
||||||
|
|
||||||
return result, nil
|
time.Sleep(delay)
|
||||||
|
// Check dispenser status
|
||||||
|
status, err = CheckDispenserStatus(port)
|
||||||
|
if err != nil {
|
||||||
|
return stockStatus, fmt.Errorf("[%s] error checking dispenser status: %v", funcName, err)
|
||||||
|
}
|
||||||
|
logStatus(status)
|
||||||
|
stockStatus = stockTake(status)
|
||||||
|
|
||||||
|
return stockStatus, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DispenserStart(port *serial.Port) (string, error) {
|
||||||
|
const funcName = "dispenserSequence"
|
||||||
|
stockStatus := ""
|
||||||
|
// Check dispenser status
|
||||||
|
status, err := CheckDispenserStatus(port)
|
||||||
|
if err != nil {
|
||||||
|
return stockStatus, fmt.Errorf("[%s] error checking dispenser status: %v", funcName, err)
|
||||||
|
}
|
||||||
|
logStatus(status)
|
||||||
|
stockStatus = stockTake(status)
|
||||||
|
if isCardWellEmpty(status) {
|
||||||
|
return stockStatus, fmt.Errorf(stockStatus)
|
||||||
|
}
|
||||||
|
|
||||||
|
if isAtEncoderPosition(status) {
|
||||||
|
return stockStatus, nil
|
||||||
|
}
|
||||||
|
// Send card to encoder position
|
||||||
|
err = CardToEncoderPosition(port)
|
||||||
|
if err != nil {
|
||||||
|
return stockStatus, fmt.Errorf("[%s] error sending card to encoder position: %v", funcName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
time.Sleep(delay)
|
||||||
|
// Check dispenser status
|
||||||
|
status, err = CheckDispenserStatus(port)
|
||||||
|
if err != nil {
|
||||||
|
return stockStatus, fmt.Errorf("[%s] error checking dispenser status: %v", funcName, err)
|
||||||
|
}
|
||||||
|
logStatus(status)
|
||||||
|
stockStatus = stockTake(status)
|
||||||
|
|
||||||
|
return stockStatus, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DispenserFinal(port *serial.Port) (string, error) {
|
||||||
|
const funcName = "dispenserSequence"
|
||||||
|
stockStatus := ""
|
||||||
|
|
||||||
|
err := CardOutOfMouth(port)
|
||||||
|
if err != nil {
|
||||||
|
return stockStatus, fmt.Errorf("[%s] error sending card to out mouth position: %v", funcName, err)
|
||||||
|
}
|
||||||
|
time.Sleep(delay)
|
||||||
|
// Check dispenser status
|
||||||
|
status, err := CheckDispenserStatus(port)
|
||||||
|
if err != nil {
|
||||||
|
return stockStatus, fmt.Errorf("[%s] error checking dispenser status: %v", funcName, err)
|
||||||
|
}
|
||||||
|
logStatus(status)
|
||||||
|
stockStatus = stockTake(status)
|
||||||
|
|
||||||
|
time.Sleep(delay)
|
||||||
|
// Send card to encoder position
|
||||||
|
err = CardToEncoderPosition(port)
|
||||||
|
if err != nil {
|
||||||
|
return stockStatus, fmt.Errorf("[%s] error sending card to encoder position: %v", funcName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
time.Sleep(delay)
|
||||||
|
// Check dispenser status
|
||||||
|
status, err = CheckDispenserStatus(port)
|
||||||
|
if err != nil {
|
||||||
|
return stockStatus, fmt.Errorf("[%s] error checking dispenser status: %v", funcName, err)
|
||||||
|
}
|
||||||
|
logStatus(status)
|
||||||
|
stockStatus = stockTake(status)
|
||||||
|
|
||||||
|
return stockStatus, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// if dispenser is not responding, I should repeat the command
|
// if dispenser is not responding, I should repeat the command
|
||||||
func CheckDispenserStatus(port *serial.Port) (string, error) {
|
func CheckDispenserStatus(port *serial.Port) ([]byte, error) {
|
||||||
const funcName = "checkDispenserStatus"
|
const funcName = "checkDispenserStatus"
|
||||||
var result string
|
|
||||||
checkCmd := buildCheckAP(Address)
|
checkCmd := buildCheckAP(Address)
|
||||||
enq := append([]byte{ENQ}, Address...)
|
enq := append([]byte{ENQ}, Address...)
|
||||||
|
|
||||||
// Send check command (AP)
|
// Send check command (AP)
|
||||||
statusResp, err := sendAndReceive(port, checkCmd, delay)
|
statusResp, err := sendAndReceive(port, checkCmd, delay)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("error sending check command: %v", err)
|
return nil, fmt.Errorf("error sending check command: %v", err)
|
||||||
}
|
}
|
||||||
if len(statusResp) == 0 {
|
if len(statusResp) == 0 {
|
||||||
return "", fmt.Errorf("no response from dispenser")
|
return nil, fmt.Errorf("no response from dispenser")
|
||||||
}
|
}
|
||||||
status, err := checkStatus(statusResp)
|
err = checkACK(statusResp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return status, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result += "; " + status
|
|
||||||
|
|
||||||
// Send ENQ+ADDR to prompt device to execute the command.
|
// Send ENQ+ADDR to prompt device to execute the command.
|
||||||
statusResp, err = sendAndReceive(port, enq, delay)
|
statusResp, err = sendAndReceive(port, enq, delay)
|
||||||
@ -219,17 +338,15 @@ func CheckDispenserStatus(port *serial.Port) (string, error) {
|
|||||||
log.Errorf("error sending ENQ: %v", err)
|
log.Errorf("error sending ENQ: %v", err)
|
||||||
}
|
}
|
||||||
if len(statusResp) == 0 {
|
if len(statusResp) == 0 {
|
||||||
return "", fmt.Errorf("no response from dispenser")
|
return nil, fmt.Errorf("no response from dispenser")
|
||||||
}
|
}
|
||||||
status, err = checkStatus(statusResp)
|
if len(statusResp) < 13 {
|
||||||
if err != nil {
|
return nil, fmt.Errorf("incomplete status response from dispenser: % X", statusResp)
|
||||||
return status, err
|
|
||||||
}
|
}
|
||||||
result += status
|
return statusResp[7:11], nil // Return status bytes
|
||||||
return result, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func CardToEncoderPosition(port *serial.Port) (string, error) {
|
func CardToEncoderPosition(port *serial.Port) error {
|
||||||
const funcName = "cartToEncoderPosition"
|
const funcName = "cartToEncoderPosition"
|
||||||
enq := append([]byte{ENQ}, Address...)
|
enq := append([]byte{ENQ}, Address...)
|
||||||
|
|
||||||
@ -238,30 +355,22 @@ func CardToEncoderPosition(port *serial.Port) (string, error) {
|
|||||||
log.Println("Send card to encoder position")
|
log.Println("Send card to encoder position")
|
||||||
statusResp, err := sendAndReceive(port, dispenseCmd, delay)
|
statusResp, err := sendAndReceive(port, dispenseCmd, delay)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("error sending card to encoder position: %v", err)
|
return fmt.Errorf("error sending card to encoder position: %v", err)
|
||||||
}
|
}
|
||||||
_, err = checkStatus(statusResp)
|
err = checkACK(statusResp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
//Send ENQ to prompt device ---
|
//Send ENQ to prompt device ---
|
||||||
_, err = port.Write(enq)
|
_, err = port.Write(enq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("error sending ENQ to prompt device: %v", err)
|
return fmt.Errorf("error sending ENQ to prompt device: %v", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
time.Sleep(delay)
|
func CardOutOfMouth(port *serial.Port) error {
|
||||||
|
|
||||||
//Check card position status
|
|
||||||
status, err := CheckDispenserStatus(port)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return status, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func CardOutOfMouth(port *serial.Port) (string, error) {
|
|
||||||
const funcName = "CardOutOfMouth"
|
const funcName = "CardOutOfMouth"
|
||||||
enq := append([]byte{ENQ}, Address...)
|
enq := append([]byte{ENQ}, Address...)
|
||||||
|
|
||||||
@ -270,25 +379,17 @@ func CardOutOfMouth(port *serial.Port) (string, error) {
|
|||||||
log.Println("Send card to out mouth position")
|
log.Println("Send card to out mouth position")
|
||||||
statusResp, err := sendAndReceive(port, dispenseCmd, delay)
|
statusResp, err := sendAndReceive(port, dispenseCmd, delay)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("error sending out of mouth command: %v", err)
|
return fmt.Errorf("error sending out of mouth command: %v", err)
|
||||||
}
|
}
|
||||||
_, err = checkStatus(statusResp)
|
err = checkACK(statusResp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
//Send ENQ to prompt device ---
|
//Send ENQ to prompt device ---
|
||||||
_, err = port.Write(enq)
|
_, err = port.Write(enq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("error sending ENQ to prompt device: %v", err)
|
return fmt.Errorf("error sending ENQ to prompt device: %v", err)
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
time.Sleep(delay)
|
|
||||||
|
|
||||||
//Check card position status
|
|
||||||
status, err := CheckDispenserStatus(port)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return status, nil
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,15 +33,17 @@ type App struct {
|
|||||||
db *sql.DB
|
db *sql.DB
|
||||||
cfg *config.ConfigRec
|
cfg *config.ConfigRec
|
||||||
dbMu sync.Mutex
|
dbMu sync.Mutex
|
||||||
|
cardWellStatus string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewApp(dispPort *serial.Port, lockType, encoderAddress string, db *sql.DB, cfg *config.ConfigRec) *App {
|
func NewApp(dispPort *serial.Port, lockType, encoderAddress, cardWellStatus string, db *sql.DB, cfg *config.ConfigRec) *App {
|
||||||
return &App{
|
return &App{
|
||||||
isPayment: cfg.IsPayment,
|
isPayment: cfg.IsPayment,
|
||||||
dispPort: dispPort,
|
dispPort: dispPort,
|
||||||
lockserver: lockserver.NewLockServer(lockType, encoderAddress, errorhandlers.FatalError),
|
lockserver: lockserver.NewLockServer(lockType, encoderAddress, errorhandlers.FatalError),
|
||||||
db: db,
|
db: db,
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
|
cardWellStatus: cardWellStatus,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,6 +52,7 @@ func (app *App) RegisterRoutes(mux *http.ServeMux) {
|
|||||||
mux.HandleFunc("/printroomticket", app.printRoomTicket)
|
mux.HandleFunc("/printroomticket", app.printRoomTicket)
|
||||||
mux.HandleFunc("/takepreauth", app.takePreauthorization)
|
mux.HandleFunc("/takepreauth", app.takePreauthorization)
|
||||||
mux.HandleFunc("/takepayment", app.takePayment)
|
mux.HandleFunc("/takepayment", app.takePayment)
|
||||||
|
mux.HandleFunc("/dispenserstatus", app.reportDispenserStatus)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) takePreauthorization(w http.ResponseWriter, r *http.Request) {
|
func (app *App) takePreauthorization(w http.ResponseWriter, r *http.Request) {
|
||||||
@ -278,18 +281,10 @@ func (app *App) issueDoorCard(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// dispenser sequence
|
if app.cardWellStatus, err = dispenser.DispenserStart(app.dispPort); err != nil {
|
||||||
if status, err := dispenser.DispenserSequence(app.dispPort); err != nil {
|
|
||||||
if status != "" {
|
|
||||||
logging.Error(serviceName, status, "Dispense error", string(op), "", "", 0)
|
|
||||||
errorhandlers.WriteError(w, http.StatusServiceUnavailable, "Dispense error: "+err.Error())
|
|
||||||
} else {
|
|
||||||
logging.Error(serviceName, err.Error(), "Dispense error", string(op), "", "", 0)
|
logging.Error(serviceName, err.Error(), "Dispense error", string(op), "", "", 0)
|
||||||
errorhandlers.WriteError(w, http.StatusServiceUnavailable, "Dispense error: "+err.Error()+"; check card stock")
|
errorhandlers.WriteError(w, http.StatusServiceUnavailable, "Dispense error: "+err.Error())
|
||||||
}
|
|
||||||
return
|
return
|
||||||
} else {
|
|
||||||
log.Info(status)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// build lock server command
|
// build lock server command
|
||||||
@ -299,18 +294,16 @@ func (app *App) issueDoorCard(w http.ResponseWriter, r *http.Request) {
|
|||||||
err = app.lockserver.LockSequence()
|
err = app.lockserver.LockSequence()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logging.Error(serviceName, err.Error(), "Key encoding", string(op), "", "", 0)
|
logging.Error(serviceName, err.Error(), "Key encoding", string(op), "", "", 0)
|
||||||
|
dispenser.DispenserFinal(app.dispPort)
|
||||||
errorhandlers.WriteError(w, http.StatusBadGateway, err.Error())
|
errorhandlers.WriteError(w, http.StatusBadGateway, err.Error())
|
||||||
dispenser.CardOutOfMouth(app.dispPort)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// final dispenser steps
|
// final dispenser steps
|
||||||
if status, err := dispenser.CardOutOfMouth(app.dispPort); err != nil {
|
if app.cardWellStatus, err = dispenser.DispenserFinal(app.dispPort); err != nil {
|
||||||
logging.Error(serviceName, err.Error(), "Dispenser eject error", string(op), "", "", 0)
|
logging.Error(serviceName, err.Error(), "Dispenser eject error", string(op), "", "", 0)
|
||||||
errorhandlers.WriteError(w, http.StatusServiceUnavailable, "Dispenser eject error: "+err.Error())
|
errorhandlers.WriteError(w, http.StatusServiceUnavailable, "Dispenser eject error: "+err.Error())
|
||||||
return
|
return
|
||||||
} else {
|
|
||||||
log.Info(status)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
theResponse.Code = http.StatusOK
|
theResponse.Code = http.StatusOK
|
||||||
@ -372,3 +365,12 @@ func (app *App) printRoomTicket(w http.ResponseWriter, r *http.Request) {
|
|||||||
Message: "Print job sent successfully",
|
Message: "Print job sent successfully",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (app *App) reportDispenserStatus(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
json.NewEncoder(w).Encode(cmstypes.StatusRec{
|
||||||
|
Code: http.StatusOK,
|
||||||
|
Message: app.cardWellStatus,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@ -155,7 +155,7 @@ func (lock *SaltoLockServer) LockSequence() error {
|
|||||||
reader := bufio.NewReader(conn)
|
reader := bufio.NewReader(conn)
|
||||||
|
|
||||||
// 1. Send ENQ
|
// 1. Send ENQ
|
||||||
log.Infof("Sending ENQ")
|
log.Infof("LockSequence: sending ENQ")
|
||||||
if _, e := conn.Write([]byte{ENQ}); e != nil {
|
if _, e := conn.Write([]byte{ENQ}); e != nil {
|
||||||
return fmt.Errorf("failed to send ENQ: %w", e)
|
return fmt.Errorf("failed to send ENQ: %w", e)
|
||||||
}
|
}
|
||||||
@ -166,7 +166,7 @@ func (lock *SaltoLockServer) LockSequence() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 3. Send command frame
|
// 3. Send command frame
|
||||||
log.Infof("Sending encoding command: %q", string(lock.command))
|
log.Infof("LockSequence: sending encoding command: %q", string(lock.command))
|
||||||
if _, e := conn.Write(lock.command); e != nil {
|
if _, e := conn.Write(lock.command); e != nil {
|
||||||
return fmt.Errorf("failed to send command frame: %w", e)
|
return fmt.Errorf("failed to send command frame: %w", e)
|
||||||
}
|
}
|
||||||
|
|||||||
16
main.go
16
main.go
@ -18,15 +18,15 @@ import (
|
|||||||
"gitea.futuresens.co.uk/futuresens/hardlink/bootstrap"
|
"gitea.futuresens.co.uk/futuresens/hardlink/bootstrap"
|
||||||
"gitea.futuresens.co.uk/futuresens/hardlink/config"
|
"gitea.futuresens.co.uk/futuresens/hardlink/config"
|
||||||
"gitea.futuresens.co.uk/futuresens/hardlink/dispenser"
|
"gitea.futuresens.co.uk/futuresens/hardlink/dispenser"
|
||||||
"gitea.futuresens.co.uk/futuresens/hardlink/handlers"
|
|
||||||
"gitea.futuresens.co.uk/futuresens/hardlink/errorhandlers"
|
"gitea.futuresens.co.uk/futuresens/hardlink/errorhandlers"
|
||||||
|
"gitea.futuresens.co.uk/futuresens/hardlink/handlers"
|
||||||
"gitea.futuresens.co.uk/futuresens/hardlink/lockserver"
|
"gitea.futuresens.co.uk/futuresens/hardlink/lockserver"
|
||||||
"gitea.futuresens.co.uk/futuresens/hardlink/logging"
|
"gitea.futuresens.co.uk/futuresens/hardlink/logging"
|
||||||
"gitea.futuresens.co.uk/futuresens/hardlink/printer"
|
"gitea.futuresens.co.uk/futuresens/hardlink/printer"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
buildVersion = "1.0.30"
|
buildVersion = "1.1.0"
|
||||||
serviceName = "hardlink"
|
serviceName = "hardlink"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -38,6 +38,7 @@ func main() {
|
|||||||
lockserver.Cert = config.Cert
|
lockserver.Cert = config.Cert
|
||||||
lockserver.LockServerURL = config.LockserverUrl
|
lockserver.LockServerURL = config.LockserverUrl
|
||||||
dispHandle := &serial.Port{}
|
dispHandle := &serial.Port{}
|
||||||
|
cardWellStatus := ""
|
||||||
|
|
||||||
// Setup logging and get file handle
|
// Setup logging and get file handle
|
||||||
logFile, err := logging.SetupLogging(config.LogDir, serviceName, buildVersion)
|
logFile, err := logging.SetupLogging(config.LogDir, serviceName, buildVersion)
|
||||||
@ -56,17 +57,12 @@ func main() {
|
|||||||
}
|
}
|
||||||
defer dispHandle.Close()
|
defer dispHandle.Close()
|
||||||
|
|
||||||
status, err := dispenser.CheckDispenserStatus(dispHandle)
|
cardWellStatus, err = dispenser.DispenserPrepare(dispHandle)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if len(status) == 0 {
|
|
||||||
err = fmt.Errorf("%s; wrong dispenser address: %s", err, config.DispenserAdrr)
|
err = fmt.Errorf("%s; wrong dispenser address: %s", err, config.DispenserAdrr)
|
||||||
errorhandlers.FatalError(err)
|
errorhandlers.FatalError(err)
|
||||||
} else {
|
|
||||||
fmt.Println(status)
|
|
||||||
fmt.Println(err.Error())
|
|
||||||
}
|
}
|
||||||
}
|
fmt.Println(cardWellStatus)
|
||||||
log.Infof("Dispenser initialized on port %s, %s", config.DispenserPort, status)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test lock-server connection
|
// Test lock-server connection
|
||||||
@ -101,7 +97,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create App and wire routes
|
// Create App and wire routes
|
||||||
app := handlers.NewApp(dispHandle, config.LockType, config.EncoderAddress, database, &config)
|
app := handlers.NewApp(dispHandle, config.LockType, config.EncoderAddress, cardWellStatus, database, &config)
|
||||||
|
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
app.RegisterRoutes(mux)
|
app.RegisterRoutes(mux)
|
||||||
|
|||||||
@ -9,6 +9,8 @@ divided `/starttransaction` endpoint into two separate endpoints:
|
|||||||
added preauth releaser functionality to release preauthorization payments after a defined time period
|
added preauth releaser functionality to release preauthorization payments after a defined time period
|
||||||
added db connection check before adding a transaction to the database
|
added db connection check before adding a transaction to the database
|
||||||
and reconnection functionality if the connection to the database is lost
|
and reconnection functionality if the connection to the database is lost
|
||||||
|
added `/dispenserstatus` endpoint
|
||||||
|
key card always stays at encoder position
|
||||||
|
|
||||||
#### 1.0.30 - 09 January 2026
|
#### 1.0.30 - 09 January 2026
|
||||||
improved logging for preauth releaser
|
improved logging for preauth releaser
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user