First Commit

This commit is contained in:
2022-03-20 21:00:00 -04:00
commit 2f95fab7f3
53 changed files with 959 additions and 0 deletions

View File

@ -0,0 +1,13 @@
package haus.nightmare.GlassTesla;
import android.app.Application;
import android.test.ApplicationTestCase;
/**
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
*/
public class ApplicationTest extends ApplicationTestCase<Application> {
public ApplicationTest() {
super(Application.class);
}
}

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="haus.nightmare.GlassTesla">
<uses-permission android:name="com.google.android.glass.permission.DEVELOPMENT" />
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
tools:ignore="GoogleAppIndexingWarning">
<activity
android:name="haus.nightmare.GlassTesla.MainActivity"
android:icon="@mipmap/ic_launcher"
android:label="@string/title_activity_main">
<intent-filter>
<action android:name="com.google.android.glass.action.VOICE_TRIGGER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="com.google.android.glass.VoiceTrigger"
android:resource="@xml/voice_trigger" />
</activity>
</application>
</manifest>

View File

@ -0,0 +1,47 @@
package haus.nightmare.GlassTesla;
public class ChargeState {
public boolean battery_heater_on;
public int battery_level;
public double battery_range;
public int charge_current_request;
public int charge_current_request_max;
public boolean charge_enable_request;
public double charge_energy_added;
public int charge_limit_soc;
public int charge_limit_soc_max;
public int charge_limit_soc_min;
public int charge_limit_soc_std;
public double charge_miles_added_ideal;
public double charge_miles_added_rated;
public Object charge_port_cold_weather_mode;
public boolean charge_port_door_open;
public String charge_port_latch;
public double charge_rate;
public boolean charge_to_max_range;
public int charger_actual_current;
public int charger_phases;
public int charger_pilot_current;
public int charger_power;
public int charger_voltage;
public String charging_state;
public String conn_charge_cable;
public double est_battery_range;
public String fast_charger_brand;
public boolean fast_charger_present;
public String fast_charger_type;
public double ideal_battery_range;
public boolean managed_charging_active;
public Object managed_charging_start_time;
public boolean managed_charging_user_canceled;
public int max_range_charge_counter;
public int minutes_to_full_charge;
public boolean not_enough_power_to_heat;
public boolean scheduled_charging_pending;
public Object scheduled_charging_start_time;
public double time_to_full_charge;
public long timestamp;
public boolean trip_charging;
public int usable_battery_level;
public Object user_charge_enable_request;
}

View File

@ -0,0 +1,28 @@
package haus.nightmare.GlassTesla;
public class ClimateState {
public boolean battery_heater;
public boolean battery_heater_no_power;
public String climate_keeper_mode;
public int defrost_mode;
public double driver_temp_setting;
public int fan_status;
public double inside_temp;
public boolean is_auto_conditioning_on;
public boolean is_climate_on;
public boolean is_front_defroster_on;
public boolean is_preconditioning;
public boolean is_rear_defroster_on;
public int left_temp_direction;
public double max_avail_temp;
public double min_avail_temp;
public double outside_temp;
public double passenger_temp_setting;
public boolean remote_heater_control_enabled;
public int right_temp_direction;
public int seat_heater_left;
public int seat_heater_right;
public boolean side_mirror_heaters;
public long timestamp;
public boolean wiper_blade_heater;
}

View File

@ -0,0 +1,20 @@
package haus.nightmare.GlassTesla;
// import com.fasterxml.jackson.databind.ObjectMapper; // version 2.11.1
// import com.fasterxml.jackson.annotation.JsonProperty; // version 2.11.1
/* ObjectMapper om = new ObjectMapper();
Root root = om.readValue(myJsonString, Root.class); */
public class DriveState {
public int gps_as_of;
public int heading;
public double latitude;
public double longitude;
public double native_latitude;
public int native_location_supported;
public double native_longitude;
public String native_type;
public int power;
public Object shift_state;
public Object speed;
public long timestamp;
}

View File

@ -0,0 +1,11 @@
package haus.nightmare.GlassTesla;
public class GuiSettings {
public boolean gui_24_hour_time;
public String gui_charge_rate_units;
public String gui_distance_units;
public String gui_range_display;
public String gui_temperature_units;
public boolean show_range_units;
public long timestamp;
}

