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.
171 lines
4.4 KiB
171 lines
4.4 KiB
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 {
|
|
Ent dxcc.Entity
|
|
Call string
|
|
Grid string
|
|
Band string
|
|
Mode string
|
|
Signal int
|
|
GeoHash string
|
|
Timestamp time.Time
|
|
Rx int
|
|
}
|
|
|
|
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"
|
|
}
|
|
return band
|
|
}
|
|
|
|
func ScanLine(line string) (Result, bool) {
|
|
var err error
|
|
var tmp string
|
|
element := new(Row)
|
|
result := new(Result)
|
|
found := 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)
|
|
continue
|
|
}
|
|
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 result.Call == "73" || result.Call == "<...>" || result.Call == "QSO" || result.Call == "QSY" {
|
|
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.Ent, found = dxcc.Lookup(result.Call)
|
|
// FIXME result.Grid = qrz.lookup(result.Call) ;) or track in ALL.txt ^^
|
|
if(found){
|
|
result.Signal = element.Strength
|
|
result.Mode = element.Mode
|
|
result.Band = GetBand(element.Bandf)
|
|
// 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,
|
|
"time":string(result.Timestamp.String()),
|
|
"mode":result.Mode,
|
|
"geohash":result.GeoHash,
|
|
"rx":result.Rx,
|
|
}).Trace("successfully parsed line")
|
|
return *result, true
|
|
} else {
|
|
log.WithFields(log.Fields{"line":line,"callsign":element.Second}).Trace("cant parse callsign")
|
|
}
|
|
} else {
|
|
// log.WithFields(log.Fields{"line":line}).Info("found old formated line..")
|
|
}
|
|
return *result, false
|
|
}
|
|
|
|
|
|
|