commit ba01f677f7e7f5f1b956a8486e5a28c436a8b7f1 Author: Gregory Rudolph Date: Tue Jul 27 12:23:45 2021 -0400 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..557bf2c --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +Program.cs +.vscode +bin +obj \ No newline at end of file diff --git a/Client.cs b/Client.cs new file mode 100644 index 0000000..14f4554 --- /dev/null +++ b/Client.cs @@ -0,0 +1,141 @@ +using System; +using System.Net; +using System.IO; +using System.Text; +using Newtonsoft.Json; + +namespace Tesla { + +public class Client +{ + public string baseURL = "https://owner-api.teslamotors.com/api/1"; + protected string token; + public string vehicle_id { get; set; } + private RootDataResponse dataResponse; + private DateTime lastRefresh; + + public Vehicle[] ListVehicles() + { + HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(baseURL + "/vehicles"); + string responseString = processRequest(myHttpWebRequest); + VehicleListResponse response = JsonConvert.DeserializeObject(responseString); + return response.response.ToArray(); + } + + public DataResponse WakeVehicle() + { + + HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(baseURL + $"/vehicles/{vehicle_id}/wake_up"); + myHttpWebRequest.Method = "POST"; + string responseString = processRequest(myHttpWebRequest); + RootDataResponse response = JsonConvert.DeserializeObject(responseString); + return response.response; + } + + public CommandResponse RunCommand(string command, string parms = "") + { + ASCIIEncoding encoding = new ASCIIEncoding (); + byte[] byte1 = encoding.GetBytes (parms); + HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(baseURL + $"/vehicles/{vehicle_id}/command/{command}"); + myHttpWebRequest.Method = "POST"; + myHttpWebRequest.ContentLength = byte1.Length; + Stream newStream = myHttpWebRequest.GetRequestStream (); + newStream.Write (byte1, 0, byte1.Length); + + string responseString = processRequest(myHttpWebRequest); + APIResponseRoot response = JsonConvert.DeserializeObject(responseString); + return response.response; + } + + + public ChargeState GetChargeState() + { + return GetVehicleData().response.charge_state; + } + + public ClimateState GetClimateState() + { + return GetVehicleData().response.climate_state; + } + + public DriveState GetDriveState() + { + return GetVehicleData().response.drive_state; + } + public GuiSettings GetGuiSettings() + { + return GetVehicleData().response.gui_settings; + } + public VehicleState GetVehicleState() + { + return GetVehicleData().response.vehicle_state; + } + public VehicleConfig GetVehicleConfig() + { + return GetVehicleData().response.vehicle_config; + } + public bool GetMobileEnabled() + { + HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(baseURL + $"/vehicles/{vehicle_id}/mobile_enabled"); + string responseString = processRequest(myHttpWebRequest); + return responseString.Contains("true"); + } + + public RootChargingSites GetChargingSites() + { + HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(baseURL + $"/vehicles/{vehicle_id}/nearby_charging_sites"); + string responseString = processRequest(myHttpWebRequest); + RootChargingSites response = JsonConvert.DeserializeObject(responseString); + return response; + } + + public RootDataResponse GetVehicleData() + { + RootDataResponse response = this.dataResponse; + if (lastRefresh <= DateTime.UtcNow.Subtract(TimeSpan.FromMinutes(5.0))) + { + return UpdateVehicleData(); + } + + return response; + } + public RootDataResponse UpdateVehicleData() + { + HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(baseURL + $"/vehicles/{vehicle_id}/vehicle_data"); + string responseString = processRequest(myHttpWebRequest); + RootDataResponse response = JsonConvert.DeserializeObject(responseString); + this.dataResponse = response; + this.lastRefresh = DateTime.UtcNow; + return response; + } + protected string processRequest(HttpWebRequest myHttpWebRequest) + { + HttpWebResponse myHttpWebResponse = null; + addHeaders(myHttpWebRequest); + try + { + myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse(); + Stream stream = myHttpWebResponse.GetResponseStream(); + StreamReader reader = new StreamReader(stream, Encoding.UTF8); + String responseString = reader.ReadToEnd(); + myHttpWebResponse.Close(); + return responseString; + } + catch (System.Net.WebException e) + { + Console.WriteLine(e); + return null; + } + } + public void addHeaders(HttpWebRequest httpWebRequest) + { + httpWebRequest.Headers["Authorization"] = token; + httpWebRequest.Headers["User-Agent"] = "Tesla.NET"; + httpWebRequest.Headers["Content-Type"] = "application/json"; + } + public void setToken(string t) + { + this.token = t; + } +} +} \ No newline at end of file diff --git a/Commands.cs b/Commands.cs new file mode 100644 index 0000000..39db07a --- /dev/null +++ b/Commands.cs @@ -0,0 +1,47 @@ +namespace Tesla { + public class BasicCommands { + public static string Honk = "honk_horn"; + public static string Flash = "flash_lights"; + public static string Unlock = "door_unlock"; + public static string Lock = "door_lock"; + public static string OpenChargeDoor = "charge_port_door_open"; + public static string CloseChargeDoor = "charge_port_door_close"; + public static string ChargeStart = "charge_start"; + public static string ChargeStop = "charge_stop"; + public static string ChargeStandard = "charge_standard"; + public static string ChargeMax = "charge_max_range"; + public static string ClimateOn = "auto_conditioning_start"; + public static string ClimateOff = "auto_conditioning_stop"; + public static string MediaPlayPauseToggle = "media_toggle_playback"; + public static string MediaNext = "media_next_track"; + public static string MediaPrevious = "media_prev_track"; + public static string MediaNextFavourite = "media_next_fav"; + public static string MediaPreviousFavourite = "media_prev_fav"; + public static string MediaVolumeUp = "media_volume_up"; + public static string MediaVolumeDown = "media_volume_down"; + public static string CancelSoftwareUpdate = "cancel_software_update"; + public static string ResetValetPin = "reset_valet_pin"; +} + +// ExtendedCommands require parms https://tesla-api.timdorr.com/vehicle/commands/ +public class ExtendedCommands { + public static string RemoteStart = "remote_start_drive"; + public static string HomeLink = "trigger_homelink"; + public static string SetSpeedLimit = "speed_limit_set_limit"; + public static string ActivateSpeedLimit = "speed_limit_activate"; + public static string DeactivateSpeedLimit = "speed_limit_deactivate"; + public static string ClearSpeedLimitPin = "speed_limit_clear_pin"; + public static string SetValetMode = "set_valet_mode"; + public static string SetSentryMode = "set_sentry_mode"; + public static string Trunk = "actuate_trunk"; + public static string Windows = "window_control"; + public static string Sunroof = "sun_roof_control"; + public static string SetChargeLimit = "set_charge_limit"; + public static string SetClimateTemp = "set_temps"; + public static string SetPreconditioningMax = "set_preconditioning_max"; + public static string RemoteSeatHeater = "remote_seat_heater_request"; + public static string RemoteSteeringWheelheater = "remote_steering_wheel_heater_request"; + public static string ShareContent = "share"; + public static string ScheduleSoftwareUpdate = "schedule_software_update"; +} +} \ No newline at end of file diff --git a/Models/APIResponse.cs b/Models/APIResponse.cs new file mode 100644 index 0000000..8f207a7 --- /dev/null +++ b/Models/APIResponse.cs @@ -0,0 +1,17 @@ +// APIResponseRoot myDeserializedClass = JsonConvert.DeserializeObject(myJsonResponse); +// https://json2csharp.com/ + + namespace Tesla { + public class CommandResponse + { + public bool result { get; set; } + public string reason { get; set; } + } + + public class APIResponseRoot + { + public CommandResponse response { get; set; } + } + + + } \ No newline at end of file diff --git a/Models/ChargingSites.cs b/Models/ChargingSites.cs new file mode 100644 index 0000000..0f3ea2a --- /dev/null +++ b/Models/ChargingSites.cs @@ -0,0 +1,46 @@ + +using System.Collections.Generic; +// RootChargingSites myDeserializedClass = JsonConvert.DeserializeObject(myJsonResponse); + +namespace Tesla +{ + public class Location + { + public double lat { get; set; } + public double @long { get; set; } + } + + public class DestinationCharging + { + public Location location { get; set; } + public string name { get; set; } + public string type { get; set; } + public double distance_miles { get; set; } + } + + public class Supercharger + { + public Location location { get; set; } + public string name { get; set; } + public string type { get; set; } + public double distance_miles { get; set; } + public int available_stalls { get; set; } + public int total_stalls { get; set; } + public bool site_closed { get; set; } + } + + public class ChargingSitesResponse + { + public int congestion_sync_time_utc_secs { get; set; } + public List destination_charging { get; set; } + public List superchargers { get; set; } + public long timestamp { get; set; } + } + + public class RootChargingSites + { + public ChargingSitesResponse response { get; set; } + } + + +} \ No newline at end of file diff --git a/Models/StateData.cs b/Models/StateData.cs new file mode 100644 index 0000000..19ea10c --- /dev/null +++ b/Models/StateData.cs @@ -0,0 +1,235 @@ +// RootDataResponse myDeserializedClass = JsonConvert.DeserializeObject(myJsonResponse); +using System.Collections.Generic; +namespace Tesla +{ + + public class DriveState + { + public string gps_as_of { get; set; } + public string heading { get; set; } + public double latitude { get; set; } + public double longitude { get; set; } + public double native_latitude { get; set; } + public string native_location_supported { get; set; } + public double native_longitude { get; set; } + public string native_type { get; set; } + public string power { get; set; } + public object shift_state { get; set; } + public object speed { get; set; } + public long timestamp { get; set; } + } + + public class ClimateState + { + public string battery_heater { get; set; } + public string battery_heater_no_power { get; set; } + public string climate_keeper_mode { get; set; } + public string defrost_mode { get; set; } + public double driver_temp_setting { get; set; } + public string fan_status { get; set; } + public double inside_temp { get; set; } + public string is_auto_conditioning_on { get; set; } + public string is_climate_on { get; set; } + public string is_front_defroster_on { get; set; } + public string is_preconditioning { get; set; } + public string is_rear_defroster_on { get; set; } + public string left_temp_direction { get; set; } + public double max_avail_temp { get; set; } + public double min_avail_temp { get; set; } + public double outside_temp { get; set; } + public double passenger_temp_setting { get; set; } + public string remote_heater_control_enabled { get; set; } + public string right_temp_direction { get; set; } + public string seat_heater_left { get; set; } + public string seat_heater_right { get; set; } + public string side_mirror_heaters { get; set; } + public long timestamp { get; set; } + public string wiper_blade_heater { get; set; } + } + + public class ChargeState + { + public string battery_heater_on { get; set; } + public string battery_level { get; set; } + public double battery_range { get; set; } + public string charge_current_request { get; set; } + public string charge_current_request_max { get; set; } + public string charge_enable_request { get; set; } + public double charge_energy_added { get; set; } + public string charge_limit_soc { get; set; } + public string charge_limit_soc_max { get; set; } + public string charge_limit_soc_min { get; set; } + public string charge_limit_soc_std { get; set; } + public double charge_miles_added_ideal { get; set; } + public double charge_miles_added_rated { get; set; } + public object charge_port_cold_weather_mode { get; set; } + public string charge_port_door_open { get; set; } + public string charge_port_latch { get; set; } + public double charge_rate { get; set; } + public string charge_to_max_range { get; set; } + public string charger_actual_current { get; set; } + public string charger_phases { get; set; } + public string charger_pilot_current { get; set; } + public string charger_power { get; set; } + public string charger_voltage { get; set; } + public string charging_state { get; set; } + public string conn_charge_cable { get; set; } + public double est_battery_range { get; set; } + public string fast_charger_brand { get; set; } + public string fast_charger_present { get; set; } + public string fast_charger_type { get; set; } + public double ideal_battery_range { get; set; } + public string managed_charging_active { get; set; } + public object managed_charging_start_time { get; set; } + public string managed_charging_user_canceled { get; set; } + public string max_range_charge_counter { get; set; } + public string minutes_to_full_charge { get; set; } + public string not_enough_power_to_heat { get; set; } + public string scheduled_charging_pending { get; set; } + public object scheduled_charging_start_time { get; set; } + public double time_to_full_charge { get; set; } + public long timestamp { get; set; } + public string trip_charging { get; set; } + public string usable_battery_level { get; set; } + public object user_charge_enable_request { get; set; } + } + + public class GuiSettings + { + public string gui_24_hour_time { get; set; } + public string gui_charge_rate_units { get; set; } + public string gui_distance_units { get; set; } + public string gui_range_display { get; set; } + public string gui_temperature_units { get; set; } + public string show_range_units { get; set; } + public long timestamp { get; set; } + } + + public class MediaState + { + public string remote_control_enabled { get; set; } + } + + public class SoftwareUpdate + { + public string download_perc { get; set; } + public string expected_duration_sec { get; set; } + public string install_perc { get; set; } + public string status { get; set; } + public string version { get; set; } + } + + public class SpeedLimitMode + { + public string active { get; set; } + public double current_limit_mph { get; set; } + public string max_limit_mph { get; set; } + public string min_limit_mph { get; set; } + public string pin_code_set { get; set; } + } + + public class VehicleState + { + public string api_version { get; set; } + public string autopark_state_v2 { get; set; } + public string autopark_style { get; set; } + public string calendar_supported { get; set; } + public string car_version { get; set; } + public string center_display_state { get; set; } + public string df { get; set; } + public string dr { get; set; } + public string fd_window { get; set; } + public string fp_window { get; set; } + public string ft { get; set; } + public string homelink_device_count { get; set; } + public string homelink_nearby { get; set; } + public string is_user_present { get; set; } + public string last_autopark_error { get; set; } + public string locked { get; set; } + public MediaState media_state { get; set; } + public string notifications_supported { get; set; } + public double odometer { get; set; } + public string parsed_calendar_supported { get; set; } + public string pf { get; set; } + public string pr { get; set; } + public string rd_window { get; set; } + public string remote_start { get; set; } + public string remote_start_enabled { get; set; } + public string remote_start_supported { get; set; } + public string rp_window { get; set; } + public string rt { get; set; } + public string sentry_mode { get; set; } + public string sentry_mode_available { get; set; } + public string smart_summon_available { get; set; } + public SoftwareUpdate software_update { get; set; } + public SpeedLimitMode speed_limit_mode { get; set; } + public string summon_standby_mode_enabled { get; set; } + public string sun_roof_percent_open { get; set; } + public string sun_roof_state { get; set; } + public long timestamp { get; set; } + public string valet_mode { get; set; } + public string valet_pin_needed { get; set; } + public object vehicle_name { get; set; } + } + + public class VehicleConfig + { + public string can_accept_navigation_requests { get; set; } + public string can_actuate_trunks { get; set; } + public string car_special_type { get; set; } + public string car_type { get; set; } + public string charge_port_type { get; set; } + public string default_charge_to_max { get; set; } + public string ece_restrictions { get; set; } + public string eu_vehicle { get; set; } + public string exterior_color { get; set; } + public string has_air_suspension { get; set; } + public string has_ludicrous_mode { get; set; } + public string motorized_charge_port { get; set; } + public string plg { get; set; } + public string rear_seat_heaters { get; set; } + public string rear_seat_type { get; set; } + public string rhd { get; set; } + public string roof_color { get; set; } + public string seat_type { get; set; } + public string spoiler_type { get; set; } + public string sun_roof_installed { get; set; } + public string third_row_seats { get; set; } + public long timestamp { get; set; } + public string trim_badging { get; set; } + public string use_range_badging { get; set; } + public string wheel_type { get; set; } + } + + public class DataResponse + { + public long id { get; set; } + public long user_id { get; set; } + public string vehicle_id { get; set; } + public string vin { get; set; } + public string display_name { get; set; } + public string option_codes { get; set; } + public object color { get; set; } + public string access_type { get; set; } + public List tokens { get; set; } + public string state { get; set; } + public string in_service { get; set; } + public string id_s { get; set; } + public string calendar_enabled { get; set; } + public string api_version { get; set; } + public object backseat_token { get; set; } + public object backseat_token_updated_at { get; set; } + public DriveState drive_state { get; set; } + public ClimateState climate_state { get; set; } + public ChargeState charge_state { get; set; } + public GuiSettings gui_settings { get; set; } + public VehicleState vehicle_state { get; set; } + public VehicleConfig vehicle_config { get; set; } + } + + public class RootDataResponse + { + public DataResponse response { get; set; } + } + +} \ No newline at end of file diff --git a/Models/Vehicle.cs b/Models/Vehicle.cs new file mode 100644 index 0000000..414f050 --- /dev/null +++ b/Models/Vehicle.cs @@ -0,0 +1,29 @@ + +using System.Collections.Generic; +namespace Tesla +{ + public class VehicleListResponse + { + public List response { get; set; } + public int count { get; set; } + } + public class Vehicle + { + public long id { get; set; } + public int vehicle_id { get; set; } + public string vin { get; set; } + public string display_name { get; set; } + public string option_codes { get; set; } + public object color { get; set; } + public string access_type { get; set; } + public List tokens { get; set; } + public string state { get; set; } + public bool in_service { get; set; } + public string id_s { get; set; } + public bool calendar_enabled { get; set; } + public int api_version { get; set; } + public object backseat_token { get; set; } + public object backseat_token_updated_at { get; set; } + public string command_signing { get; set; } + } +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/Tesla.NET.csproj b/Tesla.NET.csproj new file mode 100644 index 0000000..a3c7122 --- /dev/null +++ b/Tesla.NET.csproj @@ -0,0 +1,13 @@ + + + + Exe + net5.0 + + + + + + + +