Skip to content

Commit

Permalink
Update main.cpp
Browse files Browse the repository at this point in the history
  • Loading branch information
awiswasi authored Jan 30, 2025
1 parent 8e4f9e1 commit 1a2f677
Showing 1 changed file with 118 additions and 83 deletions.
201 changes: 118 additions & 83 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
#include <string>
#include <chrono>
#include <thread>

#include <iomanip>
#include "controller.h"


// Helper functions
std::string get_masked_input(const std::string& prompt) {
std::string input;
std::cout << prompt;
Expand All @@ -15,6 +15,112 @@ std::string get_masked_input(const std::string& prompt) {
return input;
}

std::string generate_device_id() {
return std::to_string(
std::chrono::duration_cast<std::chrono::seconds>(
std::chrono::system_clock::now().time_since_epoch()
).count()
);
}

bool handle_2fa_registration(subarulink::Controller& ctrl) {
auto methods = ctrl.contact_methods();
if (methods.empty()) {
std::cerr << "No 2FA contact methods available" << std::endl;
return false;
}

// Display available 2FA methods
std::cout << "\nSelect 2FA method:" << std::endl;
int i = 1;
for (const auto& method : methods) {
std::cout << i++ << ". " << method.second << std::endl;
}

// Get user choice
int choice;
std::cout << "Enter choice (1-" << methods.size() << "): ";
std::cin >> choice;
std::cin.ignore(); // Clear newline

// Get selected method
auto it = methods.begin();
std::advance(it, choice - 1);

// Request code
std::cout << "Requesting authentication code..." << std::endl;
if (!ctrl.request_auth_code(it->first).get()) {
std::cerr << "Failed to request authentication code" << std::endl;
return false;
}

// Get verification code from user
std::cout << "Enter verification code sent to " << it->second << ": ";
std::string code;
std::getline(std::cin, code);

// Submit verification code
std::cout << "Submitting verification code..." << std::endl;
if (!ctrl.submit_auth_code(code).get()) {
std::cerr << "Failed to verify code" << std::endl;
return false;
}

std::cout << "Device successfully registered!" << std::endl;
return true;
}

void display_vehicle_info(const std::string& vin, subarulink::Controller& ctrl) {
std::cout << "\nVehicle: " << ctrl.vin_to_name(vin) << std::endl;
std::cout << "Year: " << ctrl.get_model_year(vin) << std::endl;
std::cout << "Model: " << ctrl.get_model_name(vin) << std::endl;

// Get detailed data
auto vehicle_data = ctrl.get_data(vin).get();

try {
// Display odometer
auto odo_it = vehicle_data.vehicle_status.find("ODOMETER");
if (odo_it != vehicle_data.vehicle_status.end() && !odo_it->second.is_null()) {
std::cout << "Odometer: " << odo_it->second.get<int>() << " miles" << std::endl;
} else {
std::cout << "Odometer: Not available" << std::endl;
}

// Display average fuel consumption
auto mpg_it = vehicle_data.vehicle_status.find("AVG_FUEL_CONSUMPTION");
if (mpg_it != vehicle_data.vehicle_status.end() && !mpg_it->second.is_null()) {
std::cout << "Average MPG: " << std::fixed << std::setprecision(1)
<< mpg_it->second.get<double>() << std::endl;
} else {
std::cout << "Average MPG: Not available" << std::endl;
}

// Display range
auto range_it = vehicle_data.vehicle_status.find("DISTANCE_TO_EMPTY_FUEL");
if (range_it != vehicle_data.vehicle_status.end() && !range_it->second.is_null()) {
std::cout << "Range: " << range_it->second.get<int>() << " miles" << std::endl;
} else {
std::cout << "Range: Not available" << std::endl;
}

// Display location if available
auto lat_it = vehicle_data.vehicle_status.find("LATITUDE");
auto lon_it = vehicle_data.vehicle_status.find("LONGITUDE");
if (lat_it != vehicle_data.vehicle_status.end() && lon_it != vehicle_data.vehicle_status.end() &&
!lat_it->second.is_null() && !lon_it->second.is_null()) {
std::cout << "Location: " << std::fixed << std::setprecision(6)
<< lat_it->second.get<double>() << ", "
<< lon_it->second.get<double>() << std::endl;
} else {
std::cout << "Location: Not available" << std::endl;
}

} catch (const std::exception& e) {
std::cout << "Error reading vehicle data: " << e.what() << std::endl;
}
}

int main() {
try {
// Get credentials
Expand All @@ -25,104 +131,33 @@ int main() {
std::string password = get_masked_input("Enter Subaru Starlink password: ");
std::string pin = get_masked_input("Enter Subaru Starlink PIN: ");

// Generate device ID based on seconds since epoch
std::string device_id = std::to_string(
std::chrono::duration_cast<std::chrono::seconds>(
std::chrono::system_clock::now().time_since_epoch()
).count()
);

// Create controller
subarulink::Controller ctrl(
username,
password,
device_id,
generate_device_id(),
pin,
"SubarulinkCpp", // device name
"USA" // country
"SubarulinkCpp", // device name
"USA" // country
);

// Connect - this will handle basic authentication
auto connect_future = ctrl.connect();
if (!connect_future.get()) {
if (!ctrl.connect().get()) {
std::cerr << "Failed to connect" << std::endl;
return 1;
}

// Check if device needs to be registered (2FA required)
if (!ctrl.device_registered()) {
auto methods = ctrl.contact_methods();
if (methods.empty()) {
std::cerr << "No 2FA contact methods available" << std::endl;
return 1;
}

// Display available 2FA methods
std::cout << "\nSelect 2FA method:" << std::endl;
int i = 1;
for (const auto& method : methods) {
std::cout << i++ << ". " << method.second << std::endl;
}

// Get user choice
int choice;
std::cout << "Enter choice (1-" << methods.size() << "): ";
std::cin >> choice;
std::cin.ignore(); // Clear newline

// Get selected method
auto it = methods.begin();
std::advance(it, choice - 1);

// Request code
std::cout << "Requesting authentication code..." << std::endl;
auto request_future = ctrl.request_auth_code(it->first);
if (!request_future.get()) {
std::cerr << "Failed to request authentication code" << std::endl;
return 1;
}

// Get verification code from user
std::cout << "Enter verification code sent to " << it->second << ": ";
std::string code;
std::getline(std::cin, code);

// Submit verification code
std::cout << "Submitting verification code..." << std::endl;
auto verify_future = ctrl.submit_auth_code(code);
if (!verify_future.get()) {
std::cerr << "Failed to verify code" << std::endl;
return 1;
}

std::cout << "Device successfully registered!" << std::endl;
// Handle 2FA if needed
if (!ctrl.device_registered() && !handle_2fa_registration(ctrl)) {
return 1;
}

// Now proceed with getting vehicle information
// Get and display vehicle information
auto vehicles = ctrl.get_vehicles();
std::cout << "\nFound " << vehicles.size() << " vehicles:" << std::endl;

for (const auto& vin : vehicles) {
std::cout << "\nVehicle: " << ctrl.vin_to_name(vin) << std::endl;
std::cout << "Year: " << ctrl.get_model_year(vin) << std::endl;
std::cout << "Model: " << ctrl.get_model_name(vin) << std::endl;

// Get detailed data
auto data_future = ctrl.get_data(vin);
auto vehicle_data = data_future.get();

// Display odometer
try {
auto it = vehicle_data.vehicle_status.find("ODOMETER");
if (it != vehicle_data.vehicle_status.end() && !it->second.is_null()) {
std::cout << "Odometer: " << it->second.get<int>()
<< " miles" << std::endl;
} else {
std::cout << "Odometer data not available" << std::endl;
}
} catch (const std::exception& e) {
std::cout << "Error reading odometer: " << e.what() << std::endl;
}
display_vehicle_info(vin, ctrl);
}

} catch (const std::exception& e) {
Expand All @@ -131,4 +166,4 @@ int main() {
}

return 0;
}
}

0 comments on commit 1a2f677

Please sign in to comment.