using Yuna.Website.Server.Storage; using Yuna.Website.Server.Model; using Yuna.Website.Server.Services.DeviceSkillService; using Yuna.Website.Server.Storage.Repositories.Device; using Microsoft.IdentityModel.Tokens; using System.Text.Json; namespace Yuna.Website.Server.Services.DeviceService { public class DeviceService : IDeviceService { private readonly IPropService _propService; private readonly IDeviceRepository _deviceRepository; private readonly IHttpClientFactory _httpClientFactory; private readonly ILogger _logger; public DeviceService( IPropService propService, IDeviceRepository repository, IHttpClientFactory factory, ILogger logger) { _propService = propService; _deviceRepository = repository; _httpClientFactory = factory; _logger = logger; } public async Task AddProps(IReadOnlyList props, long deviceId) { var device = await _deviceRepository.GetById(deviceId); if (device is null) return null; await _deviceRepository.AddProps(props, deviceId); device.Props.AddRange(props); return device; } public async Task?> FetchPropsData(Device device) { var result = new Dictionary(); if (device.Props.IsNullOrEmpty()) return result; var client = _httpClientFactory.CreateClient(device.DeviceUrl); try { _logger.LogTrace("Trying to get data\n " + "from device: {Id}\n" + "via url: {DeviceUrl}", device.Id, device.DeviceUrl); var response = await client.GetAsync(device.DeviceUrl); _logger.LogTrace("Got response\n " + "from device: {Id}\n" + "via url: {DeviceUrl}", device.Id, device.DeviceUrl); var strContent = await response.Content.ReadAsStringAsync(); result = ParseDeviceJson(device.Props, strContent); } catch (Exception ex) { _logger.LogError("Fail: {Message}", ex.Message); return null; } return result; } private Dictionary ParseDeviceJson(IEnumerable props, string jsonStr) { var result = new Dictionary(); using JsonDocument responseJson = JsonDocument.Parse(jsonStr); foreach (var prop in props) { var propExists = responseJson.RootElement.TryGetProperty(prop.JsonValueName, out var propValue); if (!propExists) throw new Exception($"Unable to find jsonValue {prop.JsonValueName}, aborting"); if(propValue.TryGetDouble(out var value)) { value = Math.Round(value, 2); result.Add(prop.Id, value.ToString()); continue; } result.Add(prop.Id, propValue.GetBoolean().ToString()!); _logger.LogTrace("Obtained value for {JsonValueName}", prop.JsonValueName); } return result; } public async Task Create(Device device) { var result = await _deviceRepository.Create(device); return result; } public async Task Delete(long id) { var result = await _deviceRepository.Delete(id); return result; } public async Task GetById(long id) { var result = await _deviceRepository.GetById(id); return result; } public async Task> GetList() { var result = await _deviceRepository.GetList(); return result ?? []; } public async Task> GetList(long userId) { var result = await _deviceRepository.GetList(userId); return result ?? []; } public async Task Update(Device device) { var result = await _deviceRepository.Update(device); return result; } } }