protocol is implemented

This commit is contained in:
crusader 2019-08-09 14:06:04 +09:00
parent 41cd8e9bb8
commit 51819428c3
5 changed files with 182 additions and 21 deletions

6
go.mod
View File

@ -1,3 +1,9 @@
module git.loafle.net/outsourcing/kiast-drone-collector module git.loafle.net/outsourcing/kiast-drone-collector
go 1.12 go 1.12
require (
github.com/influxdata/influxdb1-client v0.0.0-20190402204710-8ff2fc3824fc
github.com/stretchr/testify v1.3.0 // indirect
github.com/vjeantet/jodaTime v0.0.0-20170816150230-be924ce213fb
)

11
go.sum Normal file
View File

@ -0,0 +1,11 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/influxdata/influxdb1-client v0.0.0-20190402204710-8ff2fc3824fc h1:KpMgaYJRieDkHZJWY3LMafvtqS/U8xX6+lUN+OKpl/Y=
github.com/influxdata/influxdb1-client v0.0.0-20190402204710-8ff2fc3824fc/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/vjeantet/jodaTime v0.0.0-20170816150230-be924ce213fb h1:9Cx/q/wd5p+BjCDBjY+rauPbwoS+chrnQ9MKMUtv/hs=
github.com/vjeantet/jodaTime v0.0.0-20170816150230-be924ce213fb/go.mod h1:XK4iy/zfkdRGe+lWQYwmebWh0IIMIe6+wi3APUAiCJ0=

View File

@ -1,13 +1,115 @@
package drone package drone
type DroneGPS struct { import (
Date string "fmt"
Time string "strconv"
Latitude string "strings"
Longitude string
Altitude string "github.com/vjeantet/jodaTime"
Speed string )
Direction string
Fixed string type droneGPS struct {
Time int64
// 위도
Latitude float64
// 경도
Longitude float64
// 고도
Altitude float32
// 속도
Speed int32
// 방향
Direction int16
// A or V
Fixed string
// LTE 통신 상태
LTEStatus string LTEStatus string
// EMM 오류 정보
EMMError string
// ESM 오류 정보
ESMError string
// 신호세기
SignalStrength int32
// 위성 갯수
SatelliteCount int32
// 위성 신호세기 ex) 17-44,19-43,6-42,28-41
SatelliteSignalStrength string
}
// fixed
// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
// $$GPS, 년월일, 시분초, 위도, 경도, 고도, 속도, 방향, A, LTE 통신 상태, EMM 오류 정보, ESM 오류 정보, 신호세기, 위성 갯수, 위성 ID-신호세기, 위성 ID-신호세기, 위성 ID-신호세기, 위성 ID-신호세기
// $$GPS,20190718,050519,37396586,126968913,798,0,0,A,2,255,255,-53,13,17-44,19-43,6-42,28-41
// unfixed
// $$GPS,,,,,,,, V, LTE 통신 상태, EMM 오류 정보, ESM 오류 정보, 신호세기, 위성 갯수, 위성 ID-신호세기, 위성 ID-신호세기, 위성 ID-신호세기, 위성 ID-신호세기
// $$GPS,,,,,,,,V,2,255,255,-53,4,17-44,19-42,6-40,28-40
func parseProtocol(buf []byte) (*droneGPS, error) {
data := string(buf)
items := strings.Split(data, ",")
gps := &droneGPS{
// A or V
Fixed: items[8],
// LTE 통신 상태
LTEStatus: items[9],
// EMM 오류 정보
EMMError: items[10],
// ESM 오류 정보
ESMError: items[11],
}
gps.SatelliteSignalStrength = strings.Join(items[12:], ",")
signalStrength, err := strconv.ParseInt(items[12], 10, 32)
if nil != err {
return nil, err
}
gps.SignalStrength = int32(signalStrength)
satelliteCount, err := strconv.ParseInt(items[13], 10, 32)
if nil != err {
return nil, err
}
gps.SatelliteCount = int32(satelliteCount)
if "A" == gps.Fixed {
dateTime, err := jodaTime.Parse("YYYYMMDDHHmmss", fmt.Sprintf("%s%s", items[1], items[2]))
if nil != err {
return nil, err
}
gps.Time = dateTime.Unix()
latitude, err := strconv.ParseFloat(fmt.Sprintf("%s.%s", items[3][0:len(items[3])-6], items[3][len(items[3])-6:]), 64)
if nil != err {
return nil, err
}
gps.Latitude = latitude
longitude, err := strconv.ParseFloat(fmt.Sprintf("%s.%s", items[4][0:len(items[4])-6], items[4][len(items[4])-6:]), 64)
if nil != err {
return nil, err
}
gps.Longitude = longitude
altitude, err := strconv.ParseFloat(fmt.Sprintf("%s.%s", items[5][0:len(items[5])-1], items[5][len(items[5])-1:]), 32)
if nil != err {
return nil, err
}
gps.Altitude = float32(altitude)
speed, err := strconv.ParseInt(items[6], 10, 32)
if nil != err {
return nil, err
}
gps.Speed = int32(speed)
direction, err := strconv.ParseInt(items[7], 10, 16)
if nil != err {
return nil, err
}
gps.Direction = int16(direction)
}
return gps, nil
} }

