添加 客流统计服务 与 数据层

old
xiaoguo 2 years ago
parent b8a943c812
commit 383d80f4ad

@ -106,9 +106,13 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Repositories\Entities\GSDBContext.cs" />
<Compile Include="Repositories\Entities\MenuEntity.cs" />
<Compile Include="Repositories\Entities\PassengerFlowStatisticsEntity.cs" />
<Compile Include="Repositories\Entities\SystemConfigEntity.cs" />
<Compile Include="Repositories\Impl\PassengerFlowStatisticsRepository.cs" />
<Compile Include="Repositories\Impl\SystemRepository.cs" />
<Compile Include="Repositories\IPassengerFlowStatisticsRepository.cs" />
<Compile Include="Repositories\ISystemRepository.cs" />
<Compile Include="Repositories\Entities\PassengerFlowStatisticsDayEntity.cs" />
<Compile Include="SDK\Monitoring\CHCNetSDK.cs" />
<Compile Include="Services\ILogService.cs" />
<Compile Include="Services\Impl\LogService.cs" />
@ -124,6 +128,8 @@
<Compile Include="Services\Models\MainWindowModel.cs" />
<Compile Include="Services\Models\MenuModel.cs" />
<Compile Include="Services\Models\PageModel.cs" />
<Compile Include="Services\Models\PassengerFlowStatisticsModel.cs" />
<Compile Include="Services\Models\PassengerFlowStatisticsTotalModel.cs" />
<Compile Include="Services\Models\SystemConfigModel.cs" />
</ItemGroup>
<ItemGroup>

@ -21,7 +21,7 @@ namespace GuideScreen.Common.Repositories
/// <summary>
/// 数据库上下文
/// </summary>
public class GSDBContext : DbContext
internal class GSDBContext : DbContext
{
//用System.Data.SQLite::SQLiteConnection创建DbConnection进行构造初始化
public GSDBContext(DbConnection dbConnection, bool contextOwnsConnection = true)
@ -47,13 +47,16 @@ namespace GuideScreen.Common.Repositories
var sqliteConnectionInitializer = new MySqliteCreateDatabaseIfNotExists(modelBuilder);
Database.SetInitializer(sqliteConnectionInitializer);
}
public DbSet<MenuEntity> MenuEntities { get; set; }
public DbSet<MenuEntity> MenuEntities { get; set; }
public DbSet<SystemConfigEntity> SystemConfigEntities { get; set; }
public DbSet<PassengerFlowStatisticsEntity> PassengerFlowStatisticsEntites { get; set; }
public DbSet<PassengerFlowStatisticsDayEntity> PassengerFlowStatisticsDayEntites { get; set; }
}
public class MySqliteCreateDatabaseIfNotExists : SqliteCreateDatabaseIfNotExists<GSDBContext>
internal class MySqliteCreateDatabaseIfNotExists : SqliteCreateDatabaseIfNotExists<GSDBContext>
{
public MySqliteCreateDatabaseIfNotExists(DbModelBuilder modelBuilder) : base(modelBuilder)
{

@ -13,50 +13,58 @@ namespace GuideScreen.Common.Repositories.Entities
/// 菜单 实体
/// </summary>
[Table("menus")]
public class MenuEntity
internal class MenuEntity
{
/// <summary>
/// 主键ID
/// </summary>
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
[Column("id")]
public int ID { get; set; }
/// <summary>
/// 父节点ID
/// </summary>
[Required]
[Column("parentID")]
public int ParentID { get; set; }
/// <summary>
/// 名称
/// </summary>
[Index(IsUnique = true)]
[Column("name")]
public string Name { get; set; }
/// <summary>
/// 图标编号
/// </summary>
[Column("symbol")]
public int Symbol { get; set; }
/// <summary>
/// 窗体实例化地址
/// </summary>
[Column("windowUri")]
public string WindowUri { get; set; }
/// <summary>
/// 页面编号
/// </summary>
[Column("pageIndex")]
public int PageIndex { get; set; }
/// <summary>
/// 是否启用
/// </summary>
[Column("enabled")]
public bool Enabled { get; set; }
/// <summary>
/// 是否需要管理员权限
/// </summary>
[Column("isAdmin")]
public bool IsAdmin { get; set; }
}
}

@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GuideScreen.Common.Repositories.Entities
{
/// <summary>
/// 客流统计 实体
/// </summary>
[Table("passengerFlowStatisticsDay")]
internal class PassengerFlowStatisticsDayEntity
{
/// <summary>
/// 主键 ID
/// </summary>
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Column("id")]
public int ID { get; set; }
/// <summary>
/// 进入人数
/// </summary>
[Column("enterNum")]
public int EnterNum { get; set; }
/// <summary>
/// 离开人数
/// </summary>
[Column("leaveNum")]
public int LeaveNum { get; set; }
/// <summary>
/// 设备IP
/// </summary>
[Column("deviceIP")]
public string DeviceIP { get; set; }
/// <summary>
/// 创建时间
/// </summary>
[Column("day")]
public string Day { get; set; }
/// <summary>
/// 创建时间
/// </summary>
[Column("createDateTime")]
public DateTime CreateDateTime { get; set; }
}
}

@ -0,0 +1,61 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GuideScreen.Common.Repositories.Entities
{
/// <summary>
/// 客流统计 实体
/// </summary>
[Table("passengerFlowStatistics")]
internal class PassengerFlowStatisticsEntity
{
/// <summary>
/// 主键 ID
/// </summary>
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Column("id")]
public int ID { get; set; }
/// <summary>
/// 进入人数
/// </summary>
[Column("enterNum")]
public int EnterNum { get; set; }
/// <summary>
/// 离开人数
/// </summary>
[Column("leaveNum")]
public int LeaveNum { get; set; }
/// <summary>
/// 开始时间
/// </summary>
[Column("startTime")]
public DateTime StartTime { get; set; }
/// <summary>
/// 结束时间
/// </summary>
[Column("endTime")]
public DateTime EndTime { get; set; }
/// <summary>
/// 设备IP
/// </summary>
[Column("deviceIP")]
public string DeviceIP { get; set; }
/// <summary>
/// 创建时间
/// </summary>
[Column("createDateTime")]
public DateTime CreateDateTime { get; set; }
}
}