View File

@ -0,0 +1,190 @@
package haus.nightmare.GlassTesla;
import com.google.android.glass.media.Sounds;
import com.google.android.glass.widget.CardBuilder;
import com.google.android.glass.widget.CardScrollAdapter;
import com.google.android.glass.widget.CardScrollView;
import com.google.gson.Gson;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.StrictMode;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import org.conscrypt.Conscrypt;
import java.net.URL;
import java.security.Security;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import javax.net.ssl.SSLException;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class MainActivity extends Activity {
private CardScrollView cardScroller;
private View view;
private TeslaResponse vehicleData;
private SharedPreferences prefs;
@Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
prefs = getPreferences(MODE_PRIVATE);
view = buildStatusView();
view.setKeepScreenOn(true);
cardScroller = new CardScrollView(this);
cardScroller.setAdapter(new CardScrollAdapter() {
@Override
public int getCount() {
return 1;
}
@Override
public Object getItem(int position) {
return view;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return view;
}
@Override
public int getPosition(Object item) {
if (view.equals(item)) {
return 0;
}
return AdapterView.INVALID_POSITION;
}
});
cardScroller.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
am.playSoundEffect(Sounds.TAP);
}
});
setContentView(cardScroller);
}
@Override
protected void onResume() {
super.onResume();
cardScroller.activate();
}
@Override
protected void onPause() {
cardScroller.deactivate();
super.onPause();
}
private View buildStatusView() {
if (vehicleData == null) {
try {
getVehicleData();
} catch(Exception e) {
Log.v("Tesla API Setup", "Unable to get Tesla data", e);
this.finishAffinity();
System.exit(0); // Shouldn't be reached, but just in case let's kill it dead
}
}
CardBuilder card = new CardBuilder(this, CardBuilder.Layout.TEXT);
String chargeDuration = "";
int totalSecs = (int) (vehicleData.charge_state.time_to_full_charge * 3600);
int hours = totalSecs / 3600;
int minutes = (totalSecs % 3600) / 60;
if (hours > 0) {
chargeDuration += hours + "h";
}
if (minutes > 0) {
chargeDuration += minutes + "m";
}
Calendar cal = Calendar.getInstance();
cal.add(Calendar.HOUR_OF_DAY, hours);
cal.add(Calendar.MINUTE, minutes);
card.setText(
String.format(getString(R.string.StatusFormat),
vehicleData.charge_state.battery_level,
(int) vehicleData.charge_state.battery_range,
vehicleData.vehicle_state.sentry_mode ? "Enabled" : "Disabled",
vehicleData.charge_state.charging_state,
vehicleData.charge_state.charger_power,
chargeDuration,
new SimpleDateFormat("hh:mm").format(cal.getTime())
)
);
card.setFootnote(String.format("%s last updated: %s",
vehicleData.display_name,
new SimpleDateFormat("hh:mm").format(vehicleData.charge_state.timestamp)
));
return card.getView();
}
// /api/1/vehicles/{id}/vehicle_data
public void getVehicleData() {
String vehicleId = prefs.getString("vehicle_id", "");
String json = getResponseFromJsonURL("https://owner-api.teslamotors.com/api/1/vehicles/" + vehicleId +"/vehicle_data");
Gson gson = new Gson();
ResponseRoot root = gson.fromJson(json, ResponseRoot.class);
vehicleData = root.response;
}
public String getResponseFromJsonURL(String url) {
String token = prefs.getString("bearer_token", "");
String jsonResponse = null;
if (url.length() > 0) {
try {
Security.insertProviderAt(Conscrypt.newProvider(), 1);
/************** For getting response from HTTP URL start ***************/
URL object = new URL(url);
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(object)
.addHeader("Authorization", "Bearer " + token)
.addHeader("User-Agent", "Tesla-GLASS")
.addHeader("Content-Type", "application/json")
.build();
Response response = client.newCall(request).execute();
int responseCode = response.code();
if (responseCode == 200) {
return response.body().string();
}
} catch (SSLException e) {
Log.e("DataSSL", "SSL Exception getting json:", e);
} catch (Exception e) {
e.printStackTrace();
}
}
return jsonResponse;
}
}

