2023-07-19 21:31:00 +01:00
|
|
|
package vstp
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
2023-07-20 11:07:39 +01:00
|
|
|
"fmt"
|
2023-07-19 21:31:00 +01:00
|
|
|
"strconv"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"git.fjla.uk/owlboard/go-types/pkg/database"
|
|
|
|
"git.fjla.uk/owlboard/go-types/pkg/upstreamApi"
|
|
|
|
"git.fjla.uk/owlboard/mq-client/helpers"
|
|
|
|
"git.fjla.uk/owlboard/mq-client/log"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Unmarshals the JSON data and runs it through the formatData() function and returns the data in a DB ready Struct
|
2023-07-20 11:07:39 +01:00
|
|
|
func unmarshalData(jsonData string) database.Service {
|
|
|
|
log.Msg.Debug("Unmarshalling message body")
|
|
|
|
fmt.Println(jsonData)
|
|
|
|
log.Msg.Debug("Converting to byte array")
|
|
|
|
jsonDataBytes := []byte(jsonData)
|
|
|
|
fmt.Println(jsonDataBytes)
|
|
|
|
var schedule upstreamApi.VstpMsg
|
|
|
|
err := json.Unmarshal(jsonDataBytes, &schedule)
|
2023-07-19 21:31:00 +01:00
|
|
|
if err != nil {
|
|
|
|
log.Msg.Error("Unable to unmarshal message body: " + err.Error())
|
|
|
|
//return err
|
|
|
|
}
|
2023-07-20 11:07:39 +01:00
|
|
|
log.Msg.Debug("Unmarshalling Complete")
|
|
|
|
fmt.Println(schedule)
|
|
|
|
saveToFile(schedule, "unmarshalled")
|
|
|
|
return formatData(schedule.CIFMsg)
|
2023-07-19 21:31:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Transforms the upstreamApi.Schedule type into a database.Service type
|
|
|
|
func formatData(dataInput upstreamApi.Schedule) database.Service {
|
|
|
|
service := database.Service{
|
|
|
|
TransactionType: dataInput.TransactionType,
|
|
|
|
StpIndicator: dataInput.CIFSTPIndicator,
|
|
|
|
Operator: dataInput.ScheduleSegment.ATOCCode,
|
|
|
|
TrainUid: dataInput.CIFTrainUID,
|
|
|
|
Headcode: dataInput.ScheduleSegment.SignallingID,
|
|
|
|
PowerType: dataInput.ScheduleSegment.CIFPowerType,
|
|
|
|
PlanSpeed: parseSpeed(dataInput.ScheduleSegment.CIFSpeed),
|
|
|
|
ScheduleStartDate: parseDate(dataInput.ScheduleStartDate, false),
|
|
|
|
ScheduleEndDate: parseDate(dataInput.ScheduleEndDate, true),
|
|
|
|
DaysRun: parseDaysRun(dataInput.ScheduleDaysRun),
|
|
|
|
Stops: parseStops(dataInput.ScheduleSegment.ScheduleLocation),
|
|
|
|
}
|
|
|
|
return service
|
|
|
|
}
|
|
|
|
|
|
|
|
// Uses the map provided in 'helpers' to translate incorrect CIF speeds to their correct equivalent
|
|
|
|
func parseSpeed(CIFSpeed string) int32 {
|
|
|
|
log.Msg.Debug("CIFSpeed Input: " + CIFSpeed)
|
|
|
|
actualSpeed, exists := helpers.SpeedMap[CIFSpeed]
|
|
|
|
if !exists {
|
|
|
|
actualSpeed = CIFSpeed
|
|
|
|
}
|
|
|
|
log.Msg.Debug("Corrected Speed: " + actualSpeed)
|
|
|
|
|
|
|
|
speed, err := strconv.ParseInt(actualSpeed, 10, 32)
|
|
|
|
if err != nil {
|
|
|
|
log.Msg.Warn("Unable to parse speed: " + CIFSpeed + " " + actualSpeed)
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
return int32(speed)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Converts the date string provided from the upstream API into a proper Date type and adds a time
|
|
|
|
func parseDate(dateString string, end bool) time.Time {
|
|
|
|
log.Msg.Debug("Date Input: " + dateString)
|
|
|
|
date, err := time.Parse("2006-01-02", dateString)
|
|
|
|
if err != nil {
|
|
|
|
log.Msg.Error("Unable to parse date: " + dateString)
|
|
|
|
return time.Time{}
|
|
|
|
}
|
|
|
|
log.Msg.Debug("Parsed date: " + date.String())
|
|
|
|
|
|
|
|
var hour, minute, second, nanosecond int
|
|
|
|
location := time.UTC
|
|
|
|
if end {
|
|
|
|
hour, minute, second, nanosecond = 23, 59, 59, 999999999
|
|
|
|
} else {
|
|
|
|
hour, minute, second, nanosecond = 0, 0, 0, 0
|
|
|
|
}
|
|
|
|
|
|
|
|
dateWithTime := time.Date(date.Year(), date.Month(), date.Day(), hour, minute, second, nanosecond, location)
|
|
|
|
return dateWithTime
|
|
|
|
}
|
|
|
|
|
|
|
|
// Converts the binary stype 'daysRun' field into an array of short days
|
|
|
|
func parseDaysRun(daysBinary string) []string {
|
|
|
|
log.Msg.Debug("daysRun Input: " + daysBinary)
|
|
|
|
shortDays := []string{"m", "t", "w", "th", "f", "s", "su"}
|
|
|
|
var result []string
|
|
|
|
for i, digit := range daysBinary {
|
|
|
|
if digit == '1' {
|
|
|
|
result = append(result, shortDays[i])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
|
|
|
// Converts an array if upstreamApi.ScheduleLocation types to an array of database.Stop types
|
|
|
|
func parseStops(inputStops []upstreamApi.ScheduleLocation) []database.Stop {
|
|
|
|
var stops []database.Stop
|
|
|
|
|
|
|
|
for _, loc := range inputStops {
|
|
|
|
stop := database.Stop{
|
2023-07-20 11:07:39 +01:00
|
|
|
PublicDeparture: getStringPointer(loc.PublicDepartureTime),
|
|
|
|
WttDeparture: getStringPointer(loc.ScheduledDepartureTime),
|
|
|
|
PublicArrival: getStringPointer(loc.PublicArrivalTime),
|
|
|
|
WttArrival: getStringPointer(loc.ScheduledArrivalTime),
|
2023-07-19 21:31:00 +01:00
|
|
|
IsPublic: loc.PublicDepartureTime != "" || loc.PublicArrivalTime != "",
|
|
|
|
Tiploc: loc.Location.Tiploc.TiplocID,
|
|
|
|
}
|
|
|
|
|
|
|
|
stops = append(stops, stop)
|
|
|
|
}
|
|
|
|
|
|
|
|
return stops
|
|
|
|
}
|
2023-07-20 11:07:39 +01:00
|
|
|
|
|
|
|
func getStringPointer(s string) *string {
|
|
|
|
if s == "" {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return &s
|
|
|
|
}
|