Files
Web_CRICS_Server_VS2010_Prod/RCUHost/Implement/ServiceReceiver.cs
2025-12-11 09:17:16 +08:00

399 lines
15 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Common;
using Dao;
using Domain;
using RCUHost.Protocols;
namespace RCUHost.Implement
{
public class ServiceReceiver : GenericReceiverBase, IServiceReceiver
{
private static log4net.ILog logger = log4net.LogManager.GetLogger(typeof(ServiceReceiver));
private ConcurrentDictionary<string, ConcurrentDictionary<int, ServiceStatus>> roomsServices = new ConcurrentDictionary<string, ConcurrentDictionary<int, ServiceStatus>>();
public IHostRepository HostRepository { get; set; }
public IAlarmSettingRepository AlarmSettingRepository { get; set; }
public IRoomServiceRepository RoomServiceRepository { get; set; }
public IRoomServiceRecordRepository RoomServiceRecordRepository { get; set; }
public void SetService(Host host, int serviceCode, int status)
{
byte[] data = CreateServiceControlDataPacket(serviceCode, status);
SendAndPushCommandQueue(data, host.HostNumber, host.MAC);// host.IP, host.Port);
}
public override void Process(ReceiverContext context)
{
bool bkb = GenericReceiverBase.DealWwith(context);
if (bkb == false)
{
return;
}
Reply(context);
Host host = HostRepository.GetByHostNumber(context.SystemHeader.Value.HostNumber.ToString());//.RemoteEndPoint.Address.ToString());
if (host != null)
{
try
{
int offset = StructConverter.SizeOf(context.SystemHeader);
int length = context.Data.Length - offset - 2;
using (MemoryStream stream = new MemoryStream(context.Data, offset, length))
{
var services = DecodeServices(host.IP, stream);
foreach (var service in services)
{
if (service.Value.Status != 2)
{
//处理服务
ProcessServices(host, service.Value);
//设置Host表的保险箱状态
if (service.Value.Code == 12)
{
HostRepository.SetSafeBoxStatus(host, service.Value.Status);
}
//处理异常
ProcessAbnormities(host, service.Value);
}
}
}
}
catch (Exception ex)
{
if (logger.IsErrorEnabled)
{
logger.Error(context.RemoteEndPoint.Address.ToString() + ":" + context.RemoteEndPoint.Port.ToString() + ":" + Tools.ByteToString(context.Data));
logger.Error("解析【" + host.HostNumber + "】客房服务数据出错。", ex);
}
}
}
}
/// <summary>
/// 处理服务
/// </summary>
/// <param name="host"></param>
/// <param name="status"></param>
private void ProcessServices(Host host, ServiceStatus status)
{
var serviceSetting = AlarmSettingRepository.Get(host.SysHotel.ID, 'B', status.Code);
if (serviceSetting != null && status.Status != 2)
{
//更新客房服务状态
var roomService = RoomServiceRepository.Get(host.ID, serviceSetting.Code);
if (roomService != null && roomService.Status != Convert.ToBoolean(status.Status))
{
roomService.Status = Convert.ToBoolean(status.Status);
roomService.StartTime = DateTime.Now;
RoomServiceRepository.Update(roomService);
}
if (status.Status == 0)
{
//更新清除服务记录状态和时间
var serviceRecord = RoomServiceRecordRepository.Get(host.ID, serviceSetting.Code, true);
if (serviceRecord != null)
{
serviceRecord.Status = false;
serviceRecord.EndTime = DateTime.Now;
RoomServiceRecordRepository.Update(serviceRecord);
}
}
else if (status.Status == 1)
{
//判断数据库中是否存在服务开启记录,不存在才去记录服务
var existServiceRecord = RoomServiceRecordRepository.Get(host.ID, serviceSetting.Code, true);
if (existServiceRecord == null)
{
var serviceRecord = new RoomServiceRecord();
serviceRecord.HostID = host.ID;
serviceRecord.RoomNumber = host.RoomNumber;
serviceRecord.AlarmCode = serviceSetting.Code;
serviceRecord.Name = serviceSetting.Name;
serviceRecord.Status = true;
serviceRecord.StartTime = DateTime.Now;
RoomServiceRecordRepository.Save(serviceRecord);
}
}
//给FreeGo福瑞狗上报服务状态
//FreeGoOperation.UploadService(host.SysHotel.Code, host.RoomNumber, serviceSetting.Name, status.Status.ToString());
}
}
/// <summary>
/// 处理异常
/// </summary>
/// <param name="host"></param>
/// <param name="status"></param>
private void ProcessAbnormities(Host host, ServiceStatus status)
{
#region
var abnormitySetting = AlarmSettingRepository.Get(host.SysHotel.ID, 'C', "C03", status.Code);
if (abnormitySetting != null)
{
var abnormity = RoomServiceRepository.Get(host.ID, abnormitySetting.Code);
bool isUpdated = false;
if (status.Status == 1)
{
//保险箱开 如果非客人卡且出租房态,则报警
if (host.RoomCard != null && host.RoomCard.RoomCardType != null && host.RoomCard.RoomCardType.ID != 0x20 &&
host.RoomStatus != null && host.RoomStatus.ID == 0x02)
{
isUpdated = true;
if (abnormity != null && !abnormity.Status)
{
abnormity.Status = true;
abnormity.StartTime = DateTime.Now;
RoomServiceRepository.Update(abnormity);
//插入保险箱开的记录
var abnormityRecord = RoomServiceRecordRepository.Get(host.ID, abnormitySetting.Code, true);
if (abnormityRecord == null)
{
abnormityRecord = RoomServiceRecordRepository.CreateServiceRecord(host, abnormitySetting);
RoomServiceRecordRepository.Save(abnormityRecord);
}
}
}
}
//保险箱关或未接保险箱(关掉报警)
if (!isUpdated)
{
if (abnormity != null && abnormity.Status)
{
abnormity.Status = false;//取消报警
abnormity.StartTime = DateTime.Now;
RoomServiceRepository.Update(abnormity);
//更新保险箱关的记录
var abnormityRecord = RoomServiceRecordRepository.Get(host.ID, abnormitySetting.Code, true);
if (abnormityRecord != null)
{
abnormityRecord.Status = false;
abnormityRecord.EndTime = DateTime.Now;
RoomServiceRecordRepository.Update(abnormityRecord);
}
}
}
}
#endregion
#region 退
abnormitySetting = AlarmSettingRepository.Get(host.SysHotel.ID, 'C', "C04", status.Code);
var abnormity1 = RoomServiceRepository.Get(host.ID, "C04");
if (abnormitySetting != null && abnormity1 != null)
{
bool isUpdated = false;
if (status.Status == 0)
{
//保险箱关 如果是“退房”状态,则报警
if (host.RoomStatus != null && host.RoomStatus.ID == 0x08)
{
isUpdated = true;
if (!abnormity1.Status)
{
abnormity1.Status = true;
abnormity1.StartTime = DateTime.Now;
RoomServiceRepository.Update(abnormity1);
//异常记录
var abnormityRecord = RoomServiceRecordRepository.Get(host.ID, abnormitySetting.Code, true);
if (abnormityRecord == null)
{
abnormityRecord = RoomServiceRecordRepository.CreateServiceRecord(host, abnormitySetting);
RoomServiceRecordRepository.Save(abnormityRecord);
}
}
}
}
if (!isUpdated)
{
//保险箱开或未接保险箱(关掉报警)
if (abnormity1.Status)
{
abnormity1.Status = false;
abnormity1.StartTime = DateTime.Now;
RoomServiceRepository.Update(abnormity1);
//异常记录
var abnormityRecord = RoomServiceRecordRepository.Get(host.ID, abnormitySetting.Code, true);
if (abnormityRecord != null)
{
abnormityRecord.Status = false;
abnormityRecord.EndTime = DateTime.Now;
RoomServiceRecordRepository.Update(abnormityRecord);
}
}
}
}
#endregion
}
/// <summary>
/// 创建服务控制数据包
/// </summary>
/// <param name="devices"></param>
/// <returns></returns>
public byte[] CreateServiceControlDataPacket(int serviceCode, int status)
{
using (MemoryStream buffer = new MemoryStream())
{
using (BinaryWriter writer = new BinaryWriter(buffer))
{
var headerLen = StructConverter.SizeOf(typeof(SystemHeader));
buffer.Seek(headerLen, SeekOrigin.Begin);
writer.Write((byte)1); //写入服务数量
writer.Write((byte)serviceCode); //写入服务代码
writer.Write((byte)status); //写入服务状态
writer.Write(new byte[] { 0, 0 }, 0, 2);//预留两字节CRC16校验码
buffer.Seek(0, SeekOrigin.Begin);
var header = CreateSystemHeader((int)buffer.Length - headerLen);
var headerData = StructConverter.StructToBytes(header);
writer.Write(headerData, 0, headerData.Length);
return buffer.ToArray();
}
}
}
public override CommandType CommandType
{
get { return CommandType.Service; }
}
/// <summary>
/// 解析服务状态
/// </summary>
/// <param name="stream"></param>
/// <returns></returns>
private ConcurrentDictionary<int, ServiceStatus> DecodeServices(string hostIP, Stream stream)
{
ConcurrentDictionary<int, ServiceStatus> services = null;
if (roomsServices.ContainsKey(hostIP))
{
services = roomsServices[hostIP];
}
else
{
services = new ConcurrentDictionary<int, ServiceStatus>();
roomsServices[hostIP] = services;
}
using (BinaryReader reader = new BinaryReader(stream))
{
try
{
int count = reader.ReadByte();//读取服务数量
for (int i = 0; i < count; i++)
{
ServiceStatus serviceStatus = null;
int serviceCode = reader.ReadByte();//读取服务代码
if (services.ContainsKey(serviceCode))
{
serviceStatus = services[serviceCode];
}
else
{
serviceStatus = new ServiceStatus();
services[serviceCode] = serviceStatus;
}
serviceStatus.Code = serviceCode;
serviceStatus.Status = reader.ReadByte();//读取服务状态
}
}
catch (Exception) { }
return services;
}
}
}
internal class ServiceStatus
{
private int code;
private int status = 2;
public int Code
{
get { return this.code; }
set
{
this.code = value;
}
}
public int Status
{
get { return this.status; }
set
{
this.status = value;
}
}
}
internal delegate void ServiceChangedDelegate(string hostIP, ServiceStatus serviceStatus);
internal class RoomServiceCache
{
private Hashtable services = new Hashtable();
public string HostIP { get; set; }
public event ServiceChangedDelegate ServiceChanged;
public void AddOrUpdate(int code, int status)
{
ServiceStatus service = services[code] as ServiceStatus;
if (service != null)
{
if (service.Status != status)
{
service.Status = status;
RasieServiceChanged(service);
}
}
else
{
service = new ServiceStatus();
service.Code = code;
service.Status = status;
services[code] = service;
RasieServiceChanged(service);
}
}
public IList<ServiceStatus> Services
{
get
{
IList<ServiceStatus> values = new List<ServiceStatus>();
foreach (var service in services.Values)
{
values.Add((ServiceStatus)service);
}
return values;
}
}
private void RasieServiceChanged(ServiceStatus serviceStatus)
{
if (ServiceChanged != null)
{
ServiceChanged(HostIP, serviceStatus);
}
}
}
}