linky2influx/main.go

138 lines
2.4 KiB
Go
Raw Normal View History

2021-02-03 22:26:03 +00:00
package main
import (
2021-02-03 23:50:39 +00:00
"bytes"
2021-02-03 22:26:03 +00:00
"flag"
2021-02-03 23:50:39 +00:00
"io"
2021-02-03 22:26:03 +00:00
"log"
"os"
"os/signal"
"syscall"
"time"
2021-02-03 23:50:39 +00:00
"unicode"
2021-02-03 22:26:03 +00:00
"github.com/tarm/serial"
)
2021-02-03 23:50:39 +00:00
func readSerial(s *serial.Port, c chan []byte) {
var unread bytes.Buffer
buf := make([]byte, 128)
2021-02-03 22:26:03 +00:00
2021-02-03 23:50:39 +00:00
for {
n, err := s.Read(buf)
if err != nil {
log.Fatal(err)
}
unread.Write(buf[:n])
for {
line, err := unread.ReadBytes('\n')
if err == io.EOF {
if _, err = unread.Write(line); err != nil {
log.Println(err)
}
break
} else if err != nil {
log.Println(err)
break
}
c <- bytes.TrimRightFunc(line, func(r rune) bool {
return unicode.IsSpace(r) || unicode.IsControl(r)
})
}
}
}
func computeChecksum(area []byte) (checksum byte) {
for _, c := range area {
checksum += c
}
checksum = (checksum & 0x3F) + 0x20
return
}
2021-02-03 23:51:04 +00:00
func getHorodate(fields *[][]byte) (horodate time.Time, err error) {
if len(*fields) == 4 && len((*fields)[1]) == 13 {
horodate, err = time.Parse("060102150405", string((*fields)[1][1:]))
if err != nil {
horodate = time.Now().Truncate(time.Second).UTC()
}
// Handle "saison"
if (*fields)[1][0] == 'E' || (*fields)[1][0] == 'e' {
horodate = horodate.Add(2 * time.Hour)
} else {
horodate = horodate.Add(1 * time.Hour)
}
// Mark field as treated
*fields = append((*fields)[:1], (*fields)[2:]...)
} else {
horodate = time.Now().Truncate(time.Second).UTC()
}
return
}
2021-02-03 23:50:39 +00:00
func treatLines(c chan []byte) {
for {
line := <-c
if len(line) <= 1 {
continue
}
if computeChecksum(line[:len(line)-1]) != line[len(line)-1] {
log.Printf("BAD checksum on %s: calculated: %c\n", line, computeChecksum(line[:len(line)-1]))
continue
}
fields := bytes.Fields(line)
2021-02-03 23:51:04 +00:00
horodate, err := getHorodate(&fields)
if err != nil {
log.Println(err)
continue
}
log.Println(horodate, fields)
2021-02-03 23:50:39 +00:00
}
2021-02-03 22:26:03 +00:00
}
func main() {
var interval = flag.Duration("interval", 5*time.Second, "Minimum time between releve")
flag.Parse()
2021-02-03 23:50:39 +00:00
log.Println(interval)
2021-02-03 22:26:03 +00:00
if len(flag.Args()) < 1 {
log.Println("missing required argument: serial device (eg. /dev/ttyUSB0)")
return
}
config := &serial.Config{
Name: flag.Args()[0],
Baud: 9600,
Size: 7,
Parity: serial.ParityNone,
StopBits: 1,
}
s, err := serial.OpenPort(config)
if err != nil {
log.Fatal(err)
}
2021-02-03 23:50:39 +00:00
c := make(chan []byte)
go readSerial(s, c)
go treatLines(c)
2021-02-03 22:26:03 +00:00
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt, syscall.SIGTERM)
<-interrupt
}