@ -12,41 +12,47 @@ namespace GuideScreen.Common.Repositories.Entities
/// 系统参数
/// </summary>
[Table("systemConfig")]
public class SystemConfigEntity
internal class SystemConfigEntity
{
/// <summary>
/// 主键ID
/// </summary>
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Column("id")]
public int ID { get; set; }
/// <summary>
/// 参数名称
/// </summary>
[Required]
[Column("configName")]
public string ConfigName { get; set; }
/// <summary>
/// 参数键值
/// </summary>
[Index(IsUnique = true)]
[Column("configKey")]
public string ConfigKey { get; set; }
/// <summary>
/// 参数值
/// </summary>
[Required]
[Column("configValue")]
public string ConfigValue { get; set; }
/// <summary>
/// 描述
/// </summary>
[Column("remarks")]
public string Remarks { get; set; }
/// <summary>
/// 是否启用
/// </summary>
[Column("enabled")]
public bool Enabled { get; set; }
}
}

@ -0,0 +1,17 @@
using GuideScreen.Common.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GuideScreen.Common.Repositories
{
/// <summary>
/// 客流统计 数据层 接口
/// </summary>
public interface IPassengerFlowStatisticsRepository : IDependency
{
}
}

@ -13,7 +13,7 @@ namespace GuideScreen.Common.Repositories
/// <summary>
/// 系统相关 数据层 接口
/// </summary>
public interface ISystemRepository: IDependency
internal interface ISystemRepository: IDependency
{
/// <summary>
/// 获取系统菜单

@ -0,0 +1,143 @@
using GuideScreen.Common.Common;
using GuideScreen.Common.Repositories.Entities;
using GuideScreen.Common.Services.Models;
using Masuit.Tools;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GuideScreen.Common.Repositories.Impl
{
/// <summary>
/// 客流统计 数据层 实现
/// </summary>
internal class PassengerFlowStatisticsRepository : IPassengerFlowStatisticsRepository
{
/// <summary>
/// 添加客流信息
/// </summary>
/// <param name="entity"></param>
public void AddPassengerFlowStatistics(PassengerFlowStatisticsEntity entity)
{
var dateStr = entity.EndTime.ToString("yyyy-MM-dd");
using (var context = GSDBContext.GetDbContext())
{
var dayEntity = context.PassengerFlowStatisticsDayEntites.Where(f => f.Day == dateStr).FirstOrDefault();
entity.CreateDateTime = DateTime.Now;
if (dayEntity == null)
{
dayEntity = new PassengerFlowStatisticsDayEntity();
dayEntity.Day = dateStr;
dayEntity.EnterNum = entity.EnterNum;
dayEntity.LeaveNum = entity.LeaveNum;
dayEntity.DeviceIP = entity.DeviceIP;
dayEntity.CreateDateTime = entity.CreateDateTime;
context.PassengerFlowStatisticsDayEntites.Add(dayEntity);
}
else
{
dayEntity.EnterNum += entity.EnterNum;
dayEntity.LeaveNum += entity.LeaveNum;
}
context.PassengerFlowStatisticsEntites.Add(entity);
context.SaveChanges();
}
}
/// <summary>
/// 获取当天客流量统计
/// </summary>
/// <param name="date"></param>
/// <returns></returns>
public PassengerFlowStatisticsModel GetPassengerFlowStatisticsDayTotal(DateTime date)
{
var dateStr = date.ToString("yyyy-MM-dd");
PassengerFlowStatisticsModel model = new PassengerFlowStatisticsModel();
using (var context = GSDBContext.GetDbContext())
{
var entity = context.PassengerFlowStatisticsDayEntites.Where(f => f.Day == dateStr).FirstOrDefault();
if (entity != null)
{
model = ModelTools.PubClone<PassengerFlowStatisticsDayEntity, PassengerFlowStatisticsModel>.Trans(entity);
}
return model;
}
}
/// <summary>
/// 获取周客流量统计
/// </summary>
/// <param name="date"></param>
/// <returns></returns>
public List<PassengerFlowStatisticsTotalModel> GetPassengerFlowStatisticsWeekTotal(DateTime date)
{
var endDay = DateTime.Parse(date.ToString("yyyy-MM-dd")).AddDays(1).AddSeconds(-1);
var begDay = DateTime.MinValue;
int week = (int)date.DayOfWeek;
if (week == 0)
{
begDay = endDay.AddDays(-6);
}
else
{
begDay = endDay.AddDays(-(week - 1));
}
begDay = DateTime.Parse(endDay.ToString("yyyy-MM-dd"));
var weekTotal = new List<PassengerFlowStatisticsTotalModel>();
using (var context = GSDBContext.GetDbContext())
{
var values = context.PassengerFlowStatisticsDayEntites.Where(f => f.CreateDateTime >= begDay && f.CreateDateTime <= endDay).OrderBy(f => f.CreateDateTime).Select(f => new
{
f.EnterNum,
f.LeaveNum,
f.CreateDateTime,
}).ToArray();
weekTotal = values.Select(f => new PassengerFlowStatisticsTotalModel
{
EnterNum = f.EnterNum,
LeaveNum = f.LeaveNum,
XTypeName = ConvertDayOfWeek(f.CreateDateTime.DayOfWeek)
}
).ToList();
return weekTotal;
}
}
private string ConvertDayOfWeek(DayOfWeek dayOfWeek)
{
var value = string.Empty;
switch (dayOfWeek)
{
case DayOfWeek.Sunday:
value = "星期天";
break;
case DayOfWeek.Monday:
value = "星期一";
break;
case DayOfWeek.Tuesday:
value = "星期二";
break;
case DayOfWeek.Wednesday:
value = "星期三";
break;
case DayOfWeek.Thursday:
value = "星期四";
break;
case DayOfWeek.Friday:
value = "星期五";
break;
case DayOfWeek.Saturday:
value = "星期六";
break;
default:
break;
}
return value;
}
}
}

@ -16,115 +16,227 @@ namespace GuideScreen.Common.Services
/// </summary>
public interface IPLCCommunicationService : IDependency
{
event EventHandler<string> ErrorMessage;
#region 同步
/// <summary>
/// 连接PLC长连接
/// </summary>
/// <param name="address"></param>
/// <param name="port"></param>
PLCResult Connection(string address, int port = 0);
/// <summary>
/// 关闭连接PLC长连接
/// </summary>
PLCResult ColseConnection();
/// <summary>
/// 读取指定地址的bool值
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
PLCResult<bool> ReadBool(string address);
/// <summary>
/// 读取指定地址的byte值
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
PLCResult<byte> ReadByte(string address);
/// <summary>
/// 读取指定地址的Int16值
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
PLCResult<short> ReadInt16(string address);
/// <summary>
/// 读取指定地址的Int32值
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
PLCResult<int> ReadInt32(string address);
/// <summary>
/// 读取指定地址的long值
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
PLCResult<long> ReadLong(string address);
/// <summary>
/// 读取指定地址的Float值
/// </summary>
/// <returns></returns>
PLCResult<float> ReadFloat(string address);
/// <summary>
/// 读取指定地址的double值
/// </summary>
/// <returns></returns>
PLCResult<double> ReadDouble(string address);
/// <summary>
/// 写入bool值
/// </summary>
/// <param name="address">写入地址</param>
/// <param name="value"></param>
PLCResult Write(string address, bool value);
/// <summary>
/// 写入byte值
/// </summary>
/// <param name="address">写入地址</param>
/// <param name="value"></param>
PLCResult Write(string address, byte value);
/// <summary>
/// 写入Int16值
/// </summary>
/// <param name="address">写入地址</param>
/// <param name="value"></param>
PLCResult Write(string address, Int16 value);
event EventHandler<string> InfoMessage;
/// <summary>
/// 写入Int32值
/// </summary>
/// <param name="address">写入地址</param>
/// <param name="value"></param>
PLCResult Write(string address, Int32 value);
/// <summary>
/// 写入float值
/// </summary>
/// <param name="address">写入地址</param>
/// <param name="value"></param>
PLCResult Write(string address, float value);
/// <summary>
/// 写入double值
/// </summary>
/// <param name="address">写入地址</param>
/// <param name="value"></param>
PLCResult Write(string address, double value);
/// <summary>
/// 写入long值
/// </summary>
/// <param name="address">写入地址</param>
/// <param name="value"></param>
PLCResult Write(string address, long value);
#endregion
#region 异步
/// <summary>
/// 连接PLC长连接
/// </summary>
/// <param name="address"></param>
/// <param name="port"></param>
void Connection(string address, int port = 0);
Task<PLCResult> ConnectionAsync(string address, int port = 0);
/// <summary>
/// 关闭连接PLC长连接
/// </summary>
void ColseConnection();
Task<PLCResult> ColseConnectionAsyn();
/// <summary>
/// 读取指定地址的bool值
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
bool ReadBool(string address);
Task<PLCResult<bool>> ReadBoolAsync(string address);
/// <summary>
/// 读取指定地址的byte值
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
byte ReadByte(string address);
Task<PLCResult<byte>> ReadByteAsync(string address);
/// <summary>
/// 读取指定地址的Int16值
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
int ReadInt16(string address);
Task<PLCResult<short>> ReadInt16Async(string address);
/// <summary>
/// 读取指定地址的Int32值
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
int ReadInt32(string address);
Task<PLCResult<int>> ReadInt32Async(string address);
/// <summary>
/// 读取指定地址的long值
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
long ReadLong(string address);
Task<PLCResult<long>> ReadLongAsync(string address);
/// <summary>
/// 读取指定地址的Float值
/// </summary>
/// <returns></returns>
float ReadFloat(string address);
Task<PLCResult<float>> ReadFloatAsync(string address);
/// <summary>
/// 读取指定地址的double值
/// </summary>
/// <returns></returns>
double ReadDouble(string address);
Task<PLCResult<double>> ReadDoubleAsync(string address);
/// <summary>
/// 写入bool值
/// </summary>
/// <param name="address">写入地址</param>
/// <param name="value"></param>
void Write(string address, bool value);
Task<PLCResult> WriteAsync(string address, bool value);
/// <summary>
/// 写入byte值
/// </summary>
/// <param name="address">写入地址</param>
/// <param name="value"></param>
void Write(string address, byte value);
Task<PLCResult> WriteAsync(string address, byte value);
/// <summary>
/// 写入Int16值
/// </summary>
/// <param name="address">写入地址</param>
/// <param name="value"></param>
void Write(string address, Int16 value);
Task<PLCResult> WriteAsync(string address, Int16 value);
/// <summary>
/// 写入Int32值
/// </summary>
/// <param name="address">写入地址</param>
/// <param name="value"></param>
void Write(string address, Int32 value);
Task<PLCResult> WriteAsync(string address, Int32 value);
/// <summary>
/// 写入float值
/// </summary>
/// <param name="address">写入地址</param>
/// <param name="value"></param>
void Write(string address, float value);
Task<PLCResult> WriteAsync(string address, float value);
/// <summary>
/// 写入double值
/// </summary>
/// <param name="address">写入地址</param>
/// <param name="value"></param>
void Write(string address, double value);
Task<PLCResult> WriteAsync(string address, double value);
/// <summary>
/// 写入long值
/// </summary>
/// <param name="address">写入地址</param>
/// <param name="value"></param>
void Write(string address, long value);
Task<PLCResult> WriteAsync(string address, long value);
#endregion
}
}