View File

@ -1,15 +1,20 @@
package drone package drone
import ( import (
"bufio"
"log" "log"
"net" "net"
"os"
"sync" "sync"
"time" "time"
influxdb "github.com/influxdata/influxdb1-client/v2"
) )
// An uninteresting service. // An uninteresting service.
type Service struct { type Service struct {
ch chan bool ch chan bool
influx influxdb.Client
waitGroup *sync.WaitGroup waitGroup *sync.WaitGroup
} }
@ -27,6 +32,18 @@ func NewService() *Service {
// if anything is received on the service's channel. // if anything is received on the service's channel.
func (s *Service) Serve(listener *net.TCPListener) { func (s *Service) Serve(listener *net.TCPListener) {
defer s.waitGroup.Done() defer s.waitGroup.Done()
influx, err := influxdb.NewHTTPClient(influxdb.HTTPConfig{
Addr: "http://localhost:8086",
Username: os.Getenv("INFLUX_USER"),
Password: os.Getenv("INFLUX_PWD"),
})
if err != nil {
panic(err) // error handling here; normally we wouldn't use fmt but it works for the example
}
s.influx = influx
for { for {
select { select {
case <-s.ch: case <-s.ch:
@ -52,6 +69,7 @@ func (s *Service) Serve(listener *net.TCPListener) {
// Stop the service by closing the service's channel. Block until the service // Stop the service by closing the service's channel. Block until the service
// is really stopped. // is really stopped.
func (s *Service) Stop() { func (s *Service) Stop() {
s.influx.Close()
close(s.ch) close(s.ch)
s.waitGroup.Wait() s.waitGroup.Wait()
} }
@ -70,8 +88,11 @@ func (s *Service) serve(conn *net.TCPConn) {
default: default:
} }
conn.SetDeadline(time.Now().Add(1e9)) conn.SetDeadline(time.Now().Add(1e9))
buf := make([]byte, 4096) //buf := make([]byte, 4096)
if _, err := conn.Read(buf); nil != err {
reader := bufio.NewReader(conn)
buf, err := reader.ReadBytes('#')
if nil != err {
if opErr, ok := err.(*net.OpError); ok && opErr.Timeout() { if opErr, ok := err.(*net.OpError); ok && opErr.Timeout() {
continue continue
} }
@ -79,17 +100,38 @@ func (s *Service) serve(conn *net.TCPConn) {
return return
} }
// fixed p, err := parseProtocol(buf)
// $$GPS, 년월일, 시분초, 위도, 경도, 고도, 속도, 방향, A, LTE 통신 상태, EMM 오류 정보, ESM 오류 정보, 신호세기, 위성 갯수, 위성 ID-신호세기, 위성 ID-신호세기, 위성 ID-신호세기, 위성 ID-신호세기 if err != nil {
// $$GPS,20190718,050519,37396586,126968913,798,0,0,A,2,255,255,-53,13,17-44,19-43,6-42,28-41 log.Println(err)
}
// unfixed bp, _ := influxdb.NewBatchPoints(influxdb.BatchPointsConfig{
// $$GPS,,,,,,,, V, LTE 통신 상태, EMM 오류 정보, ESM 오류 정보, 신호세기, 위성 갯수, 위성 ID-신호세기, 위성 ID-신호세기, 위성 ID-신호세기, 위성 ID-신호세기 Database: "kiast",
// $$GPS,,,,,,,,V,2,255,255,-53,4,17-44,19-42,6-40,28-40 Precision: "s",
})
// Create a point and add to batch
tags := map[string]string{}
fields := map[string]interface{}{
"time": p.Time,
"latitude": p.Latitude,
"longitude": p.Longitude,
"altitude": p.Altitude,
"speed": p.Speed,
"direction": p.Direction,
"fixed": p.Fixed,
"lte_status": p.LTEStatus,
"emm_error": p.EMMError,
"esm_error": p.ESMError,
"signal_strength": p.SignalStrength,
"satellite_count": p.SatelliteCount,
"satellite_signal_strength": p.SatelliteSignalStrength,
}
pt, err := influxdb.NewPoint("drone_gps", tags, fields, time.Now())
if err != nil {
log.Println(err)
}
bp.AddPoint(pt)
// if _, err := conn.Write(buf); nil != err { s.influx.Write(bp)
// log.Println(err)
// return
// }
} }
} }