Skip to content

Commit

Permalink
SBB: parse unknown delays
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-albers committed Jan 30, 2025
1 parent 5e59de0 commit c9a0b9c
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 8 deletions.
10 changes: 8 additions & 2 deletions Sources/TripKit/Model/Stop.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ public class Stop: NSObject, NSSecureCoding {
predictedTime: aDecoder.decodeObject(of: NSDate.self, forKey: PropertyKey.predictedDepartureTime) as Date?,
plannedPlatform: aDecoder.decodeObject(of: NSString.self, forKey: PropertyKey.plannedDeparturePlatform) as String?,
predictedPlatform: aDecoder.decodeObject(of: NSString.self, forKey: PropertyKey.predictedDeparturePlatform) as String?,
cancelled: aDecoder.decodeBool(forKey: PropertyKey.departureCancelled)
cancelled: aDecoder.decodeBool(forKey: PropertyKey.departureCancelled),
undefinedDelay: aDecoder.decodeBool(forKey: PropertyKey.departureUndefinedDelay)
)
} else {
departure = nil
Expand All @@ -92,7 +93,8 @@ public class Stop: NSObject, NSSecureCoding {
predictedTime: aDecoder.decodeObject(of: NSDate.self, forKey: PropertyKey.predictedArrivalTime) as Date?,
plannedPlatform: aDecoder.decodeObject(of: NSString.self, forKey: PropertyKey.plannedArrivalPlatform) as String?,
predictedPlatform: aDecoder.decodeObject(of: NSString.self, forKey: PropertyKey.predictedArrivalPlatform) as String?,
cancelled: aDecoder.decodeBool(forKey: PropertyKey.arrivalCancelled)
cancelled: aDecoder.decodeBool(forKey: PropertyKey.arrivalCancelled),
undefinedDelay: aDecoder.decodeBool(forKey: PropertyKey.arrivalUndefinedDelay)
)
} else {
arrival = nil
Expand All @@ -110,6 +112,7 @@ public class Stop: NSObject, NSSecureCoding {
aCoder.encode(departure.plannedPlatform, forKey: PropertyKey.plannedDeparturePlatform)
aCoder.encode(departure.predictedPlatform, forKey: PropertyKey.predictedDeparturePlatform)
aCoder.encode(departure.cancelled, forKey: PropertyKey.departureCancelled)
aCoder.encode(departure.undefinedDelay, forKey: PropertyKey.departureUndefinedDelay)
}

if let arrival = arrival {
Expand All @@ -118,6 +121,7 @@ public class Stop: NSObject, NSSecureCoding {
aCoder.encode(arrival.plannedPlatform, forKey: PropertyKey.plannedArrivalPlatform)
aCoder.encode(arrival.predictedPlatform, forKey: PropertyKey.predictedArrivalPlatform)
aCoder.encode(arrival.cancelled, forKey: PropertyKey.arrivalCancelled)

Check failure on line 123 in Sources/TripKit/Model/Stop.swift

View workflow job for this annotation

GitHub Actions / Fixtures test results

error

Cannot find 'arriva' in scope
aCoder.encode(arriva.undefinedDelay, forKey: PropertyKey.arrivalUndefinedDelay)
}

aCoder.encode(message, forKey: PropertyKey.message)
Expand All @@ -140,11 +144,13 @@ public class Stop: NSObject, NSSecureCoding {
static let plannedArrivalPlatform = "plannedArrivalPlatform"
static let predictedArrivalPlatform = "predictedArrivalPlatform"
static let arrivalCancelled = "arrivalCancelled"
static let arrivalUndefinedDelay = "arrivalUndefinedDelay"
static let plannedDepartureTime = "plannedDepartureTime"
static let predictedDepartureTime = "predictedDepartureTime"
static let plannedDeparturePlatform = "plannedDeparturePlatform"
static let predictedDeparturePlatform = "predictedDeparturePlatform"
static let departureCancelled = "departureCancelled"
static let departureUndefinedDelay = "departureUndefinedDelay"
static let message = "message"

}
Expand Down
5 changes: 4 additions & 1 deletion Sources/TripKit/Model/StopEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ public class StopEvent: NSObject {
public let predictedPlatform: String?
/// True if the stop has been planned originally, but is now skipped.
public var cancelled: Bool
/// True if the actual delay is unknown.
public var undefinedDelay: Bool

/// Predicted time if available, otherwise the planned time.
public var time: Date { predictedTime ?? plannedTime }
Expand All @@ -42,13 +44,14 @@ public class StopEvent: NSObject {
return max(plannedTime, predictedTime)
}

public init(location: Location, plannedTime: Date, predictedTime: Date?, plannedPlatform: String?, predictedPlatform: String?, cancelled: Bool) {
public init(location: Location, plannedTime: Date, predictedTime: Date?, plannedPlatform: String?, predictedPlatform: String?, cancelled: Bool, undefinedDelay: Bool = false) {
self.location = location
self.plannedTime = plannedTime
self.predictedTime = predictedTime
self.plannedPlatform = plannedPlatform
self.predictedPlatform = predictedPlatform
self.cancelled = cancelled
self.undefinedDelay = undefinedDelay
}

public override func isEqual(_ other: Any?) -> Bool {
Expand Down
5 changes: 5 additions & 0 deletions Sources/TripKit/Model/Trip.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ public class Trip: NSObject, NSSecureCoding {
return Int(predictedArrival.timeIntervalSince(leg.arrivalStop.plannedTime) / 60) != 0
}

/// Returns true if any of the legs have an unknown delay.
public var hasUndefinedDelay: Bool {
return legs.compactMap({$0 as? PublicLeg}).contains(where: {$0.departureStop.undefinedDelay || $0.arrivalStop.undefinedDelay})
}

/// Returns the earliest departure time.
///
/// This may be either the predicted or the planned time, depending on what is smaller.
Expand Down
11 changes: 6 additions & 5 deletions Sources/TripKit/Provider/Implementations/SbbProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -682,7 +682,7 @@ public class SbbProvider: AbstractNetworkProvider {
return Location(type: .station, id: id, coord: coord, place: place, name: name)
}

private func gql_parseStop(location: Location, json: JSON, cancelled: Bool) -> StopEvent? {
private func gql_parseStop(location: Location, json: JSON, cancelled: Bool, delayUndefined: Bool) -> StopEvent? {
let plannedTime = parseTime(from: json["time"])
let delay = json["delay"].intValue
let predictedTime = plannedTime?.addingTimeInterval(TimeInterval(delay * 60))
Expand All @@ -693,7 +693,7 @@ public class SbbProvider: AbstractNetworkProvider {

let stopEvent: StopEvent?
if let plannedTime = plannedTime {
stopEvent = StopEvent(location: location, plannedTime: plannedTime, predictedTime: predictedTime, plannedPlatform: plannedPosition, predictedPlatform: predictedPosition, cancelled: cancelled)
stopEvent = StopEvent(location: location, plannedTime: plannedTime, predictedTime: predictedTime, plannedPlatform: plannedPosition, predictedPlatform: predictedPosition, cancelled: cancelled, undefinedDelay: delayUndefined)
} else {
stopEvent = nil
}
Expand Down Expand Up @@ -929,11 +929,12 @@ public class SbbProvider: AbstractNetworkProvider {
guard let location = gql_parsePlace(json: stopJson["place"]) else { continue }

let status = stopJson["stopStatus"].string
let statusMessage = stopJson["stopStatusFormatted"].string
let statusMessage = Set([stopJson["stopStatusFormatted"].string, stopJson["departure", "delayText"].string, stopJson["arrival", "delayText"].string].compactMap({$0})).joined(separator: ". ")
let forBoarding = stopJson["forBoarding"].boolValue
let forAlighting = stopJson["forAlighting"].boolValue
let isFirst = index == 0
let isLast = index == jsonStopPoints.count - 1
let delayUndefined = stopJson["delayUndefined"].boolValue
var cancelled = status == "CANCELLED" || status == "NOT_SERVICED"
if (status == "END_PARTIAL_CANCELLATION" || !forAlighting) && isLast {
cancelled = true
Expand All @@ -943,8 +944,8 @@ public class SbbProvider: AbstractNetworkProvider {
cancelled = true
}

let departure = gql_parseStop(location: location, json: stopJson["departure"], cancelled: cancelled)
let arrival = gql_parseStop(location: location, json: stopJson["arrival"], cancelled: cancelled)
let departure = gql_parseStop(location: location, json: stopJson["departure"], cancelled: cancelled, delayUndefined: delayUndefined)
let arrival = gql_parseStop(location: location, json: stopJson["arrival"], cancelled: cancelled, delayUndefined: delayUndefined)

let loadFactor = parseLoadFactor(from: stopJson["occupancy", "\(occupancyClass)Class"])
if let loadFactor = loadFactor, maxOccupancy == nil || loadFactor.rawValue < maxOccupancy!.rawValue {
Expand Down

0 comments on commit c9a0b9c

Please sign in to comment.