From 487967ecf6723b8fb0b542a367c80013aed51a4b Mon Sep 17 00:00:00 2001 From: henne Date: Sun, 10 Aug 2025 16:06:44 +0100 Subject: [PATCH] hacked ergebnis --- camera/main.go | 54 ++++++++++++++++++++++++++++----- radar/main.go | 16 +++++++++- radar_lib/main.go | 10 ++---- radar_lib/reader.go | 42 +++++++++++++++++-------- speedsign/http_test.go | 11 +++++++ webserver/templates/header.html | 5 +++ webserver/templates/index.html | 2 +- webserver/templates/ticket.html | 9 +++++- 8 files changed, 118 insertions(+), 31 deletions(-) create mode 100644 speedsign/http_test.go diff --git a/camera/main.go b/camera/main.go index 2ec7cb4..1d349a7 100644 --- a/camera/main.go +++ b/camera/main.go @@ -2,29 +2,66 @@ package camera import ( "fmt" - "os/exec" + "log" + "os" - "github.com/disintegration/imaging" - "github.com/sirupsen/logrus" + "github.com/jonmol/gphoto2" ) -var gphotoPath string +var camera *gphoto2.Camera func init() { var err error - gphotoPath, err = exec.LookPath("gphoto2") + camera, err = gphoto2.NewCamera("") if err != nil { - logrus.Panic("gphoto2 not found") + log.Printf("could not connect to camera") } } func TakePhoto(id string) error { filename := fmt.Sprintf("images/original/ticket-%s.jpg", id) - cmd := exec.Command(gphotoPath, "--capture-image-and-download", "--filename", filename) - err := cmd.Run() + file, err := os.Create(filename) if err != nil { return err } + err = camera.CaptureDownload(file, false) + if err != nil { + return err + } + return nil +} + +/* Lets try it differently. +var gphotoPath string +var cmd *exec.Cmd +var cmdPipe io.WriteCloser + +func init() { + var err error + gphotoPath, err = exec.LookPath("gphoto2") + if err != nil { + log.Panic("gphoto2 not found") + } + go cameraShell() +} + +func cameraShell() { + var err error + cmd = exec.Command(gphotoPath, "--shell") + cmdPipe, err = cmd.StdinPipe() + if err != nil { + log.Printf("pipe error: %v", err) + } + err = cmd.Run() + if err != nil { + log.Printf("camera shell ended!! with error %v", err) + } + log.Printf("camera shell ended") +} + +func TakePhoto(id string) error { + filename := fmt.Sprintf("images/original/ticket-%s.jpg", id) + fmt.Fprint(cmdPipe, "capture-image-and-download\n") img, err := imaging.Open("./" + filename) if err != nil { return err @@ -36,3 +73,4 @@ func TakePhoto(id string) error { } return nil } +*/ diff --git a/radar/main.go b/radar/main.go index 4974de7..fe3cb54 100644 --- a/radar/main.go +++ b/radar/main.go @@ -3,6 +3,7 @@ package radar import ( "fmt" "log" + "time" "git.ctdo.de/henne/blitzer-v2/camera" "git.ctdo.de/henne/blitzer-v2/config" @@ -14,6 +15,8 @@ import ( ) var r *radar_lib.Radar +var speedFree = true +var eventFree = true func init() { r = radar_lib.New(config.C.Radar.Port, config.C.Radar.Baud) @@ -22,10 +25,19 @@ func init() { } func onSpeedEvent(speed int) { + if !speedFree { + return + } + speedFree = false speedsign.Show(speed) + speedFree = true } func onEvent(speed int) { + if !eventFree { + return + } + eventFree = false speedingTicket := db.SpeedingTicket{ Speed: speed, AllowedSpeed: db.GetConfig().TriggerSpeed, @@ -41,6 +53,7 @@ func onEvent(speed int) { logrus.Error(err) } printer.PrintTicket(speedingTicket) + eventFree = true } func SetConfig(height int, angle int, waveform bool) { @@ -62,6 +75,7 @@ func SetSpeedConfig(speed int, minDistance, maxDistance, minSpeed, maxSpeed, tri if err != nil { log.Printf("%v", err) } + time.Sleep(1 * time.Second) err = r.SetEventConfig(1, triggerDistance*2, triggerDistance*2+20, speed, 240, int(radar_lib.DirectionIncoming), radar_lib.TargetStateExit) if err != nil { log.Printf("%v", err) @@ -69,7 +83,7 @@ func SetSpeedConfig(speed int, minDistance, maxDistance, minSpeed, maxSpeed, tri } func SetCommunicationConfig(speedOutput, targetOutput, triggerOutput int) { - err := r.SetCommunicationConfig(radar_lib.PortRS485, radar_lib.Baud115200, radar_lib.OutputType(speedOutput), radar_lib.OutputType(targetOutput), radar_lib.OutputType(triggerOutput), 200) + err := r.SetCommunicationConfig(radar_lib.PortRS485, radar_lib.Baud115200, radar_lib.OutputType(speedOutput), radar_lib.OutputType(targetOutput), radar_lib.OutputType(triggerOutput), 1000) if err != nil { log.Printf("%v", err) } diff --git a/radar_lib/main.go b/radar_lib/main.go index cdda1ab..5440ec4 100644 --- a/radar_lib/main.go +++ b/radar_lib/main.go @@ -83,6 +83,7 @@ func New(port string, baudrate int) *Radar { if err != nil { log.Fatal(err) } + //s.SetReadTimeout(1000 * time.Millisecond) r := &Radar{ port: s, baudrate: baudrate, @@ -113,10 +114,6 @@ func (r *Radar) write(data []byte) error { return r.port.Drain() } -func (r *Radar) lockConfig() { - r.configLock.Lock() -} - // SetPinTrigger configures a pin to trigger on the radar when an object is detected in a specific range. // controlPin defines the Pin to trigger, distance is the target distance in 0.5 meters, outputLevel is the voltage in 0.1V steps, direction defines weather to trigger on incoming / outgoing or both func (r *Radar) SetPinTrigger(controlPin int, distance int, outputLevel int, direction Direction) error { @@ -136,7 +133,6 @@ func (r *Radar) SetBaseConfig(height int, angle int, waveformConfig int) error { // SetEventConfig can configure up to 8 events that will trigger a response from the radar. distances are in 0.5m, speeds are in km/h. func (r *Radar) SetEventConfig(eventNumber, minDistance, maxDistance, minSpeed, maxSpeed, direction, state int) error { - r.lockConfig() if eventNumber < 1 || eventNumber > 1 { return errors.New("eventNumber needs to be between 1 and 8") @@ -148,7 +144,7 @@ func (r *Radar) SetEventConfig(eventNumber, minDistance, maxDistance, minSpeed, } func (r *Radar) SetTargetSpeedConfig(direction Direction, minDistance, maxDistance, minSpeed, maxSpeed, speeding int, outputLogic OutputLogic) error { - r.lockConfig() + data := startSequence data = append(data, 0x03, byte(direction), byte(minDistance), byte(maxDistance), byte(minSpeed), byte(maxSpeed), byte(speeding), byte(outputLogic)) data = append(data, endSequence...) @@ -156,7 +152,7 @@ func (r *Radar) SetTargetSpeedConfig(direction Direction, minDistance, maxDistan } func (r *Radar) SetCommunicationConfig(port Port, baud Baud, speedOutput, targetOutput, triggerOutput OutputType, communicationPeriod int) error { - r.lockConfig() + data := startSequence speed := byte(speedOutput) target := byte(targetOutput) diff --git a/radar_lib/reader.go b/radar_lib/reader.go index f6e5c28..2167a66 100644 --- a/radar_lib/reader.go +++ b/radar_lib/reader.go @@ -2,8 +2,12 @@ package radar_lib import ( "log" + "time" ) +var lastSpeed int = 0 +var lastFlashTime time.Time = time.Now() + func (r *Radar) listenSerial() { rcvBuf := make([]byte, 100) lastIndex := 0 @@ -15,13 +19,13 @@ func (r *Radar) listenSerial() { break } if n == 0 { - log.Println("\nEOF") + log.Println("Radar: EOF") break } for i := range n { rcvBuf[lastIndex] = buf[i] if i > 1 && buf[i-1] == 0x0D && buf[i] == 0x0A { - r.decodeInput(rcvBuf[0 : lastIndex+1]) + go r.decodeInput(rcvBuf[0 : lastIndex+1]) lastIndex = 0 } else { lastIndex++ @@ -35,6 +39,11 @@ func (r *Radar) decodeInput(buf []byte) { // trigger message if len(buf) > 2 && buf[0] == 0x56 && buf[1] == 0x50 { log.Printf("Radar Trigger Message Event %d", buf[2]) + //if int(buf[2]) == 1 { + //if r.handler != nil { + //go r.handler(lastSpeed) + //} + //} return } // config response @@ -44,7 +53,6 @@ func (r *Radar) decodeInput(buf []byte) { s = "SUCCESS" } log.Printf("%s response: Code: %d", s, buf[2]) - r.configLock.Unlock() return } // speed information @@ -62,23 +70,31 @@ func (r *Radar) decodeInput(buf []byte) { valid = "yes" } log.Printf("Speed: %dkm/h (%s, Over: %s, Valid: %s)", buf[3], dir, overspeed, valid) - if r.speedHandler != nil { - r.speedHandler(int(buf[3])) + if r.speedHandler != nil && valid == "yes" { + lastSpeed = int(buf[3]) + go r.speedHandler(int(buf[3])) } else { log.Printf("speedhandler = nil") } - if r.handler != nil { - if overspeed == "yes" && valid == "yes" { - r.handler(int(buf[3])) - } - } else { - log.Printf("eventhandler = nil") + if r.handler != nil && valid == "yes" && time.Now().After(lastFlashTime.Add(3*time.Second)) { + lastFlashTime = time.Now() + go r.handler(lastSpeed) } return } - // skip this for now + // Target info if len(buf) > 2 && buf[0] == 0x56 && buf[1] == 0x51 { - + i := 0 + if int(buf[2]) > 0 && int(buf[2]) < 11 { + for i = range int(buf[2]) { + curIndex := 4*i + 3 + id := int(buf[curIndex]) + distance := int(buf[curIndex+1]) + speed := int(buf[curIndex+2]) + energy := int(buf[curIndex+3]) + log.Printf("TargetID: %d, Distance: %d, Speed: %d, Energy: %d", id, distance, speed, energy) + } + } return } diff --git a/speedsign/http_test.go b/speedsign/http_test.go new file mode 100644 index 0000000..8cfe61c --- /dev/null +++ b/speedsign/http_test.go @@ -0,0 +1,11 @@ +package speedsign_test + +import ( + "testing" + + "git.ctdo.de/henne/blitzer-v2/speedsign" +) + +func TestHttp(t *testing.T) { + speedsign.Show(5) +} diff --git a/webserver/templates/header.html b/webserver/templates/header.html index 2c03e71..6b3f0e0 100644 --- a/webserver/templates/header.html +++ b/webserver/templates/header.html @@ -25,6 +25,11 @@ background-color: var(--pico-color-red-650); color: var(--pico-color); } + .rotate-180 { + -webkit-transform: rotate(180deg); + -ms-transform: rotate(180deg); + transform: rotate(180deg); + } diff --git a/webserver/templates/index.html b/webserver/templates/index.html index cb7d0b4..ae66f64 100644 --- a/webserver/templates/index.html +++ b/webserver/templates/index.html @@ -17,7 +17,7 @@ {{ .Speed }}km/h {{ if ne .ImagePath "" }} - Beweisfoto + Beweisfoto {{ end }} diff --git a/webserver/templates/ticket.html b/webserver/templates/ticket.html index 0761364..26c9fb5 100644 --- a/webserver/templates/ticket.html +++ b/webserver/templates/ticket.html @@ -6,6 +6,13 @@ WHY 2025 Traffic Police +
@@ -24,7 +31,7 @@
{{ if ne .Ticket.ImagePath "" }} -
Proof
+
Proof
{{ end }} {{ if ne .Ticket.KIImagePath "" }}
Proof