mirror of
https://bitbucket.org/myhomie/mycorerepository.git
synced 2025-12-06 09:41:19 +00:00
MerossService Api Http ok, MQTT WIP
This commit is contained in:
parent
0139257a28
commit
1cd7a56d1b
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
34
MyCore/Models/Meross/MerossDevice.cs
Normal file
34
MyCore/Models/Meross/MerossDevice.cs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace MyCore.Models.Meross
|
||||||
|
{
|
||||||
|
public class MerossDevice
|
||||||
|
{
|
||||||
|
public string uuid { get; set; }
|
||||||
|
public int onlineStatus { get; set; }
|
||||||
|
public string devName { get; set; }
|
||||||
|
public string devIconId { get; set; }
|
||||||
|
public long bindTime { get; set; }
|
||||||
|
public string deviceType { get; set; }
|
||||||
|
public string subType { get; set; }
|
||||||
|
public List<Channel> channels { get; set; }
|
||||||
|
public string region { get; set; }
|
||||||
|
public string firmwareVersion { get; set; }
|
||||||
|
public string hdwareVersion { get; set; }
|
||||||
|
public string userDevIcon { get; set; }
|
||||||
|
public int iconType { get; set; }
|
||||||
|
public string skillNumber { get; set; }
|
||||||
|
public string domain { get; set; }
|
||||||
|
public string reservedDomain { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Channel
|
||||||
|
{
|
||||||
|
public string type { get; set; }
|
||||||
|
public string devName { get; set; }
|
||||||
|
public string devIconId { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -17,7 +17,6 @@ namespace MyCore.Services
|
|||||||
{
|
{
|
||||||
public class MQTTService
|
public class MQTTService
|
||||||
{
|
{
|
||||||
|
|
||||||
private IMqttClient _client;
|
private IMqttClient _client;
|
||||||
private IMqttClientOptions _options;
|
private IMqttClientOptions _options;
|
||||||
private string _mqttServer = "192.168.31.140";
|
private string _mqttServer = "192.168.31.140";
|
||||||
@ -112,9 +111,11 @@ namespace MyCore.Services
|
|||||||
|
|
||||||
// If so retrieve the device in database and his Type
|
// If so retrieve the device in database and his Type
|
||||||
|
|
||||||
// Retrieve the object
|
// Retrieve the device as an object (We have a defined list of devices. That's not a problem, it's a choice as we want reliability)
|
||||||
|
|
||||||
// Check in the list of automations if we have something to do with the message
|
// Check in the list of automations if we have something to do with the message (Check in mqtt input section)
|
||||||
|
|
||||||
|
// Automation = id, name,
|
||||||
|
|
||||||
// Load everydevice in cache.. ? Performance ?
|
// Load everydevice in cache.. ? Performance ?
|
||||||
|
|
||||||
|
|||||||
269
MyCore/Services/MerossService.cs
Normal file
269
MyCore/Services/MerossService.cs
Normal file
@ -0,0 +1,269 @@
|
|||||||
|
using MQTTnet;
|
||||||
|
using MQTTnet.Client;
|
||||||
|
using MQTTnet.Client.Options;
|
||||||
|
using MQTTnet.Formatter;
|
||||||
|
using MQTTnet.Implementations;
|
||||||
|
using MyCore.Models.Meross;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace MyCore.Services
|
||||||
|
{
|
||||||
|
public class MerossService
|
||||||
|
{
|
||||||
|
// API HTTP
|
||||||
|
private const string _merossUrl = "https://iot.meross.com";
|
||||||
|
private static string _secret = "23x17ahWarFH6w29";
|
||||||
|
private string _loginUrl = $"{_merossUrl}/v1/Auth/Login";
|
||||||
|
private string _logUrl = $"{_merossUrl}/v1/log/user";
|
||||||
|
private string _devList = $"{_merossUrl}/v1/Device/devList";
|
||||||
|
|
||||||
|
private static string username = "thomas.fransolet@hotmail.be";
|
||||||
|
private static string password = "Coconuts07";
|
||||||
|
|
||||||
|
private static ResultToken resultToken;
|
||||||
|
|
||||||
|
// API MQTT
|
||||||
|
private const int port = 2001;
|
||||||
|
private const string domain = "iot.meross.com";
|
||||||
|
|
||||||
|
private IMqttClient _client;
|
||||||
|
private IMqttClientOptions _options;
|
||||||
|
private string _userMQTT;
|
||||||
|
private string _passwordMQTT;
|
||||||
|
|
||||||
|
public class Credential
|
||||||
|
{
|
||||||
|
public string email;
|
||||||
|
public string password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ResultToken
|
||||||
|
{
|
||||||
|
public string userid;
|
||||||
|
public string email;
|
||||||
|
public string token;
|
||||||
|
public string key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum RequestType
|
||||||
|
{
|
||||||
|
Login,
|
||||||
|
Log,
|
||||||
|
DeviceList
|
||||||
|
}
|
||||||
|
|
||||||
|
public MerossService()
|
||||||
|
{
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var loginTask = Task.Run(() => PostURI(new Uri(_loginUrl), RequestType.Login));
|
||||||
|
loginTask.Wait();
|
||||||
|
|
||||||
|
if (loginTask.Result != "")
|
||||||
|
{
|
||||||
|
var data = ((JObject)JsonConvert.DeserializeObject(loginTask.Result))["data"];
|
||||||
|
resultToken = JsonConvert.DeserializeObject<ResultToken>(data.ToString());
|
||||||
|
|
||||||
|
var deviceTask = Task.Run(() => PostURI(new Uri(_devList), RequestType.DeviceList));
|
||||||
|
deviceTask.Wait();
|
||||||
|
|
||||||
|
if (deviceTask.Result != "")
|
||||||
|
{
|
||||||
|
data = ((JObject)JsonConvert.DeserializeObject(deviceTask.Result))["data"];
|
||||||
|
var test = JsonConvert.DeserializeObject<List<MerossDevice>>(data.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
var logTask = Task.Run(() => PostURI(new Uri(_logUrl), RequestType.Log));
|
||||||
|
logTask.Wait();
|
||||||
|
|
||||||
|
if (logTask.Result != "")
|
||||||
|
{
|
||||||
|
data = ((JObject)JsonConvert.DeserializeObject(logTask.Result))["data"];
|
||||||
|
}
|
||||||
|
|
||||||
|
//MQTT CONNEXION
|
||||||
|
ConnexionToMqtt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
resultToken = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static async Task<string> PostURI(Uri u, RequestType requestType)
|
||||||
|
{
|
||||||
|
var response = string.Empty;
|
||||||
|
var requestParam = "";
|
||||||
|
string nonce = GenerateNonce(16).ToUpper();
|
||||||
|
var timeStamp = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds();
|
||||||
|
|
||||||
|
switch (requestType)
|
||||||
|
{
|
||||||
|
case RequestType.Login:
|
||||||
|
requestParam = Base64Encode(JsonConvert.SerializeObject(new Credential { email = username, password = password }).ToString());
|
||||||
|
break;
|
||||||
|
case RequestType.Log:
|
||||||
|
requestParam = Base64Encode("{'extra': { }, 'model': 'Android,Android SDK built for x86_64', 'system': 'Android','uuid': '493dd9174941ed58waitForOpenWifi', 'vendor': 'Meross', 'version': '6.0'}");
|
||||||
|
break;
|
||||||
|
case RequestType.DeviceList:
|
||||||
|
requestParam = "e30=";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
string stringForMD5 = stringForMD5 = _secret + timeStamp.ToString() + nonce + requestParam;
|
||||||
|
string md5 = CreateMD5(stringForMD5);
|
||||||
|
|
||||||
|
var payloadLogin = "{ \"params\":\"" + requestParam + "\",\"sign\":\"" + md5.ToLower() + "\",\"timestamp\":" + timeStamp + ",\"nonce\":\"" + nonce + "\"}";
|
||||||
|
using (var client = new HttpClient())
|
||||||
|
{
|
||||||
|
HttpContent c = new StringContent(payloadLogin, Encoding.UTF8, "application/json");
|
||||||
|
if (resultToken != null)
|
||||||
|
{
|
||||||
|
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", resultToken.token);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic");
|
||||||
|
}
|
||||||
|
|
||||||
|
client.DefaultRequestHeaders.Add("vender", "Meross");
|
||||||
|
client.DefaultRequestHeaders.Add("AppVersion", "1.3.0");
|
||||||
|
client.DefaultRequestHeaders.Add("AppLanguage", "EN");
|
||||||
|
client.DefaultRequestHeaders.Add("User-Agent", "okhttp/3.6.0");
|
||||||
|
|
||||||
|
HttpResponseMessage result = await client.PostAsync(u, c);
|
||||||
|
if (result.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
response = await result.Content.ReadAsStringAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string Base64Encode(string plainText)
|
||||||
|
{
|
||||||
|
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
|
||||||
|
return System.Convert.ToBase64String(plainTextBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string CreateMD5(string input)
|
||||||
|
{
|
||||||
|
// Use input string to calculate MD5 hash
|
||||||
|
using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create())
|
||||||
|
{
|
||||||
|
byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
|
||||||
|
byte[] hashBytes = md5.ComputeHash(inputBytes);
|
||||||
|
|
||||||
|
// Convert the byte array to hexadecimal string
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (int i = 0; i < hashBytes.Length; i++)
|
||||||
|
{
|
||||||
|
sb.Append(hashBytes[i].ToString("X2"));
|
||||||
|
}
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string validChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||||
|
private static Random random = new Random();
|
||||||
|
|
||||||
|
private static string GenerateNonce(int length)
|
||||||
|
{
|
||||||
|
var nonceString = new StringBuilder();
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
nonceString.Append(validChars[random.Next(0, validChars.Length - 1)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nonceString.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ConnexionToMqtt()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Create a new MQTT client.
|
||||||
|
_client = new MqttFactory().CreateMqttClient();
|
||||||
|
|
||||||
|
string stringForMD5 = resultToken.userid + resultToken.key;
|
||||||
|
string hashed_password = CreateMD5(stringForMD5);
|
||||||
|
|
||||||
|
MqttClientOptionsBuilderTlsParameters tlsParameters = new MqttClientOptionsBuilderTlsParameters();
|
||||||
|
tlsParameters.UseTls = true;
|
||||||
|
tlsParameters.SslProtocol = System.Security.Authentication.SslProtocols.Tls;
|
||||||
|
|
||||||
|
_options = new MqttClientOptionsBuilder()
|
||||||
|
.WithClientId("app: 08d4c9f99da40203ebc798a79512ec14")
|
||||||
|
.WithTcpServer(domain, port)
|
||||||
|
.WithCredentials(resultToken.userid, hashed_password)
|
||||||
|
.WithTls(tlsParameters)
|
||||||
|
.WithProtocolVersion(MqttProtocolVersion.V311)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
|
||||||
|
_client.ConnectAsync(_options, CancellationToken.None).ContinueWith(res => {
|
||||||
|
if (res.Status == TaskStatus.RanToCompletion)
|
||||||
|
{
|
||||||
|
Console.WriteLine("It's connected");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Error connecting to {domain}");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
_client.UseDisconnectedHandler(async e =>
|
||||||
|
{
|
||||||
|
Console.WriteLine("### DISCONNECTED FROM SERVER ###");
|
||||||
|
await Task.Delay(TimeSpan.FromSeconds(5));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _client.ConnectAsync(_options, CancellationToken.None); // Since 3.0.5 with CancellationToken
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Console.WriteLine("### RECONNECTING FAILED ###");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
_client.UseConnectedHandler(async e =>
|
||||||
|
{
|
||||||
|
Console.WriteLine("### CONNECTED WITH SERVER ###");
|
||||||
|
|
||||||
|
// Subscribe to a topic
|
||||||
|
await _client.SubscribeAsync(new TopicFilterBuilder().WithTopic("#").Build());
|
||||||
|
|
||||||
|
Console.WriteLine("### SUBSCRIBED ###");
|
||||||
|
});
|
||||||
|
|
||||||
|
_client.UseApplicationMessageReceivedHandler(e =>
|
||||||
|
{
|
||||||
|
Console.WriteLine("### RECEIVED APPLICATION MESSAGE ###");
|
||||||
|
Console.WriteLine($"+ Topic = {e.ApplicationMessage.Topic}");
|
||||||
|
Console.WriteLine($"+ Payload = {Encoding.UTF8.GetString(e.ApplicationMessage.Payload)}");
|
||||||
|
Console.WriteLine($"+ QoS = {e.ApplicationMessage.QualityOfServiceLevel}");
|
||||||
|
Console.WriteLine($"+ Retain = {e.ApplicationMessage.Retain}");
|
||||||
|
Console.WriteLine();
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -26,7 +26,9 @@ namespace MyCore
|
|||||||
{
|
{
|
||||||
Configuration = configuration;
|
Configuration = configuration;
|
||||||
|
|
||||||
MQTTService mQTTService = new MQTTService();
|
//MQTTService mQTTService = new MQTTService();
|
||||||
|
|
||||||
|
MerossService merossService = new MerossService();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IConfiguration Configuration { get; }
|
public IConfiguration Configuration { get; }
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user