You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

204 lines
5.2 KiB

4 years ago
package wsjtx
import (
"strconv"
"strings"
"time"
"github.com/mmcloughlin/geohash"
"github.com/tzneal/ham-go/dxcc"
log "github.com/sirupsen/logrus"
)
type Row struct {
Time time.Time
Bandf float64
Direction string
Mode string
Strength int
Offset float64
Freq string
First string
Second string
Third string
Fourth string
}
type Result struct {
Station string
Identifier string
Ent dxcc.Entity
Call string
Grid string
Band string
Mode string
Signal int
GeoHash string
Timestamp time.Time
Rx int
}
var blackList = map[string]bool {
"73": true,
"RR73;": true,
"GL": true,
"TNX": true,
"<...>": true,
"QSO": true,
"QSY": true,
"TIME": true,
"TIMESYNC": true,
}
func GetBand(freq float64) (string){
band := "unknown"
if (freq>1 && freq<2) {
band = "160m"
}
if (freq>3 && freq<4) {
band = "80m"
}
if (freq>5 && freq<6) {
band = "60m"
}
if (freq>7.0 && freq<8.0) {
band = "40m"
}
if (freq>10 && freq<11) {
band = "30m"
}
if (freq>14 && freq<15) {
band = "20m"
}
if (freq>18 && freq<19) {
band = "17m"
}
if (freq>21 && freq<22) {
band = "15m"
}
if (freq>24 && freq<25) {
band = "12m"
}
if (freq>28 && freq<30) {
band = "10m"
}
if (freq>144 && freq<145) {
band = "2m"
}
if (freq>432 && freq<433){
band = "70cm"
}
return band
}
func ScanLine(line string) (Result, bool) {
var err error
var tmp string
element := new(Row)
result := new(Result)
found := false
// dont fail on too short lines
if len(line) < 16 {
log.WithFields(log.Fields{"line":line}).Error("line too short")
return *result, false
}
// parse only lines in new format, because old format misses band
if line[6] == '_' && line[15] != 'T' {
dataSlice := strings.Fields(line)
for i, v := range dataSlice {
switch i {
case 0:
element.Time, err = time.Parse("060102_150405",v)
if err != nil {
log.WithFields(log.Fields{"err":err}).Trace("something went wrong while parsing the timestamp: ",v)
return *result, false
}
case 1:
element.Bandf,_ = strconv.ParseFloat(v,10)
case 2:
element.Direction = v
case 3:
element.Mode = v
case 4:
element.Strength,_ = strconv.Atoi(v)
case 5:
element.Offset,_ = strconv.ParseFloat(v,10)
case 6:
element.Freq = v
case 7:
element.First= v
case 8:
element.Second= v
case 9:
element.Third = v
case 10:
element.Fourth = v
default:
log.WithFields(log.Fields{"line":line}).Trace("can't parse line..")
}
}
// check for 4 element sequence like 'CQ DX DL3SD JO31'
if element.Fourth != "" {
result.Call = element.Third
log.WithFields(log.Fields{"line":line,"callsign":result.Call}).Trace("parsed 4 element callsign")
} else {
result.Call = element.Second
}
// ignore 'TNX QSO GL 73' etc.
if blackList[result.Call] {
log.WithFields(log.Fields{"line":line,"callsign":result.Call}).Trace("skipping callsign")
return *result, false
}
// take care of Calls like <DL3SD> / FIXME does this actually work?
tmp = strings.Replace(result.Call, "<", "", -1)
result.Call = strings.Replace(tmp, ">", "", -1)
result.Band = GetBand(element.Bandf)
result.Ent, found = dxcc.Lookup(result.Call)
// FIXME result.Grid = qrz.lookup(result.Call) ;) or track in ALL.txt ^^
if found && result.Band != "unknown" {
result.Signal = element.Strength
result.Mode = element.Mode
// FIXME
// * get better grid, see above
// * build geohash from better grid with gpsfromgrid(result.Grid)
result.GeoHash = geohash.Encode(result.Ent.Latitude, result.Ent.Longitude)
result.Timestamp = element.Time
if element.Direction[0] == 'R' {
result.Rx = 1
} else {
result.Rx = 0
result.Grid = element.Third
}
log.WithFields(log.Fields{ "call":result.Call,
"signal":result.Signal,
"dxcc":result.Ent.DXCC,
"continent":result.Ent.Continent,
"band":result.Band,
"sendtime":result.Timestamp,
"mode":result.Mode,
"geohash":result.GeoHash,
"rx":result.Rx,
}).Trace("successfully parsed line")
return *result, true
} else {
if !found {
log.WithFields(log.Fields{"line":line,"callsign":element.Second}).Trace("cant parse callsign")
} else if result.Band == "unknown" {
log.WithFields(log.Fields{"line":line,"band":result.Band}).Trace("cant parse band")
} else {
log.WithFields(log.Fields{"line":line}).Error("something really strange happened..")
}
}
} else {
// log.WithFields(log.Fields{"line":line}).Info("found old formated line..")
}
return *result, false
}