@ -1,9 +1,14 @@
using GuideScreen.Common.Common;
using GuideScreen.Common.Services.Models;
using GuideScreen.SDK.Monitoring;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using static GuideScreen.SDK.Monitoring.CHCNetSDK;
namespace GuideScreen.Common.Services
{
@ -12,6 +17,56 @@ namespace GuideScreen.Common.Services
/// </summary>
public interface IPassengerFlowStatisticsService : IDependency
{
event EventHandler<PassengerFlowStatisticsModel> ActionEvent;
event EventHandler<string> ExceptionEvent;
/// <summary>
/// 视频设备SDK初始化
/// </summary>
/// <returns></returns>
bool Init();
/// <summary>
/// 释放SDK资源
/// </summary>
void CleaUp();
/// <summary>
/// 登录视频设备
/// </summary>
/// <param name="ipAddress">Ip地址</param>
/// <param name="port">端口</param>
/// <param name="name">用户名</param>
/// <param name="pwd">密码</param>
void Login(string ipAddress, int port, string userName, string password);
/// <summary>
/// 登出
/// </summary>
void Logout();
/// <summary>
/// 部防
/// </summary>
/// <param name="listenIpAddress"></param>
void OpenAlarm();
/// <summary>
/// 撤防
/// </summary>
void CloseAlarm();
/// <summary>
/// 启用监听
/// </summary>
/// <param name="ListenIpAddress"></param>
void StartListen(string listenIpAddress, int port);
/// <summary>
/// 关闭监听
/// </summary>
void CloseListen(string ListenIpAddress);
}
}

