Skip to content

Commit

Permalink
Add ChargeHistory endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
jonasman committed Oct 29, 2023
1 parent 4d47737 commit efe759e
Show file tree
Hide file tree
Showing 4 changed files with 311 additions and 13 deletions.
277 changes: 277 additions & 0 deletions Sources/TeslaSwift/Model/ChargeHistory.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,277 @@
//
// ChargeHistory.swift
// TeslaSwiftDemoTests
//
// Created by João Nunes on 29/10/2023.
// Copyright © 2023 Joao Nunes. All rights reserved.
//

import Foundation

public struct ChargeHistory: Codable {
let screenTitle: String
let screenSubtitle: String
let totalCharged: Charged
let totalChargedBreakdown: Breakdown
let chargingHistoryGraph: Graph
let setRatePlan: RatePlan
let totalChargedEnergyBreakdown: Breakdown
let chargingTips: Tips
let timePeriodLimit: TimePeriodLimit

enum CodingKeys: String, CodingKey {
case screenTitle = "screen_title"
case screenSubtitle = "screen_subtitle"
case totalCharged = "total_charged"
case totalChargedBreakdown = "total_charged_breakdown"
case chargingHistoryGraph = "charging_history_graph"
case setRatePlan = "set_rate_plan"
case totalChargedEnergyBreakdown = "total_charged_energy_breakdown"
case chargingTips = "charging_tips"
case timePeriodLimit = "time_period_limit"
}

public struct Charged: Codable {
let value: String
let rawValue: Int
let afterAdornment: String
let title: String

enum CodingKeys: String, CodingKey {
case value
case rawValue = "raw_value"
case afterAdornment = "after_adornment"
case title
}
}

public struct Breakdown: Codable {
let home, superCharger, other, work: BreakdownItem

enum CodingKeys: String, CodingKey {
case home
case superCharger = "super_charger"
case other
case work
}
}

public struct BreakdownItem: Codable {
let value: String
let rawValue: Int?
let afterAdornment: String
let subTitle: String?

enum CodingKeys: String, CodingKey {
case value
case rawValue = "raw_value"
case afterAdornment = "after_adornment"
case subTitle = "sub_title"
}
}

struct Graph: Codable {
let dataPoints: [DataPoint]
let period: Period
let interval: Int
let xLabels: [XLabel]
let yLabels: [YLabel]
let horizontalGridLines: [Double]
let verticalGridLines: [Double]
let discreteX: Bool
let yRangeMax: Double
let XDomainMin: String?
let XDomainMax: String?

enum CodingKeys: String, CodingKey {
case dataPoints = "data_points"
case period
case interval
case xLabels = "x_labels"
case yLabels = "y_labels"
case horizontalGridLines = "horizontal_grid_lines"
case verticalGridLines = "vertical_grid_lines"
case discreteX = "discrete_x"
case yRangeMax = "y_range_max"
case XDomainMin = "XDomainMin"
case XDomainMax = "XDomainMax"
}
}

struct Period: Codable {
let startTimestamp: Timestamp
let endTimestamp: Timestamp

enum CodingKeys: String, CodingKey {
case startTimestamp = "start_timestamp"
case endTimestamp = "end_timestamp"
}
}

struct XLabel: Codable {
let value: String
let rawValue: Int

enum CodingKeys: String, CodingKey {
case value
case rawValue = "raw_value"
}
}

struct YLabel: Codable {
let value: String
let rawValue: Double?
let afterAdornment: String?

enum CodingKeys: String, CodingKey {
case value
case rawValue = "raw_value"
case afterAdornment = "after_adornment"
}
}

public struct DataPoint: Codable {
let timestamp: TimestampContainer
let values: [Value]
}

public struct TimestampContainer: Codable {
let timestamp: Timestamp
let displayString: String

enum CodingKeys: String, CodingKey {
case timestamp
case displayString = "display_string"
}
}

public struct Timestamp: Codable {
let seconds: Int
}

public struct Value: Codable {
let value: String
let rawValue: Double?
let afterAdornment: String
let title: String?
let subTitle: String?

enum CodingKeys: String, CodingKey {
case value
case rawValue = "raw_value"
case afterAdornment = "after_adornment"
case title
case subTitle = "sub_title"
}
}

struct RatePlan: Codable {
let messageCard: MessageCard
let primaryLink: PrimaryLink

enum CodingKeys: String, CodingKey {
case messageCard = "message_card"
case primaryLink = "primary_link"
}
}

struct Card: Codable {
let id: String
let title: String
}

struct PrimaryLink: Codable {
let type: Int
let destination: String
let label: String
}

struct Tips: Codable {
let title: String
let imageUrl: String
let textSections: [TextSection]
let tips: [TipLink]

enum CodingKeys: String, CodingKey {
case title
case imageUrl = "image_url"
case textSections = "text_sections"
case tips
}
}

struct TextSection: Codable {
let paragraphs: [String]
}

struct TipLink: Codable {
let link: LinkIcon
let section: Section
}

struct LinkIcon: Codable {
let link: Link
let leftIcon: String
let rightIcon: String

enum CodingKeys: String, CodingKey {
case link
case leftIcon = "left_icon"
case rightIcon = "right_icon"
}
}

struct Link: Codable {
let type: Int
let destination: String
let label: String
}

struct Section: Codable {
let title: String
let tips: [Tip]
}

struct Tip: Codable {
let title: String
let description: String
let media: Media
}

struct Media: Codable {
let type: Int
let source: String
let resizeMode: Int

enum CodingKeys: String, CodingKey {
case type
case source
case resizeMode = "resize_mode"
}
}

public struct SetRatePlan: Codable {
let messageCard: MessageCard
let primaryLink: PrimaryLink
}

public struct MessageCard: Codable {
let card: Card
let imageID: String

enum CodingKeys: String, CodingKey {
case card
case imageID = "image_id"
}
}

public struct TimePeriodLimit: Codable {
let ownershipStart: TimestampContainer
let featureStart: TimestampContainer

enum CodingKeys: String, CodingKey {
case ownershipStart = "ownership_start"
case featureStart = "feature_start"
}
}
}
7 changes: 5 additions & 2 deletions Sources/TeslaSwift/TeslaEndpoint.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ enum Endpoint {
case wakeUp(vehicleID: String)
case command(vehicleID: String, command: VehicleCommand)
case products
case chargeHistory(vehicleID: String)
case getEnergySiteStatus(siteID: String)
case getEnergySiteLiveStatus(siteID: String)
case getEnergySiteInfo(siteID: String)
Expand Down Expand Up @@ -84,7 +85,9 @@ extension Endpoint {
return "/api/1/vehicles/\(vehicleID)/\(command.path())"
case .products:
return "/api/1/products"

case let .chargeHistory(vehicleID):
return "/api/1/vehicles/\(vehicleID)/charge_history"

// Energy Data
case .getEnergySiteStatus(let siteID):
return "/api/1/energy_sites/\(siteID)/site_status"
Expand All @@ -105,7 +108,7 @@ extension Endpoint {

var method: String {
switch self {
case .revoke, .oAuth2Token, .oAuth2TokenCN, .wakeUp, .partnerAccounts, .command:
case .revoke, .oAuth2Token, .oAuth2TokenCN, .wakeUp, .partnerAccounts, .chargeHistory, .command:
return "POST"
case .vehicles, .vehicleSummary, .mobileAccess, .allStates, .chargeState, .climateState, .driveState, .guiSettings, .vehicleState, .vehicleConfig, .nearbyChargingSites, .oAuth2Authorization, .oAuth2revoke, .oAuth2AuthorizationCN, .oAuth2revokeCN, .products, .getEnergySiteStatus, .getEnergySiteLiveStatus, .getEnergySiteInfo, .getEnergySiteHistory, .getBatteryStatus, .getBatteryData, .getBatteryPowerHistory:
return "GET"
Expand Down
34 changes: 24 additions & 10 deletions Sources/TeslaSwift/TeslaSwift.swift
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,19 @@ extension TeslaSwift {
public func getVehicle(_ vehicle: Vehicle) async throws -> Vehicle {
return try await getVehicle(vehicle.id!)
}


/**
Wakes up the vehicle

- returns: The current Vehicle
*/
public func wakeUp(_ vehicle: Vehicle) async throws -> Vehicle {
_ = try await checkAuthentication()
let vehicleID = vehicle.id!
let response: Response<Vehicle> = try await request(.wakeUp(vehicleID: vehicleID), body: nullBody)
return response.response
}

/**
Fetches the vehicle data

Expand Down Expand Up @@ -342,17 +354,18 @@ extension TeslaSwift {
return response.response
}

/**
Wakes up the vehicle

- returns: The current Vehicle
*/
public func wakeUp(_ vehicle: Vehicle) async throws -> Vehicle {
/**
Fetches the charge history for a vehicle

- parameter vehicle: the vehicle to get charge history
- returns: The charge history
*/
public func getChargeHistory(_ vehicle: Vehicle) async throws -> ChargeHistory {
_ = try await checkAuthentication()
let vehicleID = vehicle.id!
let response: Response<Vehicle> = try await request(.wakeUp(vehicleID: vehicleID), body: nullBody)
let response: Response<ChargeHistory> = try await request(.chargeHistory(vehicleID: vehicleID), body: nullBody)
return response.response
}
}

/**
Sends a command to the vehicle
Expand Down Expand Up @@ -610,7 +623,8 @@ extension TeslaSwift {
request.httpMethod = endpoint.method

request.setValue("TeslaSwift", forHTTPHeaderField: "User-Agent")

request.setValue("TeslaApp/4.9.2", forHTTPHeaderField: "x-tesla-user-agent")

if let token = self.token?.accessToken {
request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
} else if let token = self.partnerToken?.accessToken {
Expand Down
Loading

0 comments on commit efe759e

Please sign in to comment.