You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
245 lines
9.5 KiB
245 lines
9.5 KiB
using Infrastructure.Application.Services.Settings;
|
|
using Infrastructure.Data;
|
|
using Infrastructure.Extensions;
|
|
using IoT.Shared.Services;
|
|
using Application.Domain.Entities;
|
|
using IoT.Shared.Application.Models;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Hosting;
|
|
using System;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Hosting;
|
|
using System.Net.Http;
|
|
using Microsoft.Extensions.Logging;
|
|
using System.ComponentModel.DataAnnotations;
|
|
using NJsonSchema;
|
|
using System.Globalization;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Infrastructure.Events;
|
|
|
|
namespace IoTNode.DeviceServices
|
|
{
|
|
public class BaseDeviceService : IHostedService
|
|
{
|
|
internal readonly IServiceProvider _applicationServices;
|
|
protected readonly IWebHostEnvironment _env;
|
|
|
|
public BaseDeviceService(IServiceProvider applicationServices, IWebHostEnvironment env)
|
|
{
|
|
this._applicationServices = applicationServices;
|
|
this._env = env;
|
|
}
|
|
|
|
protected string GetSetting(string name)
|
|
{
|
|
using var scope = _applicationServices.CreateScope();
|
|
return scope.ServiceProvider.GetRequiredService<ISettingService>().GetSetting(name).Value;
|
|
}
|
|
|
|
public virtual Task StartAsync(CancellationToken cancellationToken)
|
|
{
|
|
Task.Run(async () =>
|
|
{
|
|
while (!cancellationToken.IsCancellationRequested)
|
|
{
|
|
try
|
|
{
|
|
Execute();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ex.PrintStack();
|
|
}
|
|
await Task.Delay(Convert.ToInt32(GetSetting("timer.seconds")) * 1000).ConfigureAwait(true);
|
|
}
|
|
});
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public virtual void Execute()
|
|
{
|
|
}
|
|
|
|
public virtual Task StopAsync(CancellationToken cancellationToken)
|
|
{
|
|
return Task.CompletedTask;
|
|
}
|
|
public IoTProduct UpdateProduct(string productName, string productNumber, string path, string productIcon)
|
|
{
|
|
var scope = _applicationServices.CreateScope();
|
|
//
|
|
var productRepo = scope.ServiceProvider.GetService<IRepository<IoTProduct>>();
|
|
var product = productRepo.ReadOnlyTable().FirstOrDefault(o => o.Number == productNumber);
|
|
if (product == null)
|
|
{
|
|
product = new IoTProduct
|
|
{
|
|
Id = $"productid-{productNumber}".ToGuid(),
|
|
Number = productNumber,
|
|
Name = productName,
|
|
Path = path,
|
|
Image = $"/images/{productIcon}.svg"
|
|
};
|
|
if (!string.IsNullOrEmpty(path))
|
|
{
|
|
var iotNodeClient = scope.ServiceProvider.GetService<IoTNodeClient>();
|
|
product.ApiJson = iotNodeClient.GetApiJson(path);
|
|
//OpenApiService.UpdateApi(product);
|
|
}
|
|
productRepo.Add(product);
|
|
productRepo.SaveChanges();
|
|
}
|
|
//
|
|
if (this.GetSetting("notify:enabled") == "true")
|
|
{
|
|
try
|
|
{
|
|
var settingRepo = scope.ServiceProvider.GetRequiredService<ISettingService>();
|
|
var factory = scope.ServiceProvider.GetRequiredService<IHttpClientFactory>();
|
|
var notifyHost = settingRepo.GetValue("notify:host");
|
|
var url = $"{notifyHost}/Server/HasProduct/{productNumber}";
|
|
var httpClient = factory.CreateClient();
|
|
var response = httpClient.GetStringAsync(url).Result.FromJson<bool>();
|
|
if (!response)
|
|
{
|
|
scope.ServiceProvider.GetRequiredService<IoTNodeClient>().ClientToServer($"{nameof(IoTProduct)}{nameof(EntityUpdated<IoTProduct>)}", product, null);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ex.PrintStack();
|
|
scope.ServiceProvider.GetRequiredService<ILogger<BaseDeviceService>>().LogError(ex.ToString());
|
|
}
|
|
|
|
}
|
|
return product;
|
|
}
|
|
|
|
public void DeleteDevice(Guid id)
|
|
{
|
|
using var scope = _applicationServices.CreateScope();
|
|
var repo = scope.ServiceProvider.GetRequiredService<IRepository<IoTDevice>>();
|
|
var entity = repo.Table().FirstOrDefault(o => o.Id == id);
|
|
if(entity != null)
|
|
{
|
|
repo.Delete(entity);
|
|
repo.SaveChanges();
|
|
}
|
|
}
|
|
public Guid? GetIoTDeviceId(string number)
|
|
{
|
|
using var scope = _applicationServices.CreateScope();
|
|
var repo = scope.ServiceProvider.GetRequiredService<IRepository<IoTDevice>>();
|
|
return repo.ReadOnlyTable()
|
|
.Where(o => o.Number == number)
|
|
.Select(o => o.Id)
|
|
.FirstOrDefault();
|
|
}
|
|
public IoTDevice GetIoTDevice(string number)
|
|
{
|
|
using var scope = _applicationServices.CreateScope();
|
|
var repo = scope.ServiceProvider.GetRequiredService<IRepository<IoTDevice>>();
|
|
return repo.ReadOnlyTable().FirstOrDefault(o => o.Number == number);
|
|
}
|
|
|
|
public string GetIoTDataValue(Guid deviceId, DataKeys key)
|
|
{
|
|
using var scope = _applicationServices.CreateScope();
|
|
var repo = scope.ServiceProvider.GetRequiredService<IRepository<IoTData>>();
|
|
var name = key.GetName();
|
|
return repo.ReadOnlyTable()
|
|
.Where(o => o.IoTDeviceId == deviceId && o.Key == name)
|
|
.Select(o=>o.Value)
|
|
.FirstOrDefault();
|
|
}
|
|
public void AddIoTData(Guid deviceId, DataKeys key, object value, string description = "")
|
|
{
|
|
using var scope = _applicationServices.CreateScope();
|
|
var repo = scope.ServiceProvider.GetRequiredService<IRepository<IoTData>>();
|
|
var name = key.GetName();
|
|
var data = repo.Table().FirstOrDefault(o => o.IoTDeviceId == deviceId && o.Key == name);
|
|
if (data == null)
|
|
{
|
|
data = this.CreateIoTData(deviceId, key, value, description);
|
|
repo.Add(data);
|
|
this.UpdateIoTDataValue(data, value);
|
|
repo.SaveChanges();
|
|
}
|
|
}
|
|
|
|
public void UpdateIoTData(Guid deviceId, DataKeys key, object value, string description = "")
|
|
{
|
|
using var scope = _applicationServices.CreateScope();
|
|
var repo = scope.ServiceProvider.GetRequiredService<IRepository<IoTData>>();
|
|
var name = key.GetName();
|
|
var data = repo.Table().FirstOrDefault(o => o.IoTDeviceId == deviceId && o.Key == name);
|
|
if (data == null)
|
|
{
|
|
data = this.CreateIoTData(deviceId, key, value, description);
|
|
repo.Add(data);
|
|
}
|
|
else
|
|
{
|
|
var model = this.CreateIoTData(deviceId, key, value, description);
|
|
data.FromDto(model);
|
|
}
|
|
this.UpdateIoTDataValue(data, value);
|
|
repo.SaveChanges();
|
|
}
|
|
|
|
private void UpdateIoTDataValue(IoTData data,object value)
|
|
{
|
|
if (data.ValueType == IoTValueType.Int)
|
|
{
|
|
data.IntValue = Convert.ToInt32(value);
|
|
data.Value = data.IntValue.ToString();
|
|
}
|
|
else if (data.ValueType == IoTValueType.Double)
|
|
{
|
|
data.DoubleValue = Convert.ToDouble(value);
|
|
data.Value = data.DoubleValue.Value.ToString("f2");
|
|
}
|
|
else if (data.ValueType == IoTValueType.DateTime)
|
|
{
|
|
var timestamp = Convert.ToInt64(value, CultureInfo.InvariantCulture);
|
|
data.DateTimeValue = DateTimeOffset.FromUnixTimeMilliseconds(timestamp).DateTime;
|
|
data.Value = Convert.ToString(value);
|
|
}
|
|
else if (data.ValueType == IoTValueType.Object)
|
|
{
|
|
data.Value = value.ToJson();
|
|
data.ValueSchema = JsonSchema.FromType(value.GetType()).ToJson();
|
|
}
|
|
else if (data.ValueType == IoTValueType.Array)
|
|
{
|
|
data.Value = value.ToJson();
|
|
data.ValueSchema = JsonSchema.FromType(value.GetType().GetGenericArguments().First()).ToJson();
|
|
}
|
|
else
|
|
{
|
|
data.Value = Convert.ToString(value);
|
|
}
|
|
}
|
|
private IoTData CreateIoTData(Guid deviceId, DataKeys key, object value, string description = "")
|
|
{
|
|
var config = key.GetAttribute<IoTDataConfigAttribute>() ?? new IoTDataConfigAttribute();
|
|
var data = new IoTData
|
|
{
|
|
IoTDeviceId = deviceId,
|
|
Key = key.GetName(),
|
|
DataType = config.PropType,
|
|
ValueType = config.ValueType,
|
|
Name = key.GetDisplayName(),
|
|
Unit = config.Unit,
|
|
Description = description,
|
|
EnumValues = config.GetEnumValues(),
|
|
Timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds()
|
|
};
|
|
return data;
|
|
}
|
|
}
|
|
}
|