Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions TeslaLogger/Geofence.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Runtime.CompilerServices;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Exceptionless;
using HttpMultipartParser;

namespace TeslaLogger
{
Expand Down Expand Up @@ -577,5 +579,61 @@ public static double GetDistance(double longitude, double latitude, double other
return 6376500.0 * (2.0 * Math.Atan2(Math.Sqrt(d3), Math.Sqrt(1.0 - d3)));
}

[MethodImpl(MethodImplOptions.Synchronized)]
internal void OnlineUpdate()
{
Tools.DebugLog("Geofence.OnlineUpdate");
string lastETag = null;
if (KVS.Get("Geofence.OnlineUpdate.ETag", out string etag) == KVS.SUCCESS)
{
lastETag = etag;
}
HttpClient client = new HttpClient();
string url = "https://raw.githubusercontent.com/bassmaster187/TeslaLogger/master/TeslaLogger/bin/geofence.csv";
using (var request = new HttpRequestMessage(HttpMethod.Get, url))
{
if (lastETag != null)
{
request.Headers.TryAddWithoutValidation("If-None-Match", lastETag);
}
var response = client.SendAsync(request).Result;
if (response.StatusCode == System.Net.HttpStatusCode.NotModified)
{
Logfile.Log($"Geofence.OnlineUpdate: no changes (ETag: {lastETag})");
}
else if (response.IsSuccessStatusCode)
{
if (response.Headers.ETag != null)
{
lastETag = response.Headers.ETag.Tag;
KVS.InsertOrUpdate("Geofence.OnlineUpdate.ETag", lastETag);
}
Logfile.Log($"Geofence.OnlineUpdate: update! (ETag: {lastETag})");
using (Stream stream = response.Content.ReadAsStreamAsync().Result)
{
using (FileStream fs = new FileStream(FileManager.GetFilePath(TLFilename.GeofenceFilename) + ".updated", FileMode.Create, FileAccess.Write, FileShare.None, 8192, useAsync: false))
{
byte[] buffer = new byte[8192];
int bytesRead;

while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
{
fs.Write(buffer, 0, bytesRead);
}
}
}
Tools.DebugLog($"Geofence.updated: {new FileInfo(FileManager.GetFilePath(TLFilename.GeofenceFilename) + ".updated").Length} bytes");
if (new FileInfo(FileManager.GetFilePath(TLFilename.GeofenceFilename) + ".updated").Length > 0)
{
Tools.CopyFile(FileManager.GetFilePath(TLFilename.GeofenceFilename) + ".updated", FileManager.GetFilePath(TLFilename.GeofenceFilename));
}
}
else
{
Logfile.Log($"Geofence.OnlineUpdate: error: {response.StatusCode}");
}
}
}

}
}
107 changes: 50 additions & 57 deletions TeslaLogger/NearbySuCService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -476,80 +476,73 @@ Available GetGuestAvailability(Car car, int trid)
{
Available a = new Available();

string content = "{\"operationName\":\"GetSiteDetails\",\"query\":\"\\n query GetSiteDetails($siteId: SiteIdInput!) {\\n chargingNetwork {\\n site(siteId: $siteId) {\\n address {\\n countryCode\\n }\\n chargerList {\\n id\\n label\\n availability\\n }\\n holdAmount {\\n amount\\n currencyCode\\n }\\n maxPowerKw\\n name\\n programType\\n publicStallCount\\n trtId\\n pricing {\\n userRates {\\n activePricebook {\\n charging {\\n ...ChargingRate\\n }\\n parking {\\n ...ChargingRate\\n }\\n congestion {\\n ...ChargingRate\\n }\\n }\\n }\\n }\\n }\\n }\\n}\\n \\n fragment ChargingRate on ChargingUserRate {\\n uom\\n rates\\n buckets {\\n start\\n end\\n }\\n bucketUom\\n currencyCode\\n programType\\n vehicleMakeType\\n touRates {\\n enabled\\n activeRatesByTime {\\n startTime\\n endTime\\n rates\\n }\\n }\\n}\\n \",\"variables\":{\"siteId\":{\"byTrtId\":{\"trtId\":$SITEID$,\"programType\":\"PTSCH\",\"chargingExperience\":\"ADHOC\",\"locale\":\"en-US\"}}}}";
content = content.Replace("$SITEID$", trid.ToString());
string payload = "{\"operationName\":\"GetSiteDetails\",\"query\":\"\\n query GetSiteDetails($siteId: SiteIdInput!) {\\n chargingNetwork {\\n site(siteId: $siteId) {\\n address {\\n countryCode\\n }\\n chargerList {\\n id\\n label\\n availability\\n }\\n holdAmount {\\n amount\\n currencyCode\\n }\\n maxPowerKw\\n name\\n programType\\n publicStallCount\\n trtId\\n pricing {\\n userRates {\\n activePricebook {\\n charging {\\n ...ChargingRate\\n }\\n parking {\\n ...ChargingRate\\n }\\n congestion {\\n ...ChargingRate\\n }\\n }\\n }\\n }\\n }\\n }\\n}\\n \\n fragment ChargingRate on ChargingUserRate {\\n uom\\n rates\\n buckets {\\n start\\n end\\n }\\n bucketUom\\n currencyCode\\n programType\\n vehicleMakeType\\n touRates {\\n enabled\\n activeRatesByTime {\\n startTime\\n endTime\\n rates\\n }\\n }\\n}\\n \",\"variables\":{\"siteId\":{\"byTrtId\":{\"trtId\":$SITEID$,\"programType\":\"PTSCH\",\"chargingExperience\":\"ADHOC\",\"locale\":\"en-US\"}}}}";
payload = payload.Replace("$SITEID$", trid.ToString());

var client = TeslaGuestHttpClient();

using (var request = new HttpRequestMessage())
{
using (var scontent = new StringContent(content, Encoding.UTF8, "application/json"))
using (var scontent = new StringContent(payload, Encoding.UTF8, "application/json"))
{
string r = "";
try
{
var result = client.PostAsync("https://www.tesla.com/charging/guest/api/graphql?operationName=GetSiteDetails", scontent).Result;
r = result.Content.ReadAsStringAsync().Result;
}
catch (Exception ex)
var response = client.PostAsync("https://www.tesla.com/charging/guest/api/graphql?operationName=GetSiteDetails", scontent).Result;
string content = response.Content.ReadAsStringAsync().Result;
if (response.IsSuccessStatusCode)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
throw;
}

dynamic j = JsonConvert.DeserializeObject(r);
if (j?["data"] == null || j["errors"] != null)
{
Tools.DebugLog($"Unexpected GuestAPI response: {r}");
return a;
}
dynamic j = JsonConvert.DeserializeObject(content);
if (j?["data"] == null || j["errors"] != null)
{
Tools.DebugLog($"Unexpected GuestAPI response: {content}");
return a;
}

dynamic site = j["data"]["chargingNetwork"]["site"];
JArray chargers = site["chargerList"];
//JArray chargerDetails = site["chargersAvailable"]["chargerDetails"];
dynamic site = j["data"]["chargingNetwork"]["site"];
JArray chargers = site["chargerList"];
//JArray chargerDetails = site["chargersAvailable"]["chargerDetails"];

string name = site["name"];
string name = site["name"];

a.total = chargers.Count;
a.total = chargers.Count;

foreach (dynamic charger in chargers)
{
string id = charger["id"];
string label = charger["label"];
foreach (dynamic charger in chargers)
{
string id = charger["id"];
string label = charger["label"];


string availability = charger["availability"];
// System.Diagnostics.Debug.WriteLine($"Label: {label} availability: {availability}");
string availability = charger["availability"];
// System.Diagnostics.Debug.WriteLine($"Label: {label} availability: {availability}");

if (availability == "CHARGER_AVAILABILITY_AVAILABLE")
a.available++;
else if (availability == "CHARGER_AVAILABILITY_OCCUPIED")
a.occupied++;
else if (availability == "CHARGER_AVAILABILITY_DOWN")
a.down++;
else if (availability == "CHARGER_AVAILABILITY_UNKNOWN")
a.unknown++;
else
a.unhandled++;
if (availability == "CHARGER_AVAILABILITY_AVAILABLE")
a.available++;
else if (availability == "CHARGER_AVAILABILITY_OCCUPIED")
a.occupied++;
else if (availability == "CHARGER_AVAILABILITY_DOWN")
a.down++;
else if (availability == "CHARGER_AVAILABILITY_UNKNOWN")
a.unknown++;
else
a.unhandled++;

}
}

if (!string.IsNullOrEmpty(name))
{
Tools.DebugLog($"#{car.CarInDB} Guest SuC: <{name}> <{a.available}> <{a.total}>");
if (!string.IsNullOrEmpty(name))
{
Tools.DebugLog($"#{car.CarInDB} Guest SuC: <{name}> <{a.available}> <{a.total}>");

ArrayList send = new ArrayList();
Dictionary<string, object> sendKV = new Dictionary<string, object>();
send.Add(sendKV);
sendKV.Add("n", name);
// sendKV.Add("lat", lat);
// sendKV.Add("lng", lng);
sendKV.Add("ts", DateTime.UtcNow.ToString("s", Tools.ciEnUS));
sendKV.Add("a", a.available);
sendKV.Add("t", a.total);
sendKV.Add("kw", 0);
sendKV.Add("m", "");
ShareSuc(send, false, out _, out _);
ArrayList send = new ArrayList();
Dictionary<string, object> sendKV = new Dictionary<string, object>();
send.Add(sendKV);
sendKV.Add("n", name);
// sendKV.Add("lat", lat);
// sendKV.Add("lng", lng);
sendKV.Add("ts", DateTime.UtcNow.ToString("s", Tools.ciEnUS));
sendKV.Add("a", a.available);
sendKV.Add("t", a.total);
sendKV.Add("kw", 0);
sendKV.Add("m", "");
ShareSuc(send, false, out _, out _);
}
}
}
}
Expand Down
20 changes: 20 additions & 0 deletions TeslaLogger/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ private static void Main(string[] _)
GetAllCars();

InitNearbySuCService();

OnlineUpdateGeofenceInBackground();
}
catch (Exception ex)
{
Expand Down Expand Up @@ -597,6 +599,24 @@ internal static void RunHousekeepingInBackground()
Housekeeper.Start();
}

internal static void OnlineUpdateGeofenceInBackground()
{
Thread GeofenceOnlineUpdater = new Thread(() =>
{
// initially sleep 5min
Thread.Sleep(300000); // 5min
while (true)
{
Geofence.GetInstance().OnlineUpdate();
Thread.Sleep(86400000); // 24h
}
})
{
Priority = ThreadPriority.BelowNormal
};
GeofenceOnlineUpdater.Start();
}

private static void ExitTeslaLogger(string _msg, int _exitcode = 0)
{
Logfile.Log("Exit: " + _msg);
Expand Down
Loading