ArloService - Login, Get Devices, Get Library + SSE WIP (Connection working but no event recorded)

This commit is contained in:
Thomas Fransolet 2020-02-07 22:24:16 +01:00
parent 9a1fc65a13
commit 98041c07a3
7 changed files with 323 additions and 3 deletions

View File

@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace MyCore.Models.Arlo
{
public class ArloDevice
{
public string userId { get; set; }
public string deviceId { get; set; }
public string parentId { get; set; }
public string uniqueId { get; set; }
public string deviceType { get; set; }
public string deviceName { get; set; }
public string xCloudId { get; set; }
public string userRole { get; set; }
public int displayOrder { get; set; }
public string state { get; set; }
public string modelId { get; set; }
public bool cvrEnabled { get; set; }
public long dateCreated { get; set; }
public string skillNumber { get; set; }
public Owner owner { get; set; }
//Camera Specific
public string lastImageUploaded { get; set; }
public string presignedLastImageUrl { get; set; }
public string presignedSnapshotUrl { get; set; }
public string presignedFullFrameSnapshotUrl { get; set; }
public int mediaObjectCount { get; set; }
public bool arloMobilePlan { get; set; }
public string interfaceVersion { get; set; }
public string interfaceSchemaVer { get; set; }
public Properties properties { get; set; }
//Base Station Specific
public Connectivity connectivity { get; set; }
public string certAvailable { get; set; }
public int automationRevision { get; set; }
public bool migrateActivityZone { get; set; }
}
public class Owner
{
public string firstName { get; set; }
public string lastName { get; set; }
public string ownerId { get; set; }
}
public class Properties
{
public string modelId { get; set; }
public string olsonTimeZone { get; set; }
public string hwVersion { get; set; }
}
public class Connectivity
{
public string type { get; set; }
public bool connected { get; set; }
public string mepStatus { get; set; }
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace MyCore.Models.Arlo
{
public class UserLocation
{
// TODO
}
}

View File

@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace MyCore.Models.Arlo
{
public class UserMedia
{
public string ownerId { get; set; }
public string uniqueId { get; set; }
public string deviceId { get; set; }
public string createdDate { get; set; }
public string currentState { get; set; }
public string name { get; set; }
public string contentType { get; set; }
public string reason { get; set; }
public string createdBy { get; set; }
public long lastModified { get; set; }
public long localCreatedDate { get; set; }
public string presignedContentUrl { get; set; }
public string presignedThumbnailUrl { get; set; }
public long utcCreatedDate { get; set; }
public string timeZone { get; set; }
public string mediaDuration { get; set; }
public Meta meta { get; set; }
public int mediaDurationSecond { get; set; }
public bool donated { get; set; }
}
public class Meta
{
public string bit_rate { get; set; }
public string width { get; set; }
public string codec_tag_string { get; set; }
public string height { get; set; }
}
}

View File

@ -16,6 +16,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="3v.EvtSource" Version="2.0.0" />
<PackageReference Include="AspNetCore.Security.Jwt" Version="1.6.0" /> <PackageReference Include="AspNetCore.Security.Jwt" Version="1.6.0" />
<PackageReference Include="Microsoft.AspNetCore.App" /> <PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="2.1.2" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="2.1.2" />
@ -24,6 +25,7 @@
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.1.1" /> <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.1.1" />
<PackageReference Include="MongoDB.Driver" Version="2.8.0" /> <PackageReference Include="MongoDB.Driver" Version="2.8.0" />
<PackageReference Include="MQTTnet" Version="3.0.8" /> <PackageReference Include="MQTTnet" Version="3.0.8" />
<PackageReference Include="ServiceStack.Client" Version="5.8.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="4.0.1" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="4.0.1" />
<PackageReference Include="YeelightAPI" Version="1.7.0" /> <PackageReference Include="YeelightAPI" Version="1.7.0" />
</ItemGroup> </ItemGroup>

View File

@ -1,11 +1,208 @@
using System; using EvtSource;
using MyCore.Models.Arlo;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using ServiceStack;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace MyCore.Services namespace MyCore.Services
{ {
public class ArloService public class ArloService
{ {
// API HTTP
private const string _arloUrl = "https://arlo.netgear.com/hmsweb";
private string _loginUrl = $"{_arloUrl}/login/v2";
private string _userProfileUrl = $"{_arloUrl}/users/profile";
private string _userSessionUrl = $"{_arloUrl}/users/session";
private string _userFriendsUrl = $"{_arloUrl}/users/friends";
private string _userLocationUrl = $"{_arloUrl}/users/locations";
private string _userServiceLevelUrl = $"{_arloUrl}/users/serviceLevel/v2";
private string _userDevicesUrl = $"{_arloUrl}/users/devices";
private string _userLibraryUrl = $"{_arloUrl}/users/library";
private string _userLibraryMetadataUrl = $"{_arloUrl}/users/library/metadata/v2";
private string _userPaymentOffersUrl = $"{_arloUrl}/users/payment/offers";
private string _userDevicesNotifyUrl = $"{_arloUrl}/users/devices/notify";
private string _clientSubscribeUrl = $"{_arloUrl}/client/subscribe";
private static string _email = "fransolet.thomas@gmail.com";
private static string _password = "Coconuts09";
private static LoginResult resultToken;
private List<ArloDevice> allArloDevices;
private List<UserMedia> allUserMedias;
public class Credential
{
public string email;
public string password;
}
public class DateInterval
{
public string dateFrom;
public string dateTo;
}
public class LoginResult
{
public string userId;
public string email;
public string token;
public string paymentId;
public int authenticated;
public string accountStatus;
public string serialNumber;
public string countryCode;
public bool tocUpdate;
public bool policyUpdate;
public bool validEmail;
public bool arlo;
public long dateCreated;
}
public enum RequestType
{
Get,
Post
}
public enum Request
{
LOGIN,
DEVICES,
LIBRARY
}
public ArloService()
{
try
{
// LOGIN
var loginTask = Task.Run(() => RequestURI(new Uri(_loginUrl), RequestType.Post, Request.LOGIN));
loginTask.Wait();
if (loginTask.Result != "")
{
//RESULT TOKEN
var data = ((JObject)JsonConvert.DeserializeObject(loginTask.Result))["data"];
resultToken = JsonConvert.DeserializeObject<LoginResult>(data.ToString());
// GET DEVICE LIST
var deviceTask = Task.Run(() => RequestURI(new Uri(_userDevicesUrl), RequestType.Get, Request.DEVICES));
deviceTask.Wait();
if (deviceTask.Result != "")
{
data = ((JObject)JsonConvert.DeserializeObject(deviceTask.Result))["data"];
// RETRIEVE ALL ARLO DEVICES
allArloDevices = JsonConvert.DeserializeObject<List<ArloDevice>>(data.ToString());
}
// GET USER LIBRARY
var libraryTask = Task.Run(() => RequestURI(new Uri(_userLibraryUrl), RequestType.Post, Request.LIBRARY));
libraryTask.Wait();
if (libraryTask.Result != "")
{
data = ((JObject)JsonConvert.DeserializeObject(libraryTask.Result))["data"];
// RETRIEVE ALL DATA IN USER LIBRARY
allUserMedias = JsonConvert.DeserializeObject<List<UserMedia>>(data.ToString());
}
//SSE CONNEXION
ConnexionToSSE();
}
}
catch (Exception e)
{
resultToken = null;
}
}
static async Task<string> RequestURI(Uri u, RequestType requesType, Request request)
{
try
{
var response = string.Empty;
var body = "";
HttpContent c = null;
using (var client = new HttpClient())
{
switch (request)
{
case Request.LOGIN:
body = JsonConvert.SerializeObject(new Credential { email = _email, password = _password }).ToString();
c = new StringContent(body, Encoding.UTF8, "application/json");
break;
case Request.LIBRARY:
DateTime last7Days = new DateTime(DateTime.Now.Year, 1, 1).AddDays(DateTime.Now.DayOfYear - 7 - 1);
body = JsonConvert.SerializeObject(new DateInterval { dateFrom = last7Days.ToString("yyyyMMdd"), dateTo = DateTime.Now.ToString("yyyyMMdd")}).ToString();
c = new StringContent(body, Encoding.UTF8, "application/json");
break;
case Request.DEVICES:
default:
break;
}
client.DefaultRequestHeaders.Add("User-Agent", "okhttp/3.6.0");
if (resultToken != null)
client.DefaultRequestHeaders.Add("Authorization", resultToken.token);
if (requesType == RequestType.Get)
{
HttpResponseMessage result = await client.GetAsync(u);
response = await result.Content.ReadAsStringAsync();
}
if (requesType == RequestType.Post)
{
HttpResponseMessage result = await client.PostAsync(u, c);
if (result.IsSuccessStatusCode)
response = await result.Content.ReadAsStringAsync();
}
}
return response;
}
catch (Exception e)
{
Console.WriteLine("ArloService - An error occured in RequestURI");
return null;
}
}
public void ConnexionToSSE()
{
/*var sseClient = new ServerEventsClient($"{_clientSubscribeUrl}?token={resultToken.token}", new string[] { "EventStream" })
{
OnConnect = e => {
Console.WriteLine($"{e.IsAuthenticated}, {e.UserId}, {e.DisplayName}");
}
}.Start();*/
var evt = new EventSourceReader(new Uri($"{_clientSubscribeUrl}?token={resultToken.token}")).Start();
evt.MessageReceived +=
(object sender, EventSourceMessageEventArgs e)
=>
Console.WriteLine($"{e.Event} : {e.Message}");
evt.Disconnected += async (object sender, DisconnectEventArgs e) => {
Console.WriteLine($"Retry: {e.ReconnectDelay} - Error: {e.Exception}");
await Task.Delay(e.ReconnectDelay);
evt.Start(); // Reconnect to the same URL
};
}
} }
} }

View File

@ -197,6 +197,9 @@ namespace MyCore.Services
return nonceString.ToString(); return nonceString.ToString();
} }
#region MQTT
public class RequestMQTT public class RequestMQTT
{ {
public HeaderMqtt header; public HeaderMqtt header;
@ -500,5 +503,6 @@ namespace MyCore.Services
if (_client.IsConnected) if (_client.IsConnected)
_client.PublishAsync(mqttMessage); _client.PublishAsync(mqttMessage);
} }
#endregion
} }
} }

View File

@ -28,7 +28,9 @@ namespace MyCore
//MQTTService mQTTService = new MQTTService(); //MQTTService mQTTService = new MQTTService();
MerossService merossService = new MerossService(); //MerossService merossService = new MerossService();
ArloService arloService = new ArloService();
} }
public IConfiguration Configuration { get; } public IConfiguration Configuration { get; }