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.
302 lines
12 KiB
302 lines
12 KiB
using Application.Domain.Entities;
|
|
using Infrastructure.Data;
|
|
using Infrastructure.Events;
|
|
using Infrastructure.Extensions;
|
|
using IoT.Shared.Application.Models;
|
|
using Polly;
|
|
using System;
|
|
using System.Linq;
|
|
|
|
namespace Platform.EventHandlers
|
|
{
|
|
public class UpateStatisticEventHandler :
|
|
IEventHander<EntityDeleted<Organ>>,
|
|
IEventHander<EntityDeleted<Building>>,
|
|
IEventHander<EntityUpdated<IoTGateway>>,
|
|
IEventHander<EntityDeleted<IoTGateway>>,
|
|
IEventHander<EntityInserted<IoTData>>,
|
|
IEventHander<EntityUpdated<IoTData>>,
|
|
IEventHander<EntityDeleted<IoTData>>,
|
|
IEventHander<EntityInserted<IoTDevice>>,
|
|
IEventHander<EntityDeleted<IoTDevice>>
|
|
{
|
|
private readonly IRepository<Statistic> _statisticRepo;
|
|
private readonly IRepository<Building> _buildingRepo;
|
|
private readonly IRepository<IoTGateway> _gatewayRepo;
|
|
private readonly IRepository<IoTDevice> _deviceRepo;
|
|
private readonly IRepository<IoTData> _dataRepo;
|
|
|
|
public UpateStatisticEventHandler(IRepository<Statistic> statisticRepo,
|
|
IRepository<Building> buildingRepo,
|
|
IRepository<IoTDevice> deviceRepo,
|
|
IRepository<IoTGateway> gatewayRepo,
|
|
IRepository<IoTData> dataRepo)
|
|
{
|
|
this._statisticRepo = statisticRepo;
|
|
this._buildingRepo = buildingRepo;
|
|
this._gatewayRepo = gatewayRepo;
|
|
this._deviceRepo = deviceRepo;
|
|
this._dataRepo = dataRepo;
|
|
}
|
|
|
|
public void Handle(EntityDeleted<Organ> message)
|
|
{
|
|
//删除统计表中该机构相关的数据
|
|
var prefix = $"[{message.Data.Id}]";
|
|
var list = this._statisticRepo.Table()
|
|
.Where(o => o.Key.StartsWith(prefix))
|
|
.ToList();
|
|
foreach (var entity in list)
|
|
{
|
|
this._statisticRepo.Delete(entity);
|
|
}
|
|
this._statisticRepo.SaveChanges();
|
|
}
|
|
|
|
public void Handle(EntityDeleted<Building> message)
|
|
{
|
|
//删除统计表中该建筑相关内容
|
|
var prefix = $"[{message.Data.OrganId}][{message.Data.Id}]";
|
|
var list = this._statisticRepo.Table().Where(o => o.Key.StartsWith(prefix)).ToList();
|
|
foreach (var item in list)
|
|
{
|
|
this._statisticRepo.Delete(item);
|
|
}
|
|
this._statisticRepo.SaveChanges();
|
|
//更新机构信息
|
|
var organId = message.Data.OrganId;
|
|
this.UpdateOrganData(organId);
|
|
}
|
|
|
|
public void Handle(EntityUpdated<IoTGateway> message)
|
|
{
|
|
var buildingId1 = message.Data.BuildingId;
|
|
var buildingId2 = message.OriginalEntity.BuildingId;
|
|
|
|
if (buildingId1.HasValue)
|
|
{
|
|
if (buildingId2.HasValue)
|
|
{
|
|
if (buildingId1.Value != buildingId2.Value)
|
|
{
|
|
this.UpdateByBuilding(buildingId1.Value);
|
|
this.UpdateByBuilding(buildingId2.Value);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
this.UpdateByBuilding(buildingId1.Value);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (buildingId2.HasValue)
|
|
{
|
|
this.UpdateByBuilding(buildingId2.Value);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Handle(EntityDeleted<IoTGateway> message)
|
|
{
|
|
if (message.Data.BuildingId.HasValue)
|
|
{
|
|
this.UpdateByBuilding(message.Data.BuildingId.Value);
|
|
}
|
|
}
|
|
|
|
private void UpdateByBuilding(Guid buildingId)
|
|
{
|
|
var organId = this.GetOrganId(buildingId);
|
|
this.UpdateOrganData(organId);
|
|
this.UpdateBuildingData(organId, buildingId);
|
|
}
|
|
|
|
private void UpdateOrganData(Guid organId)
|
|
{
|
|
//设备数量
|
|
var deviceCount = this._deviceRepo.ReadOnlyTable()
|
|
.Where(o => o.IoTGateway.BuildingId.HasValue)
|
|
.Where(o => o.IoTGateway.Building.OrganId == organId).Count();
|
|
UpdateValue($"[{organId}]", "DeviceCount", deviceCount, StatisticType.Int);
|
|
//最大最小值
|
|
UpdateOrganDataValue(organId, DataKeys.Light.GetName(), StatisticType.Int);
|
|
UpdateOrganDataValue(organId, DataKeys.Temperature.GetName(), StatisticType.Double);
|
|
UpdateOrganDataValue(organId, DataKeys.Humidity.GetName(), StatisticType.Double);
|
|
//用电器
|
|
UpdateOrganPowerState(organId);
|
|
}
|
|
|
|
private void UpdateOrganPowerState(Guid organId)
|
|
{
|
|
var key = DataKeys.PowerState.GetName();
|
|
var query = this._dataRepo.ReadOnlyTable()
|
|
.Where(o => o.IoTDevice.IoTGateway.BuildingId.HasValue)
|
|
.Where(o => o.IoTDevice.IoTGateway.Building.OrganId == organId)
|
|
.Where(o => o.Key == key);
|
|
var total = query.Count();
|
|
var close = query.Count(o => o.IntValue == 0);
|
|
var open = total - close;
|
|
UpdateValue($"[{organId}]", "DeviceOpenCount", open, StatisticType.Int);
|
|
UpdateValue($"[{organId}]", "DeviceCloseCount", close, StatisticType.Int);
|
|
}
|
|
|
|
public void UpdateBuildingData(Guid organId, Guid buildingId)
|
|
{
|
|
//设备数量
|
|
var prefix = $"[{organId}][{buildingId}]";
|
|
var intValue = this._deviceRepo.ReadOnlyTable().Where(o => o.IoTGateway.BuildingId == buildingId).Count();
|
|
UpdateValue(prefix, "DeviceCount", intValue, StatisticType.Int);
|
|
//最大最小值
|
|
UpdateBuildingDataValue(organId, buildingId, DataKeys.Light.GetName(), StatisticType.Int);
|
|
UpdateBuildingDataValue(organId, buildingId, DataKeys.Temperature.GetName(), StatisticType.Double);
|
|
UpdateBuildingDataValue(organId, buildingId, DataKeys.Humidity.GetName(), StatisticType.Double);
|
|
//用电器
|
|
UpdateBuildingPowerState(organId, buildingId);
|
|
}
|
|
|
|
private void UpdateBuildingPowerState(Guid organId, Guid buildingId)
|
|
{
|
|
var key = DataKeys.PowerState.GetName();
|
|
var query = this._dataRepo.ReadOnlyTable()
|
|
.Where(o => o.IoTDevice.IoTGateway.BuildingId == buildingId)
|
|
.Where(o => o.Key == key);
|
|
var total = query.Count();
|
|
var close = query.Count(o => o.IntValue == 0);
|
|
var open = total - close;
|
|
UpdateValue($"[{organId}][{buildingId}]", "DeviceOpenCount", open, StatisticType.Int);
|
|
UpdateValue($"[{organId}][{buildingId}]", "DeviceCloseCount", close, StatisticType.Int);
|
|
}
|
|
|
|
private void UpdateOrganDataValue(Guid organId, string key, StatisticType type)
|
|
{
|
|
var query = this._dataRepo.ReadOnlyTable()
|
|
.Where(o => o.IoTDevice.IoTGateway.BuildingId.HasValue)
|
|
.Where(o => o.IoTDevice.IoTGateway.Building.OrganId == organId)
|
|
.Where(o => o.Key == key);
|
|
UpdateValue($"[{organId}]", $"Max{key}", type == StatisticType.Int ? query.Max(o => o.IntValue) : query.Max(o => o.DoubleValue), type);
|
|
UpdateValue($"[{organId}]", $"Min{key}", type == StatisticType.Int ? query.Min(o => o.IntValue) : query.Min(o => o.DoubleValue), type);
|
|
}
|
|
|
|
private void UpdateBuildingDataValue(Guid organId, Guid buildingId, string key, StatisticType type)
|
|
{
|
|
var query = this._dataRepo.ReadOnlyTable()
|
|
.Where(o => o.IoTDevice.IoTGateway.BuildingId == buildingId)
|
|
.Where(o => o.Key == key);
|
|
UpdateValue($"[{organId}][{buildingId}]", $"Max{key}", type == StatisticType.Int ? query.Max(o => o.IntValue) : query.Max(o => o.DoubleValue), type);
|
|
UpdateValue($"[{organId}][{buildingId}]", $"Min{key}", type == StatisticType.Int ? query.Min(o => o.IntValue) : query.Min(o => o.DoubleValue), type);
|
|
}
|
|
|
|
public void Handle(EntityInserted<IoTData> message)
|
|
{
|
|
IoTDataEventHandle(message);
|
|
}
|
|
|
|
public void Handle(EntityUpdated<IoTData> message)
|
|
{
|
|
IoTDataEventHandle(message);
|
|
}
|
|
|
|
public void Handle(EntityDeleted<IoTData> message)
|
|
{
|
|
IoTDataEventHandle(message);
|
|
}
|
|
|
|
public void Handle(EntityInserted<IoTDevice> message)
|
|
{
|
|
this.Update(message);
|
|
}
|
|
|
|
public void Handle(EntityDeleted<IoTDevice> message)
|
|
{
|
|
this.Update(message);
|
|
}
|
|
|
|
private void Update(BaseEvent<IoTDevice> message)
|
|
{
|
|
var gatewayId = message.Data.IoTGatewayId;
|
|
var buildingId = this._gatewayRepo.ReadOnlyTable()
|
|
.Where(o => o.Id == gatewayId)
|
|
.Select(o => o.BuildingId)
|
|
.FirstOrDefault();
|
|
if (buildingId.HasValue)
|
|
{
|
|
UpdateByBuilding(buildingId.Value);
|
|
}
|
|
}
|
|
|
|
private void IoTDataEventHandle(BaseEvent<IoTData> message)
|
|
{
|
|
|
|
if (message.Data.Key == DataKeys.Light.GetName() ||
|
|
message.Data.Key == DataKeys.Temperature.GetName() ||
|
|
message.Data.Key == DataKeys.Humidity.GetName() ||
|
|
message.Data.Key == DataKeys.PowerState.GetName())
|
|
{
|
|
var deviceId = message.Data.IoTDeviceId;
|
|
var buildingId = this._deviceRepo.ReadOnlyTable()
|
|
.Where(o => o.Id == deviceId)
|
|
.Where(o => o.IoTGateway.BuildingId.HasValue)
|
|
.Select(o => o.IoTGateway.BuildingId)
|
|
.FirstOrDefault();
|
|
if (buildingId != null)
|
|
{
|
|
var organId = this.GetOrganId(buildingId.Value);
|
|
if (message.Data.Key == DataKeys.Light.GetName())
|
|
{
|
|
UpdateOrganDataValue(organId, DataKeys.Light.GetName(), StatisticType.Int);
|
|
UpdateBuildingDataValue(organId, buildingId.Value, DataKeys.Light.GetName(), StatisticType.Int);
|
|
}
|
|
else if(message.Data.Key == DataKeys.Temperature.GetName())
|
|
{
|
|
UpdateOrganDataValue(organId, DataKeys.Temperature.GetName(), StatisticType.Double);
|
|
UpdateBuildingDataValue(organId, buildingId.Value, DataKeys.Temperature.GetName(), StatisticType.Double);
|
|
}
|
|
else if(message.Data.Key == DataKeys.Humidity.GetName())
|
|
{
|
|
UpdateOrganDataValue(organId, DataKeys.Humidity.GetName(), StatisticType.Double);
|
|
UpdateBuildingDataValue(organId, buildingId.Value, DataKeys.Humidity.GetName(), StatisticType.Double);
|
|
}
|
|
else if(message.Data.Key == DataKeys.PowerState.GetName())
|
|
{
|
|
UpdateOrganPowerState(organId);
|
|
UpdateBuildingPowerState(organId, buildingId.Value);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void UpdateValue(string prefix, string name, object value, StatisticType type)
|
|
{
|
|
void Exec()
|
|
{
|
|
var key = $"{prefix}{name}";
|
|
var entity = this._statisticRepo.Table().FirstOrDefault(o => o.Key == key);
|
|
if (entity == null)
|
|
{
|
|
entity = new Statistic
|
|
{
|
|
Type = type,
|
|
Key = key
|
|
};
|
|
this._statisticRepo.Add(entity);
|
|
}
|
|
entity.SetValue(value);
|
|
this._statisticRepo.SaveChanges();
|
|
}
|
|
Policy.Handle<Exception>()
|
|
.Retry(3,(e,i)=> {
|
|
e.PrintStack($"retry {i}:{e.Message??e.InnerException?.Message}");
|
|
})
|
|
.Execute(() => Exec());
|
|
}
|
|
|
|
private Guid GetOrganId(Guid buildingId)
|
|
{
|
|
return this._buildingRepo.ReadOnlyTable()
|
|
.Where(o => o.Id == buildingId)
|
|
.Select(o => o.OrganId)
|
|
.FirstOrDefault();
|
|
}
|
|
}
|
|
} |