Skip to content

Commit

Permalink
add dooropener, sanitize
Browse files Browse the repository at this point in the history
  • Loading branch information
stonefiled committed Sep 28, 2024
1 parent 75859c3 commit 07bf720
Show file tree
Hide file tree
Showing 5 changed files with 199 additions and 72 deletions.
3 changes: 2 additions & 1 deletion build.bat
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ REM Optional: Add Go binary to the path if not already set
REM set PATH=C:\Go\bin;%PATH%

REM Compile the Go application
go build -o bin/wgreader_rpi .\cmd\wgreader\main.go
go build -o bin/wgreader_rpi .\cmd\wgreader\main.go
go build -o bin/dooropener_rpi .\cmd\dooropener\main.go
64 changes: 64 additions & 0 deletions cmd/dooropener/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package main

import (
"context"
"flag"
"fmt"
"log"
"log/slog"
"os"
"os/signal"
"syscall"

"github.com/themulle/chronokeyaccess/pkg/dooropener"
)

func main() {
relayPin := flag.Int("relaypin", 18, "relay pin number")
closedState := flag.Bool("closedstate", true, "default closed state")
logLevelFlag := flag.String("loglevel", "info", "Log level (debug, info, error)")
open := flag.Bool("open", true, "initialize opener to default state")
// Parse command-line flags
flag.Parse()

setupLogger(*logLevelFlag)

slog.Info("starting door opener")
opener := dooropener.NewDoorOpener(*relayPin, *closedState)
opener.InitAsOutput()
if *open {
opener.OpenDoor()
}

slog.Info("done")
}

func startShutdownListener(cancel context.CancelFunc) {
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
go func() {
<-c
log.Println("shutdown")
cancel()
}()
}

func setupLogger(logLevelFlag string) error {
logLevel := slog.LevelInfo
switch logLevelFlag {
case "debug":
logLevel = slog.LevelDebug
case "info":
logLevel = slog.LevelInfo
case "error":
logLevel = slog.LevelError
default:
return fmt.Errorf("Invalid log level: %s. Use 'debug', 'info', or 'error'", logLevelFlag)
}

slog.SetDefault(slog.New(slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{
Level: logLevel,
})))

return nil
}
55 changes: 3 additions & 52 deletions cmd/web/coderequest.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ package main

