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 (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os/exec"
|
"log"
|
||||||
|
"os"
|
||||||
|
|
||||||
"github.com/disintegration/imaging"
|
"github.com/jonmol/gphoto2"
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var gphotoPath string
|
var camera *gphoto2.Camera
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
var err error
|
var err error
|
||||||
gphotoPath, err = exec.LookPath("gphoto2")
|
camera, err = gphoto2.NewCamera("")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Panic("gphoto2 not found")
|
log.Printf("could not connect to camera")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TakePhoto(id string) error {
|
func TakePhoto(id string) error {
|
||||||
filename := fmt.Sprintf("images/original/ticket-%s.jpg", id)
|
filename := fmt.Sprintf("images/original/ticket-%s.jpg", id)
|
||||||
cmd := exec.Command(gphotoPath, "--capture-image-and-download", "--filename", filename)
|
file, err := os.Create(filename)
|
||||||
err := cmd.Run()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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)
|
img, err := imaging.Open("./" + filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -36,3 +73,4 @@ func TakePhoto(id string) error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
|
@ -3,6 +3,7 @@ package radar
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"time"
|
||||||
|
|
||||||
"git.ctdo.de/henne/blitzer-v2/camera"
|
"git.ctdo.de/henne/blitzer-v2/camera"
|
||||||
"git.ctdo.de/henne/blitzer-v2/config"
|
"git.ctdo.de/henne/blitzer-v2/config"
|
||||||
|
@ -14,6 +15,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var r *radar_lib.Radar
|
var r *radar_lib.Radar
|
||||||
|
var speedFree = true
|
||||||
|
var eventFree = true
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
r = radar_lib.New(config.C.Radar.Port, config.C.Radar.Baud)
|
r = radar_lib.New(config.C.Radar.Port, config.C.Radar.Baud)
|
||||||
|
@ -22,10 +25,19 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func onSpeedEvent(speed int) {
|
func onSpeedEvent(speed int) {
|
||||||
|
if !speedFree {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
speedFree = false
|
||||||
speedsign.Show(speed)
|
speedsign.Show(speed)
|
||||||
|
speedFree = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func onEvent(speed int) {
|
func onEvent(speed int) {
|
||||||
|
if !eventFree {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
eventFree = false
|
||||||
speedingTicket := db.SpeedingTicket{
|
speedingTicket := db.SpeedingTicket{
|
||||||
Speed: speed,
|
Speed: speed,
|
||||||
AllowedSpeed: db.GetConfig().TriggerSpeed,
|
AllowedSpeed: db.GetConfig().TriggerSpeed,
|
||||||
|
@ -41,6 +53,7 @@ func onEvent(speed int) {
|
||||||
logrus.Error(err)
|
logrus.Error(err)
|
||||||
}
|
}
|
||||||
printer.PrintTicket(speedingTicket)
|
printer.PrintTicket(speedingTicket)
|
||||||
|
eventFree = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetConfig(height int, angle int, waveform bool) {
|
func SetConfig(height int, angle int, waveform bool) {
|
||||||
|
@ -62,6 +75,7 @@ func SetSpeedConfig(speed int, minDistance, maxDistance, minSpeed, maxSpeed, tri
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("%v", err)
|
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)
|
err = r.SetEventConfig(1, triggerDistance*2, triggerDistance*2+20, speed, 240, int(radar_lib.DirectionIncoming), radar_lib.TargetStateExit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("%v", err)
|
log.Printf("%v", err)
|
||||||
|
@ -69,7 +83,7 @@ func SetSpeedConfig(speed int, minDistance, maxDistance, minSpeed, maxSpeed, tri
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetCommunicationConfig(speedOutput, targetOutput, triggerOutput int) {
|
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 {
|
if err != nil {
|
||||||
log.Printf("%v", err)
|
log.Printf("%v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,6 +83,7 @@ func New(port string, baudrate int) *Radar {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
//s.SetReadTimeout(1000 * time.Millisecond)
|
||||||
r := &Radar{
|
r := &Radar{
|
||||||
port: s,
|
port: s,
|
||||||
baudrate: baudrate,
|
baudrate: baudrate,
|
||||||
|
@ -113,10 +114,6 @@ func (r *Radar) write(data []byte) error {
|
||||||
return r.port.Drain()
|
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.
|
// 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
|
// 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 {
|
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.
|
// 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 {
|
func (r *Radar) SetEventConfig(eventNumber, minDistance, maxDistance, minSpeed, maxSpeed, direction, state int) error {
|
||||||
r.lockConfig()
|
|
||||||
|
|
||||||
if eventNumber < 1 || eventNumber > 1 {
|
if eventNumber < 1 || eventNumber > 1 {
|
||||||
return errors.New("eventNumber needs to be between 1 and 8")
|
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 {
|
func (r *Radar) SetTargetSpeedConfig(direction Direction, minDistance, maxDistance, minSpeed, maxSpeed, speeding int, outputLogic OutputLogic) error {
|
||||||
r.lockConfig()
|
|
||||||
data := startSequence
|
data := startSequence
|
||||||
data = append(data, 0x03, byte(direction), byte(minDistance), byte(maxDistance), byte(minSpeed), byte(maxSpeed), byte(speeding), byte(outputLogic))
|
data = append(data, 0x03, byte(direction), byte(minDistance), byte(maxDistance), byte(minSpeed), byte(maxSpeed), byte(speeding), byte(outputLogic))
|
||||||
data = append(data, endSequence...)
|
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 {
|
func (r *Radar) SetCommunicationConfig(port Port, baud Baud, speedOutput, targetOutput, triggerOutput OutputType, communicationPeriod int) error {
|
||||||
r.lockConfig()
|
|
||||||
data := startSequence
|
data := startSequence
|
||||||
speed := byte(speedOutput)
|
speed := byte(speedOutput)
|
||||||
target := byte(targetOutput)
|
target := byte(targetOutput)
|
||||||
|
|
|
@ -2,8 +2,12 @@ package radar_lib
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var lastSpeed int = 0
|
||||||
|
var lastFlashTime time.Time = time.Now()
|
||||||
|
|
||||||
func (r *Radar) listenSerial() {
|
func (r *Radar) listenSerial() {
|
||||||
rcvBuf := make([]byte, 100)
|
rcvBuf := make([]byte, 100)
|
||||||
lastIndex := 0
|
lastIndex := 0
|
||||||
|
@ -15,13 +19,13 @@ func (r *Radar) listenSerial() {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
log.Println("\nEOF")
|
log.Println("Radar: EOF")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
for i := range n {
|
for i := range n {
|
||||||
rcvBuf[lastIndex] = buf[i]
|
rcvBuf[lastIndex] = buf[i]
|
||||||
if i > 1 && buf[i-1] == 0x0D && buf[i] == 0x0A {
|
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
|
lastIndex = 0
|
||||||
} else {
|
} else {
|
||||||
lastIndex++
|
lastIndex++
|
||||||
|
@ -35,6 +39,11 @@ func (r *Radar) decodeInput(buf []byte) {
|
||||||
// trigger message
|
// trigger message
|
||||||
if len(buf) > 2 && buf[0] == 0x56 && buf[1] == 0x50 {
|
if len(buf) > 2 && buf[0] == 0x56 && buf[1] == 0x50 {
|
||||||
log.Printf("Radar Trigger Message Event %d", buf[2])
|
log.Printf("Radar Trigger Message Event %d", buf[2])
|
||||||
|
//if int(buf[2]) == 1 {
|
||||||
|
//if r.handler != nil {
|
||||||
|
//go r.handler(lastSpeed)
|
||||||
|
//}
|
||||||
|
//}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// config response
|
// config response
|
||||||
|
@ -44,7 +53,6 @@ func (r *Radar) decodeInput(buf []byte) {
|
||||||
s = "SUCCESS"
|
s = "SUCCESS"
|
||||||
}
|
}
|
||||||
log.Printf("%s response: Code: %d", s, buf[2])
|
log.Printf("%s response: Code: %d", s, buf[2])
|
||||||
r.configLock.Unlock()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// speed information
|
// speed information
|
||||||
|
@ -62,23 +70,31 @@ func (r *Radar) decodeInput(buf []byte) {
|
||||||
valid = "yes"
|
valid = "yes"
|
||||||
}
|
}
|
||||||
log.Printf("Speed: %dkm/h (%s, Over: %s, Valid: %s)", buf[3], dir, overspeed, valid)
|
log.Printf("Speed: %dkm/h (%s, Over: %s, Valid: %s)", buf[3], dir, overspeed, valid)
|
||||||
if r.speedHandler != nil {
|
if r.speedHandler != nil && valid == "yes" {
|
||||||
r.speedHandler(int(buf[3]))
|
lastSpeed = int(buf[3])
|
||||||
|
go r.speedHandler(int(buf[3]))
|
||||||
} else {
|
} else {
|
||||||
log.Printf("speedhandler = nil")
|
log.Printf("speedhandler = nil")
|
||||||
}
|
}
|
||||||
if r.handler != nil {
|
if r.handler != nil && valid == "yes" && time.Now().After(lastFlashTime.Add(3*time.Second)) {
|
||||||
if overspeed == "yes" && valid == "yes" {
|
lastFlashTime = time.Now()
|
||||||
r.handler(int(buf[3]))
|
go r.handler(lastSpeed)
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.Printf("eventhandler = nil")
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// skip this for now
|
// Target info
|
||||||
if len(buf) > 2 && buf[0] == 0x56 && buf[1] == 0x51 {
|
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
|
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);
|
background-color: var(--pico-color-red-650);
|
||||||
color: var(--pico-color);
|
color: var(--pico-color);
|
||||||
}
|
}
|
||||||
|
.rotate-180 {
|
||||||
|
-webkit-transform: rotate(180deg);
|
||||||
|
-ms-transform: rotate(180deg);
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
<td>{{ .Speed }}km/h</td>
|
<td>{{ .Speed }}km/h</td>
|
||||||
<td>
|
<td>
|
||||||
{{ if ne .ImagePath "" }}
|
{{ if ne .ImagePath "" }}
|
||||||
<img src="{{ .ImagePath }}" alt="Beweisfoto" />
|
<img class="rotate-180" src="{{ .ImagePath }}" alt="Beweisfoto" />
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
|
@ -6,6 +6,13 @@
|
||||||
<title>WHY 2025 Traffic Police</title>
|
<title>WHY 2025 Traffic Police</title>
|
||||||
<link rel="stylesheet" href="/assets/css/pico.min.css" />
|
<link rel="stylesheet" href="/assets/css/pico.min.css" />
|
||||||
<link rel="stylesheet" href="/assets/css/pico.colors.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>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<main class="container">
|
<main class="container">
|
||||||
|
@ -24,7 +31,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div style="text-align:center">
|
<div style="text-align:center">
|
||||||
{{ if ne .Ticket.ImagePath "" }}
|
{{ 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 }}
|
{{ end }}
|
||||||
{{ if ne .Ticket.KIImagePath "" }}
|
{{ if ne .Ticket.KIImagePath "" }}
|
||||||
<div style="margin: var(--pico-block-spacing-vertical) 0;"><img src="{{ .Ticket.KIImagePath }}" alt="Proof"></div>
|
<div style="margin: var(--pico-block-spacing-vertical) 0;"><img src="{{ .Ticket.KIImagePath }}" alt="Proof"></div>
|
||||||
|
|
Loading…
Add table
Reference in a new issue