View File

@ -0,0 +1,5 @@
package haus.nightmare.GlassTesla;
public class MediaState {
public boolean remote_control_enabled;
}

View File

@ -0,0 +1,5 @@
package haus.nightmare.GlassTesla;
public class ResponseRoot {
public TeslaResponse response;
}

View File

@ -0,0 +1,9 @@
package haus.nightmare.GlassTesla;
public class SoftwareUpdate {
public int download_perc;
public int expected_duration_sec;
public int install_perc;
public String status;
public String version;
}

View File

@ -0,0 +1,9 @@
package haus.nightmare.GlassTesla;
public class SpeedLimitMode {
public boolean active;
public double current_limit_mph;
public int max_limit_mph;
public int min_limit_mph;
public boolean pin_code_set;
}

View File

@ -0,0 +1,30 @@
package haus.nightmare.GlassTesla;
import java.util.ArrayList;
public class TeslaResponse{
public long id;
public long user_id;
public long vehicle_id;
public String vin;
public String display_name;
public String option_codes;
public Object color;
public String access_type;
public ArrayList<String> tokens;
public String state;
public boolean in_service;
public String id_s;
public boolean calendar_enabled;
public int api_version;
public Object backseat_token;
public Object backseat_token_updated_at;
public DriveState drive_state;
public ClimateState climate_state;
public ChargeState charge_state;
public GuiSettings gui_settings;
public VehicleState vehicle_state;
public VehicleConfig vehicle_config;
}

View File

@ -0,0 +1,29 @@
package haus.nightmare.GlassTesla;
public class VehicleConfig {
public boolean can_accept_navigation_requests;
public boolean can_actuate_trunks;
public String car_special_type;
public String car_type;
public String charge_port_type;
public boolean default_charge_to_max;
public boolean ece_restrictions;
public boolean eu_vehicle;
public String exterior_color;
public boolean has_air_suspension;
public boolean has_ludicrous_mode;
public boolean motorized_charge_port;
public boolean plg;
public int rear_seat_heaters;
public int rear_seat_type;
public boolean rhd;
public String roof_color;
public int seat_type;
public String spoiler_type;
public int sun_roof_installed;
public String third_row_seats;
public long timestamp;
public String trim_badging;
public boolean use_range_badging;
public String wheel_type;
}

View File

@ -0,0 +1,44 @@
package haus.nightmare.GlassTesla;
public class VehicleState {
public int api_version;
public String autopark_state_v2;
public String autopark_style;
public boolean calendar_supported;
public String car_version;
public int center_display_state;
public int df;
public int dr;
public int fd_window;
public int fp_window;
public int ft;
public int homelink_device_count;
public boolean homelink_nearby;
public boolean is_user_present;
public String last_autopark_error;
public boolean locked;
public MediaState media_state;
public boolean notifications_supported;
public double odometer;
public boolean parsed_calendar_supported;
public int pf;
public int pr;
public int rd_window;
public boolean remote_start;
public boolean remote_start_enabled;
public boolean remote_start_supported;
public int rp_window;
public int rt;
public boolean sentry_mode;
public boolean sentry_mode_available;
public boolean smart_summon_available;
public SoftwareUpdate software_update;
public SpeedLimitMode speed_limit_mode;
public boolean summon_standby_mode_enabled;
public int sun_roof_percent_open;
public String sun_roof_state;
public long timestamp;
public boolean valet_mode;
public boolean valet_pin_needed;
public Object vehicle_name;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 633 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -0,0 +1,7 @@
<resources>
<string name="app_name">GlassTesla</string>
<string name="title_activity_main">Glass Tesla</string>
<string name="hello_world">Hello, world!</string>
<string name="voice_trigger">glass tesla</string>
<string name="StatusFormat">Battery: %d%% (%d mi)\nSentry Mode: %s \n%s: %dkW \nTime to Full: %s (%s)</string>
</resources>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="android:Theme.Holo.Light"></style>
</resources>

View File

@ -0,0 +1,2 @@
<!-- For more information about voice trigger, check out: https://developers.google.com/glass/develop/gdk/starting-glassware -->
<trigger keyword="@string/voice_trigger" />