hacked ergebnis
This commit is contained in:
parent
3cad0e70d9
commit
487967ecf6
8 changed files with 118 additions and 31 deletions
|
@ -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
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
11
speedsign/http_test.go
Normal file
11
speedsign/http_test.go
Normal file
|
@ -0,0 +1,11 @@
|
|||
package speedsign_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.ctdo.de/henne/blitzer-v2/speedsign"
|
||||
)
|
||||
|
||||
func TestHttp(t *testing.T) {
|
||||
speedsign.Show(5)
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<td>{{ .Speed }}km/h</td>
|
||||
<td>
|
||||
{{ if ne .ImagePath "" }}
|
||||
<img src="{{ .ImagePath }}" alt="Beweisfoto" />
|
||||
<img class="rotate-180" src="{{ .ImagePath }}" alt="Beweisfoto" />
|
||||
{{ end }}
|
||||
</td>
|
||||
<td>
|
||||
|
|
|
@ -6,6 +6,13 @@
|
|||
<title>WHY 2025 Traffic Police</title>
|
||||
<link rel="stylesheet" href="/assets/css/pico.min.css" />
|
||||
<link rel="stylesheet" href="/assets/css/pico.colors.min.css" />
|
||||
<style type="text/css">
|
||||
.rotate-180 {
|
||||
-webkit-transform: rotate(180deg);
|
||||
-ms-transform: rotate(180deg);
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="container">
|
||||
|
@ -24,7 +31,7 @@
|
|||
</div>
|
||||
<div style="text-align:center">
|
||||
{{ if ne .Ticket.ImagePath "" }}
|
||||
<div style="margin: var(--pico-block-spacing-vertical) 0;"><img src="{{ .Ticket.ImagePath }}" alt="Proof"></div>
|
||||
<div style="margin: var(--pico-block-spacing-vertical) 0;"><img class="rotate-180" src="{{ .Ticket.ImagePath }}" alt="Proof"></div>
|
||||
{{ end }}
|
||||
{{ if ne .Ticket.KIImagePath "" }}
|
||||
<div style="margin: var(--pico-block-spacing-vertical) 0;"><img src="{{ .Ticket.KIImagePath }}" alt="Proof"></div>
|
||||
|
|
Loading…
Add table
Reference in a new issue