import (
"fmt"
"log"
"strings"
"time"

"github.com/themulle/chronokeyaccess/internal/store"
"github.com/themulle/chronokeyaccess/pkg/accesslog"
Expand Down Expand Up @@ -32,16 +30,10 @@ func getCodes(cr CodeRequest) (codemanager.EntranceCodes, error) {
return retval, err
}
for _, dayTimeString := range cr.DayTime {
var dayTime time.Time
var err error
if dayTime, err = time.Parse("2006-01-02T15:04:05-0700", dayTimeString); err == nil {
} else if dayTime, err = time.Parse("2006-01-02", dayTimeString); err == nil {
} else if dayTime, err = time.Parse("2006-01-02T15:04", dayTimeString); err == nil {
} else if dayTime, err = time.Parse("01.02.2006", dayTimeString); err == nil {
} else {
dayTime, err := dateparser.Parse(dayTimeString)
if err != nil {
return retval, fmt.Errorf("invalid date format: %s", dayTimeString)
}
log.Printf("code request for: %s", dayTime.String())
dayCodes := cm.GetEntranceCodes(dayTime)
if cr.ExactMatch {
tmp := codemanager.EntranceCodes{}
Expand Down Expand Up @@ -78,49 +70,8 @@ func getCodes(cr CodeRequest) (codemanager.EntranceCodes, error) {
return retval.Uniq(), nil
}

func getSeriesPin(cr CodeRequest) (codemanager.EntranceCodes, error) {
retval := codemanager.EntranceCodes{}
var cm codemanager.CodeManager

if codeManagerStore, err := store.LoadConfiguration("config.json", "personalcodes.csv", true); err != nil {
return retval, err
} else if cm, err = codemanager.InitFromStore(codeManagerStore); err != nil {
return retval, err
} else {

/*for _,s := range codeManagerStore.Slots {
if ccs, err:=s.(*codemanager.CronCodeSlot); err==nil {
}
}*/
}

for _, dayTimeString := range cr.DayTime {
var dayTime time.Time
var err error
if dayTime, err = dateparser.Parse(dayTimeString); err != nil {
return retval, fmt.Errorf("invalid date format: %s", dayTimeString)
}
log.Printf("code request for: %s", dayTime.String())
dayCodes := cm.GetEntranceCodes(dayTime)
if cr.ExactMatch {
tmp := codemanager.EntranceCodes{}
for _, d := range dayCodes {
if d.Start == dayTime {
tmp = append(tmp, d)
}
}
dayCodes = tmp
}
retval = append(retval, dayCodes...)
}

retval.Sort()
return retval.Uniq(), nil
}

func getAccessLogs() (accesslog.AccessLogs, error) {
retval := accesslog.AccessLogs{}
var retval accesslog.AccessLogs
var err error

if retval, err = store.LoadAccessLogCSV("accesslog.csv"); err != nil {
Expand Down
85 changes: 66 additions & 19 deletions cmd/wgreader/main.go
Original file line number Diff line number Diff line change
@@ -1,46 +1,93 @@
package main

import (
"context"
"flag"
"fmt"
"log"
"log/slog"
"os"
"os/signal"
"syscall"
"time"

"github.com/themulle/chronokeyaccess/pkg/wiegand"
"github.com/themulle/chronokeyaccess/pkg/wiegand/wieganddecoder"
)

func main() {
reader := wiegand.NewWiegandReader(14, 15)
decoder := wieganddecoder.NewCommonDecoder()
func setupLogger(logLevelFlag string) error {
logLevel := slog.LevelInfo
switch logLevelFlag {
case "debug":
logLevel = slog.LevelDebug
case "info":
logLevel = slog.LevelInfo
case "error":
logLevel = slog.LevelError
default:
return fmt.Errorf("Invalid log level: %s. Use 'debug', 'info', or 'error'", logLevelFlag)
}

slog.SetDefault(slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
Level: slog.LevelInfo,
slog.SetDefault(slog.New(slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{
Level: logLevel,
})))

return nil
}

func main() {
data0pin := flag.Int("data0pin", 14, "data0 pin number")
data1pin := flag.Int("data1pin", 15, "data1 pin number")
logLevelFlag := flag.String("loglevel", "info", "Log level (debug, info, error)")
// Parse command-line flags
flag.Parse()

setupLogger(*logLevelFlag)

reader := wiegand.NewWiegandReader(*data0pin, *data1pin)
decoder := wieganddecoder.NewCommonDecoder()

slog.Info("starting wiegand reader")
if err := reader.Start(); err != nil {
slog.Error("Error initializing Wiegand reader", "error", err)
return
}

for {
time.Sleep(time.Millisecond * 100)
bits, start, stop := reader.GetCache()
if decoder.CheckInputComplete(bits, start, stop) {
reader.ResetCache()
number, err := decoder.Decode(bits)
slog.Info("got input", "number", number,
"cache", wieganddecoder.BitsToString(bits),
"error", err,
"start", start,
"stop", stop)
}
ctx, cancel := context.WithCancel(context.Background())
startShutdownListener(cancel)

}
go func() {
for {
time.Sleep(time.Millisecond * 100)
bits, start, stop := reader.GetCache()
if decoder.CheckInputComplete(bits, start, stop) {
reader.ResetCache()
number, err := decoder.Decode(bits)
slog.Info("got input", "number", number,
"cache", wieganddecoder.BitsToString(bits),
"error", err,
"start", start,
"stop", stop)

fmt.Printf("%d %s %s %s %t\n", number, start.Format(time.RFC3339), stop.Format(time.RFC3339), wieganddecoder.BitsToString(bits), err == nil)
}

}
}()

<-ctx.Done()
reader.Close()

fmt.Println("quitting")
slog.Info("done")

}

func startShutdownListener(cancel context.CancelFunc) {
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
go func() {
<-c
log.Println("shutdown")
cancel()
}()
}
64 changes: 64 additions & 0 deletions pkg/dooropener/dooropener.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package dooropener

import (
"time"

"github.com/warthog618/go-gpiocdev"
)

type DoorOpener struct {
RelayPin int
Chip string
ClosedState int
OpenState int
Runtime time.Duration
}

// NewWiegandReader erstellt einen neuen WiegandReader
func NewDoorOpener(relayPin int, closedState bool) *DoorOpener {
opener := &DoorOpener{
RelayPin: relayPin,
Chip: "gpiochip0",
Runtime: time.Second * 3,
}
if closedState {
opener.ClosedState = 1
opener.OpenState = 0
} else {
opener.ClosedState = 0
opener.OpenState = 1
}

return opener
}

func (d *DoorOpener) InitAsOutput() error {
line, err := gpiocdev.RequestLine(d.Chip, d.RelayPin, gpiocdev.AsOutput(d.ClosedState))
if err != nil {
return err
}
return line.Close()
}

func (d *DoorOpener) OpenDoor() error {
line, err := gpiocdev.RequestLine(d.Chip, d.RelayPin, gpiocdev.AsOutput(d.ClosedState))
if err != nil {
return err
}
defer line.Close()
defer line.SetValue(d.ClosedState)

start := time.Now()
for time.Since(start) < d.Runtime {
if err = line.SetValue(d.OpenState); err != nil {
return err
}
time.Sleep(time.Millisecond * 400)
if err = line.SetValue(d.ClosedState); err != nil {
return err
}
time.Sleep(time.Millisecond * 100)
}

return nil
}

0 comments on commit 07bf720

Please sign in to comment.