@ -26,10 +26,6 @@ namespace GuideScreen.Common.Services.Impl
{
private SiemensS7Net siemensS7Net = null;
public event EventHandler<string> ErrorMessage = null;
public event EventHandler<string> InfoMessage = null;
public PLCCommunicationService()
{
siemensS7Net = new SiemensS7Net(SiemensPLCS.S200Smart);
@ -42,22 +38,26 @@ namespace GuideScreen.Common.Services.Impl
/// </summary>
/// <param name="address"></param>
/// <param name="port"></param>
public void Connection(string address, int port = 0)
public PLCResult Connection(string address, int port = 0)
{
siemensS7Net.IpAddress = address;
if (port > 0)
{
siemensS7Net.Port = port;
}
siemensS7Net.ConnectServer();
var operateResult = siemensS7Net.ConnectServer();
var result = ConvertResult(operateResult);
return result;
}
/// <summary>
/// 关闭连接PLC长连接
/// </summary>
public void ColseConnection()
public PLCResult ColseConnection()
{
siemensS7Net.ConnectClose();
var operateResult = siemensS7Net.ConnectClose();
var result = ConvertResult(operateResult);
return result;
}
/// <summary>
@ -65,11 +65,11 @@ namespace GuideScreen.Common.Services.Impl
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
public bool ReadBool(string address)
public PLCResult<bool> ReadBool(string address)
{
var result = siemensS7Net.ReadBool(address);
VerifyResult(result, address);
return result.Content;
var operateResult = siemensS7Net.ReadBool(address);
var result = ConvertResult(operateResult);
return result;
}
/// <summary>
@ -77,11 +77,11 @@ namespace GuideScreen.Common.Services.Impl
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
public byte ReadByte(string address)
public PLCResult<byte> ReadByte(string address)
{
var result = siemensS7Net.ReadByte(address);
VerifyResult(result, address);
return result.Content;
var operateResult = siemensS7Net.ReadByte(address);
var result = ConvertResult(operateResult);
return result;
}
/// <summary>
@ -89,11 +89,11 @@ namespace GuideScreen.Common.Services.Impl
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
public int ReadInt16(string address)
public PLCResult<short> ReadInt16(string address)
{
var result = siemensS7Net.ReadInt16(address);
VerifyResult(result, address);
return result.Content;
var operateResult = siemensS7Net.ReadInt16(address);
var result = ConvertResult(operateResult);
return result;
}
/// <summary>
@ -101,11 +101,11 @@ namespace GuideScreen.Common.Services.Impl
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
public int ReadInt32(string address)
public PLCResult<int> ReadInt32(string address)
{
var result = siemensS7Net.ReadInt32(address);
VerifyResult(result, address);
return result.Content;
var operateResult = siemensS7Net.ReadInt32(address);
var result = ConvertResult(operateResult);
return result;
}
/// <summary>
@ -113,33 +113,33 @@ namespace GuideScreen.Common.Services.Impl
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
public long ReadLong(string address)
public PLCResult<long> ReadLong(string address)
{
var result = siemensS7Net.ReadInt64(address);
VerifyResult(result, address);
return result.Content;
var operateResult = siemensS7Net.ReadInt64(address);
var result = ConvertResult(operateResult);
return result;
}
/// <summary>
/// 读取指定地址的Float值
/// </summary>
/// <returns></returns>
public float ReadFloat(string address)
public PLCResult<float> ReadFloat(string address)
{
var result = siemensS7Net.ReadFloat(address);
VerifyResult(result, address);
return result.Content;
var operateResult = siemensS7Net.ReadFloat(address);
var result = ConvertResult(operateResult);
return result;
}
/// <summary>
/// 读取指定地址的double值
/// </summary>
/// <returns></returns>
public double ReadDouble(string address)
public PLCResult<double> ReadDouble(string address)
{
var result = siemensS7Net.ReadDouble(address);
VerifyResult(result, address);
return result.Content;
var operateResult = siemensS7Net.ReadDouble(address);
var result = ConvertResult(operateResult);
return result;
}
/// <summary>
@ -147,10 +147,11 @@ namespace GuideScreen.Common.Services.Impl
/// </summary>
/// <param name="address">写入地址</param>
/// <param name="value"></param>
public void Write(string address, bool value)
public PLCResult Write(string address, bool value)
{
var result = siemensS7Net.Write(address, value);
VerifyResult(result, address, value);
var operateResult = siemensS7Net.Write(address, value);
var result = ConvertResult(operateResult);
return result;
}
/// <summary>
@ -158,10 +159,12 @@ namespace GuideScreen.Common.Services.Impl
/// </summary>
/// <param name="address">写入地址</param>
/// <param name="value"></param>
public void Write(string address, byte value)
public PLCResult Write(string address, byte value)
{
var result = siemensS7Net.Write(address, value);
VerifyResult(result, address, value);
var operateResult = siemensS7Net.Write(address, value);
var result = ConvertResult(operateResult);
return result;
}
/// <summary>
@ -169,10 +172,11 @@ namespace GuideScreen.Common.Services.Impl
/// </summary>
/// <param name="address">写入地址</param>
/// <param name="value"></param>
public void Write(string address, Int16 value)
public PLCResult Write(string address, Int16 value)
{
var result = siemensS7Net.Write(address, value);
VerifyResult(result, address, value);
var operateResult = siemensS7Net.Write(address, value);
var result = ConvertResult(operateResult);
return result;
}
/// <summary>
@ -180,10 +184,11 @@ namespace GuideScreen.Common.Services.Impl
/// </summary>
/// <param name="address">写入地址</param>
/// <param name="value"></param>
public void Write(string address, Int32 value)
public PLCResult Write(string address, Int32 value)
{
var result = siemensS7Net.Write(address, value);
VerifyResult(result, address, value);
var operateResult = siemensS7Net.Write(address, value);
var result = ConvertResult(operateResult);
return result;
}
/// <summary>
@ -191,10 +196,11 @@ namespace GuideScreen.Common.Services.Impl
/// </summary>
/// <param name="address">写入地址</param>
/// <param name="value"></param>
public void Write(string address, float value)
public PLCResult Write(string address, float value)
{
var result = siemensS7Net.Write(address, value);
VerifyResult(result, address, value);
var operateResult = siemensS7Net.Write(address, value);
var result = ConvertResult(operateResult);
return result;
}
/// <summary>
@ -202,10 +208,11 @@ namespace GuideScreen.Common.Services.Impl
/// </summary>
/// <param name="address">写入地址</param>
/// <param name="value"></param>
public void Write(string address, double value)
public PLCResult Write(string address, double value)
{
var result = siemensS7Net.Write(address, value);
VerifyResult(result, address, value);
var operateResult = siemensS7Net.Write(address, value);
var result = ConvertResult(operateResult);
return result;
}
/// <summary>
@ -213,10 +220,11 @@ namespace GuideScreen.Common.Services.Impl
/// </summary>
/// <param name="address">写入地址</param>
/// <param name="value"></param>
public void Write(string address, long value)
public PLCResult Write(string address, long value)
{
var result = siemensS7Net.Write(address, value);
VerifyResult(result, address, value);
var operateResult = siemensS7Net.Write(address, value);
var result = ConvertResult(operateResult);
return result;
}
#endregion
@ -257,7 +265,6 @@ namespace GuideScreen.Common.Services.Impl
public async Task<PLCResult<bool>> ReadBoolAsync(string address)
{
var operateResult = await siemensS7Net.ReadBoolAsync(address);
VerifyResult(operateResult);
var result = ConvertResult(operateResult);
return result;
}
@ -270,7 +277,6 @@ namespace GuideScreen.Common.Services.Impl
public async Task<PLCResult<byte>> ReadByteAsync(string address)
{
var operateResult = await siemensS7Net.ReadByteAsync(address);
VerifyResult(operateResult);
var result = ConvertResult(operateResult);
return result;
}
@ -283,7 +289,6 @@ namespace GuideScreen.Common.Services.Impl
public async Task<PLCResult<short>> ReadInt16Async(string address)
{
var operateResult = await siemensS7Net.ReadInt16Async(address);
VerifyResult(operateResult);
var result = ConvertResult(operateResult);
return result;
}
@ -296,7 +301,6 @@ namespace GuideScreen.Common.Services.Impl
public async Task<PLCResult<int>> ReadInt32Async(string address)
{
var operateResult = await siemensS7Net.ReadInt32Async(address);
VerifyResult(operateResult);
var result = ConvertResult(operateResult);
return result;
}
@ -309,7 +313,6 @@ namespace GuideScreen.Common.Services.Impl
public async Task<PLCResult<long>> ReadLongAsync(string address)
{
var operateResult = await siemensS7Net.ReadInt64Async(address);
VerifyResult(operateResult);
var result = ConvertResult(operateResult);
return result;
}
@ -321,7 +324,6 @@ namespace GuideScreen.Common.Services.Impl
public async Task<PLCResult<float>> ReadFloatAsync(string address)
{
var operateResult = await siemensS7Net.ReadFloatAsync(address);
VerifyResult(operateResult);
var result = ConvertResult(operateResult);
return result;
}
@ -333,7 +335,6 @@ namespace GuideScreen.Common.Services.Impl
public async Task<PLCResult<double>> ReadDoubleAsync(string address)
{
var operateResult = await siemensS7Net.ReadDoubleAsync(address);
VerifyResult(operateResult);
var result = ConvertResult(operateResult);
return result;
}
@ -346,7 +347,6 @@ namespace GuideScreen.Common.Services.Impl
public async Task<PLCResult> WriteAsync(string address, bool value)
{
var operateResult = await siemensS7Net.WriteAsync(address, value);
VerifyResult(operateResult);
var result = ConvertResult(operateResult);
return result;
}
@ -360,7 +360,6 @@ namespace GuideScreen.Common.Services.Impl
{
var operateResult = await siemensS7Net.WriteAsync(address, value);
VerifyResult(operateResult);
var result = ConvertResult(operateResult);
return result;
}
@ -373,7 +372,6 @@ namespace GuideScreen.Common.Services.Impl
public async Task<PLCResult> WriteAsync(string address, Int16 value)
{
var operateResult = await siemensS7Net.WriteAsync(address, value);
VerifyResult(operateResult);
var result = ConvertResult(operateResult);
return result;
}
@ -386,7 +384,6 @@ namespace GuideScreen.Common.Services.Impl
public async Task<PLCResult> WriteAsync(string address, Int32 value)
{
var operateResult = await siemensS7Net.WriteAsync(address, value);
VerifyResult(operateResult);
var result = ConvertResult(operateResult);
return result;
}
@ -399,7 +396,6 @@ namespace GuideScreen.Common.Services.Impl
public async Task<PLCResult> WriteAsync(string address, float value)
{
var operateResult = await siemensS7Net.WriteAsync(address, value);
VerifyResult(operateResult);
var result = ConvertResult(operateResult);
return result;
}
@ -412,7 +408,6 @@ namespace GuideScreen.Common.Services.Impl
public async Task<PLCResult> WriteAsync(string address, double value)
{
var operateResult = await siemensS7Net.WriteAsync(address, value);
VerifyResult(operateResult);
var result = ConvertResult(operateResult);
return result;
}
@ -425,61 +420,13 @@ namespace GuideScreen.Common.Services.Impl
public async Task<PLCResult> WriteAsync(string address, long value)
{
var operateResult = await siemensS7Net.WriteAsync(address, value);
VerifyResult(operateResult);
var result = ConvertResult(operateResult);
return result;
}
#endregion
/// <summary>
/// 验证结果 如果启用了 ErrorMessage 就不抛出异常信息
/// </summary>
/// <param name="result"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
private bool VerifyResult(OperateResult result, string address = "", object value = null)
{
var message = $"address:{address}";
if (value != null)
{
message += $",value:{value}";
}
object content = null;
if (result.GetProperties().Where(f => f.Name == "Content").Count() > 0)
{
content = result.GetProperty<object>("Content");
}
if (content != null)
{
message += $",content:{content}";
}
message += "," + result.Message;
if (result.IsSuccess)
{
InfoMessage.Invoke(this, "PLC信息" + message);
return true;
}
else
{
if (ErrorMessage == null)
{
throw new Exception(result.Message);
}
else
{
ErrorMessage.Invoke(this, "PLC异常" + message);
return false;
}
}
}
/// <summary>
/// 转换 result (将框架结果结构转换成当前程序结果结构)
/// </summary>

@ -1,4 +1,5 @@
using GuideScreen.Common.Common;
using Masuit.Tools.Reflection;
using System;
using System.Collections.Generic;
using System.Linq;
@ -21,8 +22,6 @@ namespace GuideScreen.Common.Services.Impl
public PLCControllerService(IPLCCommunicationService pLCCommunicationService)
{
this.pLCCommunicationService = pLCCommunicationService;
this.pLCCommunicationService.ErrorMessage += PLCCommunicationService_ErrorMessage;
this.pLCCommunicationService.InfoMessage += PLCCommunicationService_InfoMessage; ;
}
private void PLCCommunicationService_InfoMessage(object sender, string e)
@ -59,8 +58,58 @@ namespace GuideScreen.Common.Services.Impl
/// <returns></returns>
public bool GetHeartbeat()
{
var ret = this.pLCCommunicationService.ReadBool(PLCPointConstants.HeartbeatSignal);
return ret;
var result = this.pLCCommunicationService.ReadBool(PLCPointConstants.HeartbeatSignal);
var res = VerifyResult(result, PLCPointConstants.HeartbeatSignal);
return res;
}
/// <summary>
/// 验证结果 如果启用了 ErrorMessage 就不抛出异常信息
/// </summary>
/// <param name="result"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
private bool VerifyResult(PLCResult result, string address = "", object value = null)
{
var message = $"address:{address}";
if (value != null)
{
message += $",value:{value}";
}
object content = null;
if (result.GetProperties().Where(f => f.Name == "Content").Count() > 0)
{
content = result.GetProperty<object>("Content");
}
if (content != null)
{
message += $",content:{content}";
}
message += "," + result.Message;
if (result.IsSuccess)
{
InfoMessage.Invoke(this, "PLC信息" + message);
return true;
}
else
{
if (ErrorMessage == null)
{
throw new Exception(result.Message);
}
else
{
ErrorMessage.Invoke(this, "PLC异常" + message);
return false;
}
}
}
}
}

@ -1,21 +1,341 @@
using System;
using GuideScreen.Common.Services.Models;
using GuideScreen.SDK.Monitoring;
using System;
using System.Collections.Generic;
using System.Diagnostics.Tracing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using static GuideScreen.SDK.Monitoring.CHCNetSDK;
namespace GuideScreen.Common.Services.Impl
{
/// <summary>
/// 客流统计服务 实现
/// </summary>
internal class PassengerFlowStatisticsService : IPassengerFlowStatisticsService
internal class PassengerFlowStatisticsServiceByHikvision : IPassengerFlowStatisticsService
{
public void Init(string ipAddress, string port, string name, string pwd)
private CHCNetSDK.UNION_STATTIME m_struStatTime = new CHCNetSDK.UNION_STATTIME();
private CHCNetSDK.UNION_STATFRAME m_struStatFrame = new CHCNetSDK.UNION_STATFRAME();
public CHCNetSDK.LOGINRESULTCALLBACK LoginCallBack = null;
private CHCNetSDK.EXCEPYIONCALLBACK m_fExceptionCB = null;
private CHCNetSDK.MSGCallBack_V31 m_falarmData_V31 = null;
private CHCNetSDK.MSGCallBack m_falarmData = null;
public event EventHandler<PassengerFlowStatisticsModel> ActionEvent;
public event EventHandler<string> ExceptionEvent;
private int lUserID;
private int lAlarmHandle;
private int iListenHandle;
/// <summary>
/// 视频设备SDK初始化
/// </summary>
/// <returns></returns>
public bool Init()
{
bool m_bInitSDK = CHCNetSDK.NET_DVR_Init();
if (!m_bInitSDK)
{
return false;
}
//保存SDK日志 To save the SDK log
CHCNetSDK.NET_DVR_SetLogToFile(3, Path.Combine(AppContext.BaseDirectory, "SdkLog"), true);
//设置透传报警信息类型
CHCNetSDK.NET_DVR_LOCAL_GENERAL_CFG struLocalCfg = new CHCNetSDK.NET_DVR_LOCAL_GENERAL_CFG();
struLocalCfg.byAlarmJsonPictureSeparate = 1;//控制JSON透传报警数据和图片是否分离0-不分离(COMM_VCA_ALARM返回)1-分离分离后走COMM_ISAPI_ALARM回调返回
Int32 nSize = Marshal.SizeOf(struLocalCfg);
IntPtr ptrLocalCfg = Marshal.AllocHGlobal(nSize);
Marshal.StructureToPtr(struLocalCfg, ptrLocalCfg, false);
if (!CHCNetSDK.NET_DVR_SetSDKLocalCfg(17, ptrLocalCfg)) //NET_DVR_LOCAL_CFG_TYPE_GENERAL
{
var iLastErr = CHCNetSDK.NET_DVR_GetLastError();
var strErr = "NET_DVR_SetSDKLocalCfg failed, error code= " + iLastErr;
throw new Exception(strErr);
}
Marshal.FreeHGlobal(ptrLocalCfg);
//设置异常消息回调函数
if (m_fExceptionCB == null)
{
m_fExceptionCB = new CHCNetSDK.EXCEPYIONCALLBACK(cbExceptionCB);
}
CHCNetSDK.NET_DVR_SetExceptionCallBack_V30(0, IntPtr.Zero, m_fExceptionCB, IntPtr.Zero);
//设置报警回调函数
if (m_falarmData_V31 == null)
{
m_falarmData_V31 = new CHCNetSDK.MSGCallBack_V31(ProcessCommAlarm_PDC);
}
CHCNetSDK.NET_DVR_SetDVRMessageCallBack_V31(m_falarmData_V31, IntPtr.Zero);
return true;
}
/// <summary>
/// 释放SDK资源
/// </summary>
public void CleaUp()
{
//释放SDK资源在程序结束之前调用
CHCNetSDK.NET_DVR_Cleanup();
}
/// <summary>
/// 登录视频设备
/// </summary>
/// <param name="ipAddress">Ip地址</param>
/// <param name="port">端口</param>
/// <param name="name">用户名</param>
/// <param name="pwd">密码</param>
public void Login(string ipAddress, int port, string userName, string password)
{
CHCNetSDK.NET_DVR_USER_LOGIN_INFO struLogInfo = new CHCNetSDK.NET_DVR_USER_LOGIN_INFO();
//设备IP地址或者域名
byte[] byIP = System.Text.Encoding.Default.GetBytes(ipAddress);
struLogInfo.sDeviceAddress = new byte[129];
byIP.CopyTo(struLogInfo.sDeviceAddress, 0);
//设备用户名
byte[] byUserName = System.Text.Encoding.Default.GetBytes(userName);
struLogInfo.sUserName = new byte[64];
byUserName.CopyTo(struLogInfo.sUserName, 0);
//设备密码
byte[] byPassword = System.Text.Encoding.Default.GetBytes(password);
struLogInfo.sPassword = new byte[64];
byPassword.CopyTo(struLogInfo.sPassword, 0);
struLogInfo.wPort = (ushort)port;//设备服务端口号
struLogInfo.cbLoginResult = LoginCallBack;
struLogInfo.bUseAsynLogin = false; //是否异步登录0- 否1- 是
if ((struLogInfo.bUseAsynLogin == true) && (LoginCallBack == null))
{
LoginCallBack = new CHCNetSDK.LOGINRESULTCALLBACK((lUserID, dwResult, lpDeviceInfo, pUser) => //注册回调函数
{
string strLoginCallBack = $"登录设备lUserID{lUserID}dwResult{dwResult}";
if (dwResult == 0)
{
uint iErrCode = CHCNetSDK.NET_DVR_GetLastError();
strLoginCallBack += ",错误号:" + iErrCode;
throw new Exception(strLoginCallBack);
}
else
{
strLoginCallBack.WriteInfoLog();
}
});
}
struLogInfo.byLoginMode = 0; //0-Private, 1-ISAPI, 2-自适应
struLogInfo.byHttps = 0; //0-不适用tls1-使用tls 2-自适应
CHCNetSDK.NET_DVR_DEVICEINFO_V40 DeviceInfo = new CHCNetSDK.NET_DVR_DEVICEINFO_V40();
//登录设备 Login the device
var m_lUserID = CHCNetSDK.NET_DVR_Login_V40(ref struLogInfo, ref DeviceInfo);
if (m_lUserID < 0)
{
var iLastErr = CHCNetSDK.NET_DVR_GetLastError();
var strErr = $"NET_DVR_Login_V30 failed, error code= {iLastErr}"; //登录失败,输出错误号 Failed to login and output the error code
throw new Exception(strErr);
}
}
/// <summary>
/// 登出
/// </summary>
public void Logout()
{
if (lUserID > 0)
{
CHCNetSDK.NET_DVR_Logout(lUserID);
lUserID = -1;
}
}
/// <summary>
/// 部防
/// </summary>
/// <param name="listenIpAddress"></param>
public void OpenAlarm()
{
CHCNetSDK.NET_DVR_SETUPALARM_PARAM struAlarmParam = new CHCNetSDK.NET_DVR_SETUPALARM_PARAM();
struAlarmParam.dwSize = (uint)Marshal.SizeOf(struAlarmParam);
struAlarmParam.byLevel = 1; //0- 一级布防,1- 二级布防
struAlarmParam.byAlarmInfoType = 1;//智能交通设备有效,新报警信息类型
struAlarmParam.byFaceAlarmDetection = 1;//1-人脸侦测
lAlarmHandle = CHCNetSDK.NET_DVR_SetupAlarmChan_V41(lUserID, ref struAlarmParam);
if (lAlarmHandle < 0)
{
var iLastErr = CHCNetSDK.NET_DVR_GetLastError();
var strErr = $"布防失败,错误号:{iLastErr}"; //布防失败,输出错误号
throw new Exception(strErr) ;
}
else
{
"布防成功".WriteInfoLog();
}
}
/// <summary>
/// 撤防
/// </summary>
public void CloseAlarm()
{
if (lAlarmHandle < 0)
{
return;
}
if (!CHCNetSDK.NET_DVR_CloseAlarmChan_V30(lAlarmHandle))
{
var iLastErr = CHCNetSDK.NET_DVR_GetLastError();
var strErr = "撤防失败,错误号:" + iLastErr; //撤防失败,输出错误号
throw new Exception(strErr);
}
else
{
"撤防成功".WriteInfoLog();
lAlarmHandle = -1;
}
}
/// <summary>
/// 启用监听
/// </summary>
/// <param name="ListenIpAddress"></param>
public void StartListen(string listenIpAddress,int port)
{
if (m_falarmData == null)
{
m_falarmData = new CHCNetSDK.MSGCallBack(MsgCallback);
}
iListenHandle = CHCNetSDK.NET_DVR_StartListen_V30(listenIpAddress, (ushort)port, m_falarmData, IntPtr.Zero);
if (iListenHandle < 0)
{
var iLastErr = CHCNetSDK.NET_DVR_GetLastError();
var strErr = "启动监听失败,错误号:" + iLastErr; //撤防失败,输出错误号
throw new Exception(strErr);
}
else
{
"成功启动监听!".WriteInfoLog();
}
}
/// <summary>
/// 关闭监听
/// </summary>
public void CloseListen(string ListenIpAddress)
{
if (iListenHandle < 0)
{
return;
}
if (!CHCNetSDK.NET_DVR_StopListen_V30(iListenHandle))
{
var iLastErr = CHCNetSDK.NET_DVR_GetLastError();
var strErr = "停止监听失败,错误号:" + iLastErr; //撤防失败,输出错误号
throw new Exception(strErr);
}
else
{
"停止监听!".WriteInfoLog();
iListenHandle = -1;
}
}
private void cbExceptionCB(uint dwType, int lUserID, int lHandle, IntPtr pUser)
{
//异常消息信息类型
string stringAlarm = $"异常消息回调信息类型0x{Convert.ToString(dwType, 16)}, lUserID:{lUserID}, lHandle:{lHandle}";
}
private void MsgCallback(int lCommand, ref CHCNetSDK.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo, uint dwBufLen, IntPtr pUser)
{
//通过lCommand来判断接收到的报警信息类型不同的lCommand对应不同的pAlarmInfo内容
ProcessCommAlarm_PDC(lCommand, ref pAlarmer, pAlarmInfo, dwBufLen, pUser);
}
private bool ProcessCommAlarm_PDC(int lCommand, ref CHCNetSDK.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo, uint dwBufLen, IntPtr pUser)
{
//只记录客流统计
if (lCommand != CHCNetSDK.COMM_ALARM_PDC)
{
return true;
}
CHCNetSDK.NET_DVR_PDC_ALRAM_INFO struPDCInfo = new CHCNetSDK.NET_DVR_PDC_ALRAM_INFO();
uint dwSize = (uint)Marshal.SizeOf(struPDCInfo);
struPDCInfo = (CHCNetSDK.NET_DVR_PDC_ALRAM_INFO)Marshal.PtrToStructure(pAlarmInfo, typeof(CHCNetSDK.NET_DVR_PDC_ALRAM_INFO));
string stringAlarm = $"客流量统计,进入人数:{struPDCInfo.dwEnterNum},离开人数:{struPDCInfo.dwLeaveNum}";
uint dwUnionSize = (uint)Marshal.SizeOf(struPDCInfo.uStatModeParam);
IntPtr ptrPDCUnion = Marshal.AllocHGlobal((Int32)dwUnionSize);
Marshal.StructureToPtr(struPDCInfo.uStatModeParam, ptrPDCUnion, false);
if (struPDCInfo.byMode == 0) //单帧统计结果此处为UTC时间
{
m_struStatFrame = (CHCNetSDK.UNION_STATFRAME)Marshal.PtrToStructure(ptrPDCUnion, typeof(CHCNetSDK.UNION_STATFRAME));
stringAlarm = $"{stringAlarm},单帧统计,相对时标:{m_struStatFrame.dwRelativeTime},绝对时标:{m_struStatFrame.dwAbsTime}";
}
string strStartTime=string.Empty, strEndTime=string.Empty;
if (struPDCInfo.byMode == 1) //最小时间段统计结果
{
m_struStatTime = (CHCNetSDK.UNION_STATTIME)Marshal.PtrToStructure(ptrPDCUnion, typeof(CHCNetSDK.UNION_STATTIME));
//开始时间
strStartTime = string.Format("{0:D4}", m_struStatTime.tmStart.dwYear) +
string.Format("{0:D2}", m_struStatTime.tmStart.dwMonth) +
string.Format("{0:D2}", m_struStatTime.tmStart.dwDay) + " "
+ string.Format("{0:D2}", m_struStatTime.tmStart.dwHour) + ":"
+ string.Format("{0:D2}", m_struStatTime.tmStart.dwMinute) + ":"
+ string.Format("{0:D2}", m_struStatTime.tmStart.dwSecond);
//结束时间
strEndTime = string.Format("{0:D4}", m_struStatTime.tmEnd.dwYear) +
string.Format("{0:D2}", m_struStatTime.tmEnd.dwMonth) +
string.Format("{0:D2}", m_struStatTime.tmEnd.dwDay) + " "
+ string.Format("{0:D2}", m_struStatTime.tmEnd.dwHour) + ":"
+ string.Format("{0:D2}", m_struStatTime.tmEnd.dwMinute) + ":"
+ string.Format("{0:D2}", m_struStatTime.tmEnd.dwSecond);
stringAlarm = $"{stringAlarm},最小时间段统计,开始时间:{strStartTime},结束时间:{strEndTime}";
}
Marshal.FreeHGlobal(ptrPDCUnion);
//写入日志
stringAlarm.WriteInfoLog();
//报警设备IP地址
string strIP = Encoding.UTF8.GetString(pAlarmer.sDeviceIP).TrimEnd('\0');
var model = new PassengerFlowStatisticsModel
{
EnterNum = (int)struPDCInfo.dwEnterNum,
LeaveNum= (int)struPDCInfo.dwLeaveNum,
StartTime=DateTime.Parse(strStartTime),
EndTime= DateTime.Parse(strEndTime),
};
ActionEvent?.Invoke(this, model);
return true;
}
}
}

@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GuideScreen.Common.Services.Models
{
/// <summary>
/// 客流统计 model
/// </summary>
public class PassengerFlowStatisticsModel
{
/// <summary>
/// 主键 ID
/// </summary>
public int ID { get; set; }
/// <summary>
/// 进入人数
/// </summary>
public int EnterNum { get; set; }
/// <summary>
/// 离开人数
/// </summary>
public int LeaveNum { get; set; }
/// <summary>
/// 开始时间
/// </summary>
public DateTime StartTime { get; set; }
/// <summary>
/// 结束时间
/// </summary>
public DateTime EndTime { get; set; }
/// <summary>
/// 设备IP
/// </summary>
public string DeviceIP { get; set; }
}
}

@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GuideScreen.Common.Services.Models
{
internal class PassengerFlowStatisticsTotalModel
{
/// <summary>
/// x轴类型名称
/// </summary>
public string XTypeName { get; set; }
/// <summary>
/// 进入人数
/// </summary>
public int EnterNum { get; set; }
/// <summary>
/// 离开人数
/// </summary>
public int LeaveNum { get; set; }
}
}
Loading…
Cancel
Save