xm
2020-12-10 3aa397ab145382935492b11c1f18c9634e69910b
ZigbeeApp/Shared/Phone/UserCenter/CommonBase/Logic/HdlGatewayReceiveLogic.cs
old mode 100755 new mode 100644
@@ -5,1262 +5,1388 @@
using ZigBee.Device;
namespace Shared.Phone.UserCenter
{
{
  /// <summary>
  /// 全局接收网关推送的的逻辑(为了执行速度,尽可能的别加耗时的操作)
  /// </summary>
  public class HdlGatewayReceiveLogic
  {
    #region ■ 变量声明___________________________
    /// <summary>
    /// 全局接收网关推送的的逻辑
    /// </summary>
    private static HdlGatewayReceiveLogic m_Current = null;
    /// <summary>
    /// 全局接收网关推送的的逻辑
    /// </summary>
    public static HdlGatewayReceiveLogic Current
    {
      get
      {
        if (m_Current == null)
        {
          m_Current = new HdlGatewayReceiveLogic();
        }
        return m_Current;
      }
    }
    /// <summary>
    /// 网关接收事件(参数1:主题 参数2:推送消息)
    /// </summary>
    private Action<string, string> GatewayReceiveEvent = null;
    /// <summary>
    /// 接收网关的id
    /// </summary>
    private string GatewayReceiveId = null;
    /// <summary>
    /// 设备推送事件集合
    /// </summary>
    private Dictionary<string, Action<CommonDevice>> dicDeviceEvent = new Dictionary<string, Action<CommonDevice>>();
    /// <summary>
    /// 命令区分
    /// </summary>
    private Dictionary<string, ReceiveComandDiv> dicCommandDiv = new Dictionary<string, ReceiveComandDiv>();
    #endregion
    #region ■ 全局接收___________________________
    /// <summary>
    /// 全局接收网关推送的的逻辑(为了执行速度,尽可能的别加耗时的操作)
    /// </summary>
    public class HdlGatewayReceiveLogic
    {
        #region ■ 变量声明___________________________
        /// <summary>
        /// 全局接收网关推送的的逻辑
        /// </summary>
        private static HdlGatewayReceiveLogic m_Current = null;
        /// <summary>
        /// 全局接收网关推送的的逻辑
        /// </summary>
        public static HdlGatewayReceiveLogic Current
        {
            get
            {
                if (m_Current == null)
                {
                    m_Current = new HdlGatewayReceiveLogic();
                }
                return m_Current;
            }
        }
        /// <summary>
        /// 设备推送事件集合
        /// </summary>
        private Dictionary<string, Action<CommonDevice>> dicDeviceEvent = new Dictionary<string, Action<CommonDevice>>();
        /// <summary>
        /// 命令区分
        /// </summary>
        private Dictionary<string, ReceiveComandDiv> dicCommandDiv = new Dictionary<string, ReceiveComandDiv>();
        #endregion
        #region ■ 全局接收___________________________
        /// <summary>
        /// 全局接收网关推送的的逻辑(为了执行速度,尽可能的别加耗时的操作)
        /// </summary>
        /// <param name="gatewayId">网关ID</param>
        /// <param name="topic">整个主题</param>
        /// <param name="reportTopic">上报数据的主题</param>
        /// <param name="msgData">接收的数据</param>
        public void GatewayOverallMsgReceive(string gatewayId, string topic, string reportTopic, string msgData)
        {
            if (topic == "AppNoLogin")
            {
                HdlThreadLogic.Current.RunMain(() =>
                {
                    //登录密匙已经过期,请重新登录
                    string msg = Language.StringByID(R.MyInternationalizationString.uTokenIsOldAndLoginAgain);
                    var contr = new ShowMsgControl(ShowMsgType.Tip, msg);
                    contr.Show();
                    UserCenterLogic.ReLoginAgain(UserCenterResourse.UserInfo.Account, false);
                });
                return;
            }
            else if (topic == "ZigbeeGateWayToClient/" + Common.Config.Instance.ConnEmqClientId + "/Push/NotifySqueeze")
            {
                HdlThreadLogic.Current.RunMain(() =>
                {
                    //此帐号已在别处登录,您被迫下线
                    string msg = Language.StringByID(R.MyInternationalizationString.uHadBeenLoginAndOffLine);
                    var contr = new ShowMsgControl(ShowMsgType.Tip, msg);
                    contr.Show();
                    UserCenterLogic.ReLoginAgain(UserCenterResourse.UserInfo.Account, false);
                });
                return;
            }
            else if (topic == "YouIpAndPortNoRecord")
            {
                HdlThreadLogic.Current.RunMain(() =>
                {
                    //您当前的IP及端口在云端不存在,请重新登录!
                    string msg = Language.StringByID(R.MyInternationalizationString.uYouIpAndPortNoRecord);
                    var contr = new ShowMsgControl(ShowMsgType.Tip, msg);
                    contr.Show();
                    UserCenterLogic.ReLoginAgain(UserCenterResourse.UserInfo.Account, false);
                });
                return;
            }
            else if (topic == "ZigbeeGateWayToClient/" + Common.Config.Instance.Home.Id + "_" + Common.Config.Instance.Guid + "/PrimaryUserDelYou")
            {
                HdlThreadLogic.Current.RunMain(() =>
                {
                    //分享住宅已更改,请联系管理员!
                    string msg = Language.StringByID(R.MyInternationalizationString.uShardResidenceHadDeletePleaseTakeToAdmin);
                    var contr = new ShowMsgControl(ShowMsgType.Tip, msg);
                    contr.Show();
                    UserCenterLogic.ReLoginAgain(UserCenterResourse.UserInfo.Account, false);
                });
                return;
            }
            else if (topic == "ZigbeeGateWayToClient/" + Common.Config.Instance.Guid + "/Push/Update")
            {
                HdlThreadLogic.Current.RunMain(() =>
                {
                    //您的权限已经变更,请重新登陆
                    string msg = Language.StringByID(R.MyInternationalizationString.uYouAccessHadChangedPleaseTakeToAdmin);
                    var contr = new ShowMsgControl(ShowMsgType.Tip, msg);
                    contr.Show();
                    UserCenterLogic.ReLoginAgain(UserCenterResourse.UserInfo.Account, false);
                });
                return;
            }
            else if (UserCenterResourse.UserInfo.AuthorityNo == 3)
            {
                if (topic == "ZigbeeGateWayToClient/" + Common.Config.Instance.Guid + "/Push/Deleted"
                || topic == "ZigbeeGateWayToClient/" + Common.Config.Instance.Guid + "/Push/DeletedShareData")
                {
                    HdlThreadLogic.Current.RunMain(() =>
                    {
                        //分享数据已经变更,请重新登陆
                        string msg = Language.StringByID(R.MyInternationalizationString.uShardDataIsChangedPleaseLoginAgain);
                        var contr = new ShowMsgControl(ShowMsgType.Tip, msg);
                        contr.Show();
                        UserCenterLogic.ReLoginAgain(UserCenterResourse.UserInfo.Account, false);
                    });
                    return;
                }
            }
            try
            {
                if (HdlGatewayLogic.Current.IsGatewayExist(gatewayId) == false)
                {
                    //不是自己绑定的网关,则不处理
                    return;
                }
                //设备属性上报
                if (reportTopic == "DeviceStatusReport")
                {
                    //设备属性上报
                    this.DeviceAttributeReportPush(JObject.Parse(msgData));
                }
                //传感器上报
                else if (reportTopic == "IASInfoReport")
                {
                    this.SensorDeviceReportPush(JObject.Parse(msgData));
                }
                //门锁上报
                else if (topic == gatewayId + "/Alarms/SendAlarmInform")
                {
                    this.DoorLockDeviceReportPush(JObject.Parse(msgData));
                }
                //通过外部方式布防撤防成功时报告
                else if (topic == gatewayId + "/Security/EnOrWithdrawSucceedReport")
                {
                    this.SecurityEnOrWithdrawSucceedReport(JObject.Parse(msgData));
                }
                //设备在线状态更新反馈
                else if (reportTopic == "OnlineStatusChange_Respon")
                {
                    this.DeviceOnlineChangePush(JObject.Parse(msgData));
                }
                //设备控制状态反馈
                else if (reportTopic == "DeviceDefaultAck")
                {
                    this.DeviceControlResponePush(JObject.Parse(msgData));
                }
                //撤防
                else if (topic == gatewayId + "/Security/WithdrawMode_Respon")
                {
                    this.RemoveSafetyGarrisonPush(JObject.Parse(msgData));
                }
                //布防
                else if (topic == gatewayId + "/Security/EnableMode_Respon")
                {
                    this.SetSafetyGarrisonPush(JObject.Parse(msgData));
                }
                //逻辑触发上报
                else if (topic == gatewayId + "/Logic/Execute_Respon")
                {
                    this.LogicExecutePush(JObject.Parse(msgData));
                }
                //场景触发上报
                else if (topic == gatewayId + "/Scene/Exec_Respon")
                {
                    this.SceneExecPush(null);
                }
            }
            catch (Exception ex)
            {
                //Log出力
                HdlLogLogic.Current.WriteLog(ex);
            }
        }
        #endregion
        #region ■ 设备属性上报_______________________
        /// <summary>
        /// 设备属性上报
        /// </summary>
        /// <param name="receiveData"></param>
        private void DeviceAttributeReportPush(JObject receiveData)
        {
            if (this.dicDeviceEvent.Count == 0)
            {
                //没有添加监听
                return;
            }
            var deviceAddr = receiveData.Value<string>("DeviceAddr");
            var deviceEpoint = receiveData.Value<int>("Epoint");
            var report = new CommonDevice { DeviceAddr = deviceAddr, DeviceEpoint = deviceEpoint };
            report.DeviceStatusReport = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.DeviceStatusReportData>(receiveData["Data"].ToString());
            if (report.DeviceStatusReport.AttriBute.Count == 0)
            {
                //网关有些奇葩,没有属性它也会发过来
                return;
            }
            //处理网关上报的数据,然后变更本地缓存
            var locadevice = Common.LocalDevice.Current.GetDevice(deviceAddr, deviceEpoint);
            if (locadevice != null)
            {
                //有反馈,这个设备肯定是在线的
                locadevice.IsOnline = 1;
                locadevice.LastDateTime = DateTime.Now;
                #region ■ 开关功能
                //开关功能
                if (report.DeviceStatusReport.CluterID == 6)
                {
                    if (locadevice is LightBase)
                    {
                        locadevice.DeviceStatusReport = report.DeviceStatusReport;
                        ((LightBase)locadevice).OnOffStatus = report.DeviceStatusReport.AttriBute[0].AttriButeData;
                        //已经接收到状态
                        locadevice.HadReadDeviceStatu = true;
                    }
                }
                #endregion
                #region ■ 电量推送
                //电量推送
                if (report.DeviceStatusReport.CluterID == 1)
                {
                    foreach (var attData in report.DeviceStatusReport.AttriBute)
                    {
                        //电量
                        if (attData.AttributeId == 33)
                        {
                            string receiptData = string.Empty;
                            //两个两个位置替换
                            for (int i = attData.AttriButeDataHex.Length - 1; i >= 0; i = i - 2)
                            {
                                receiptData += attData.AttriButeDataHex[i - 1].ToString() + attData.AttriButeDataHex[i].ToString();
                            }
                            int batteryValue = Convert.ToInt32(receiptData, 16);
                            //低于20%,则代表电量低
                            locadevice.IsBatteryDown = batteryValue < 20;
                        }
                        //已经接收到状态
                        locadevice.HadReadDeviceStatu = true;
                    }
                }
                #endregion
                #region ■ 蜂鸣器推送
                //蜂鸣器数据
                else if (report.DeviceStatusReport.CluterID == 1282)
                {
                    //mini夜灯
                    if (Common.LocalDevice.Current.IsMiniLight(locadevice) == true)
                    {
                        foreach (var attData in report.DeviceStatusReport.AttriBute)
                        {
                            if (attData.AttributeId == 0)
                            {
                                //这个是报警持续时间(大于2秒时,标记为还在响着)
                                ((ColorTemperatureLight)locadevice).IsBuzzerRing = attData.AttriButeData > 2 ? true : false;
                            }
                        }
                    }
                }
                #endregion
                #region ■ 窗帘数据
                //窗帘数据
                else if (report.DeviceStatusReport.CluterID == 258)
                {
                    //窗帘类型
                    if (report.DeviceStatusReport.AttriBute[0].AttributeId == 0)
                    {
                        locadevice.DeviceStatusReport = report.DeviceStatusReport;
                        ((Rollershade)locadevice).WcdType = report.DeviceStatusReport.AttriBute[0].AttriButeData;
                        //这个东西要保存
                        locadevice.ReSave();
                    }
                    //窗帘百分比
                    else if (report.DeviceStatusReport.AttriBute[0].AttributeId == 8)
                    {
                        locadevice.DeviceStatusReport = report.DeviceStatusReport;
                        ((Rollershade)locadevice).WcdCurrentPositionLiftPercentage = report.DeviceStatusReport.AttriBute[0].AttriButeData;
                        //已经接收到状态
                        locadevice.HadReadDeviceStatu = true;
                    }
                }
                #endregion
                #region ■ 空调和新风数据
                //空调数据
                else if (report.DeviceStatusReport.CluterID == 513)
                {
                    locadevice.DeviceStatusReport = report.DeviceStatusReport;
                    foreach (var attData in report.DeviceStatusReport.AttriBute)
                    {
                        var curTemp = attData.AttriButeData / 100;
                        if (attData.AttributeId == 0)
                        {
                            //此属性表明室内当前的温度 * 100,实际温度为“LocalTemperature / 100”,单位:℃
                            ((AC)locadevice).currentLocalTemperature = curTemp;
                            //已经接收到状态
                            locadevice.HadReadDeviceStatu = true;
                        }
                        else if (attData.AttributeId == 17)
                        {
                            //此属性表明室内当前的温度 * 100,实际温度为“LocalTemperature / 100”,单位:℃
                            ((AC)locadevice).currentCoolingSetpoint = curTemp;
                            //已经接收到状态
                            locadevice.HadReadDeviceStatu = true;
                        }
                        else if (attData.AttributeId == 18)
                        {
                            //此属性表明此设备当前的制热温度,实际温度为“HeatingSetpoint / 100”,单位:℃。
                            ((AC)locadevice).currentHeatingSetpoint = curTemp;
                            //已经接收到状态
                            locadevice.HadReadDeviceStatu = true;
                        }
                        else if (attData.AttributeId == 28)
                        {
                            //此属性描述恒温设备正处于哪种模式
                            ((AC)locadevice).currentSystemMode = attData.AttriButeData;
                            //已经接收到状态
                            locadevice.HadReadDeviceStatu = true;
                        }
                        else if (attData.AttributeId == 4096)
                        {
                            //此属性表明此设备当前的自动温度,实际温度为“AutoSetpoint / 100”,单位:℃。
                            ((AC)locadevice).currentAutoSetpoint = curTemp;
                            //已经接收到状态
                            locadevice.HadReadDeviceStatu = true;
                        }
                        else if (attData.AttributeId == 4097)
                        {
                            //过虑网清洗标志:42
                            ((AC)locadevice).CleanStatu = attData.AttriButeData == 42;
                        }
                        else if (attData.AttributeId == 4099)
                        {
                            //转换为二进制
                            var value = Convert.ToString(attData.AttriButeData, 2).PadLeft(16, '0');
                            //这五个设置是放在后面的
                            value = value.Substring(value.Length - 5, 5);
                            for (int i = 0; i < value.Length; i++)
                            {
                                //自定义的空调模式
                                ((AC)locadevice).listSupportMode[i] = Convert.ToInt32(value[i].ToString());
                            }
                            locadevice.ReSave();
                        }
                    }
                }
                //空调数据
                else if (report.DeviceStatusReport.CluterID == 514)
                {
                    locadevice.DeviceStatusReport = report.DeviceStatusReport;
                    foreach (var attData in report.DeviceStatusReport.AttriBute)
                    {
                        //区分是空调还是新风
                        var device = Shared.Common.LocalDevice.Current.GetDevice(report.DeviceAddr, report.DeviceEpoint);
                        if (device.Type == DeviceType.FreshAir)
                        {
                            if (attData.AttributeId == 0)
                            {
                                switch (attData.AttriButeData)
                                {
                                    case 0:
                                    case 4:
                                        ((FreshAir)locadevice).currentFanStatus = attData.AttriButeData;
                                        break;
                                    case 1:
                                    case 2:
                                    case 3:
                                        ((FreshAir)locadevice).currentFanSpeed = attData.AttriButeData;
                                        break;
                                    case 5:
                                    case 15:
                                        ((FreshAir)locadevice).currentFanMode = attData.AttriButeData;
                                        break;
                                }
                                //已经接收到状态
                                locadevice.HadReadDeviceStatu = true;
                            }
                        }
                        else
                        {
                            if (attData.AttributeId == 0)
                            {
                                //风扇模式
                                ((AC)locadevice).currentFanMode = attData.AttriButeData;
                                //已经接收到状态
                                locadevice.HadReadDeviceStatu = true;
                            }
                            else if (attData.AttributeId == 4096)
                            {
                                //风扇扫风
                                ((AC)locadevice).currentFanSwingMode = attData.AttriButeData;
                                //已经接收到状态
                                locadevice.HadReadDeviceStatu = true;
                            }
                            else if (attData.AttributeId == 4097)
                            {
                                //转换为二进制
                                var value = Convert.ToString(attData.AttriButeData, 2).PadLeft(16, '0');
                                //这个设置是放在后面的
                                value = value.Substring(value.Length - 1, 1);
                                //启用摆风功能
                                ((AC)locadevice).UseSwingFunction = value == "1";
                                locadevice.ReSave();
                            }
                        }
                    }
                }
                #endregion
                #region ■ 亮度数据
                //亮度数据
                else if (report.DeviceStatusReport.CluterID == 8)
                {
                    locadevice.DeviceStatusReport = report.DeviceStatusReport;
                    if (report.DeviceStatusReport.AttriBute[0].AttributeId == 0)
                    {
                        if (locadevice.Type == DeviceType.DimmableLight)
                        {
                            //此属性表明当前亮度程度
                            ((DimmableLight)locadevice).Level = report.DeviceStatusReport.AttriBute[0].AttriButeData;
                        }
                        else if (locadevice.Type == DeviceType.ColorTemperatureLight)
                        {
                            //此属性表明当前亮度程度
                            ((ColorTemperatureLight)locadevice).Level = report.DeviceStatusReport.AttriBute[0].AttriButeData;
                        }
                        //已经接收到状态
                        locadevice.HadReadDeviceStatu = true;
                        //if (locadevice is LightBase)
                        //{
                        //    //当接收到亮度值时,默认打开
                        //    ((LightBase)locadevice).OnOffStatus = 1;
                        //}
                    }
                }
                #endregion
                #region ■ 色温数据
                //色温数据
                else if (report.DeviceStatusReport.CluterID == 768)
                {
                    locadevice.DeviceStatusReport = report.DeviceStatusReport;
                    if (report.DeviceStatusReport.AttriBute[0].AttributeId == 0)
                    {
                        if (locadevice.Type == DeviceType.ColorTemperatureLight)
                        {
                            //此属性表明当前色温
                            int value = report.DeviceStatusReport.AttriBute[0].AttriButeData != 0 ? 1000000 / report.DeviceStatusReport.AttriBute[0].AttriButeData : 0;
                            ((ColorTemperatureLight)locadevice).ColorTemperature = value;
                        }
                        //已经接收到状态
                        locadevice.HadReadDeviceStatu = true;
                    }
                }
                #endregion
                #region ■ 温度数据
                //温度数据
                else if (report.DeviceStatusReport.CluterID == 1026)
                {
                    foreach (var attData in report.DeviceStatusReport.AttriBute)
                    {
                        //温度
                        if (attData.AttributeId == (int)AttriButeId.MeasuredValue)
                        {
                            decimal temperatrue = 0;
                            string receiptData = string.Empty;
                            //两个两个位置替换
                            for (int i = attData.AttriButeDataHex.Length - 1; i >= 0; i = i - 2)
                            {
                                receiptData += attData.AttriButeDataHex[i - 1].ToString() + attData.AttriButeDataHex[i].ToString();
                            }
                            //有符号(会出现负数)
                            if (attData.AttriButeDataType == 40 || attData.AttriButeDataType == 41)
                            {
                                //小数点需要一位
                                string strValue = Convert.ToInt16(receiptData, 16).ToString();
                                strValue = strValue.Substring(0, strValue.Length - 1);
                                temperatrue = Convert.ToDecimal(strValue.Insert(strValue.Length - 1, "."));
                            }
                            //无符号(不会出现负数)
                            else if (attData.AttriButeDataType == 32 || attData.AttriButeDataType == 33)
                            {
                                ushort shortData = Convert.ToUInt16(receiptData, 16);
                                if (shortData > 32767)
                                {
                                    //负数(特殊处理)
                                    string strValue = (shortData - 65536).ToString();
                                    //小数点需要一位
                                    strValue = strValue.Substring(0, strValue.Length - 1);
                                    temperatrue = Convert.ToDecimal(strValue.Insert(strValue.Length - 1, "."));
                                }
                                else
                                {
                                    //小数点需要一位
                                    string strValue = shortData.ToString();
                                    strValue = strValue.Substring(0, strValue.Length - 1);
                                    temperatrue = Convert.ToDecimal(strValue.Insert(strValue.Length - 1, "."));
                                }
                            }
                            //温度传感器
                            if (locadevice is TemperatureSensor)
                            {
                                ((TemperatureSensor)locadevice).currentTemperature = temperatrue;
                            }
                            //PM2.5传感器
                            else if (locadevice is PMSensor)
                            {
                                ((PMSensor)locadevice).currentTemperature = (int)temperatrue;
                            }
                            //已经接收到状态
                            locadevice.HadReadDeviceStatu = true;
                            //温度值需要保存
                            locadevice.ReSave();
                        }
                    }
                }
                #endregion
                #region ■ 湿度数据
                //湿度数据
                else if (report.DeviceStatusReport.CluterID == 1029)
                {
                    foreach (var attData in report.DeviceStatusReport.AttriBute)
                    {
                        //湿度
                        if (attData.AttributeId == (int)AttriButeId.MeasuredValue)
                        {
                            decimal humidity = 0;
                            string receiptData = string.Empty;
                            //两个两个位置替换
                            for (int i = attData.AttriButeDataHex.Length - 1; i >= 0; i = i - 2)
                            {
                                receiptData += attData.AttriButeDataHex[i - 1].ToString() + attData.AttriButeDataHex[i].ToString();
                            }
                            //有符号(会出现负数)
                            if (attData.AttriButeDataType == 40 || attData.AttriButeDataType == 41)
                            {
                                //小数点需要一位
                                string strValue = Convert.ToInt16(receiptData, 16).ToString();
                                strValue = strValue.Substring(0, strValue.Length - 1);
                                humidity = Convert.ToDecimal(strValue.Insert(strValue.Length - 1, "."));
                            }
                            //无符号(不会出现负数)
                            else if (attData.AttriButeDataType == 32 || attData.AttriButeDataType == 33)
                            {
                                //小数点需要一位 湿度不会出现负数
                                string strValue = Convert.ToUInt16(receiptData, 16).ToString();
                                strValue = strValue.Substring(0, strValue.Length - 1);
                                humidity = Convert.ToDecimal(strValue.Insert(strValue.Length - 1, "."));
                            }
                            //湿度传感器
                            if (locadevice is TemperatureSensor)
                            {
                                ((TemperatureSensor)locadevice).currentHumidity = humidity;
                            }
                            //新风的湿度传感器
                            else if (locadevice is HumiditySensor)
                            {
                                ((HumiditySensor)locadevice).currentHumidity = humidity;
                            }
                            //PM2.5传感器
                            else if (locadevice is PMSensor)
                            {
                                ((PMSensor)locadevice).currentHumidity = (int)humidity;
                            }
                            //已经接收到状态
                            locadevice.HadReadDeviceStatu = true;
                            //湿度值需要保存
                            locadevice.ReSave();
                        }
                    }
                }
                #endregion
                #region ■ PM2.5数据
                //PM2.5数据
                else if (report.DeviceStatusReport.CluterID == 1066)
                {
                    foreach (var attData in report.DeviceStatusReport.AttriBute)
                    {
                        //PM2.5
                        if (attData.AttributeId == (int)AttriButeId.MeasuredValue)
                        {
                            if (attData.AttriButeDataType == 57)
                            {
                                ((PMSensor)locadevice).currentPmData = attData.AttriButeData;
                            }
                        }
                        //已经接收到状态
                        locadevice.HadReadDeviceStatu = true;
                    }
                }
                #endregion
                #region ■ 设备基础信息
                else if (report.DeviceStatusReport.CluterID == 0)
                {
                    var listLocalDevice = Common.LocalDevice.Current.GetDevicesByMac(deviceAddr, false);
                    //属性都是一样的
                    foreach (var myDevice in listLocalDevice)
                    {
                        //属性是否改变
                        bool attriButeChanged = false;
                        foreach (var data in report.DeviceStatusReport.AttriBute)
                        {
                            //生产商名字
                            if (data.AttributeId == 4 && data.AttriButeDataHex.Length > 2)
                            {
                                if (data.AttriButeDataHex.Length > 2)
                                {
                                    var value = UserCenterLogic.TranslateHexadecimalIntoText(data.AttriButeDataHex.Substring(2));
                                    if (myDevice.ManufacturerName != value)
                                    {
                                        //属性变更了
                                        attriButeChanged = true;
                                    }
                                    myDevice.ManufacturerName = value;
                                }
                            }
                            //型号码(也叫模块ID)
                            if (data.AttributeId == 5)
                            {
                                if (data.AttriButeDataHex.Length > 2)
                                {
                                    var value = UserCenterLogic.TranslateHexadecimalIntoText(data.AttriButeDataHex.Substring(2));
                                    if (myDevice.ModelIdentifier != value)
                                    {
                                        //属性变更了
                                        attriButeChanged = true;
                                    }
                                    myDevice.ModelIdentifier = value;
                                }
                            }
                            //生产日期
                            if (data.AttributeId == 6)
                            {
                                if (data.AttriButeDataHex.Length > 2)
                                {
                                    var value = UserCenterLogic.TranslateHexadecimalIntoText(data.AttriButeDataHex.Substring(2));
                                    if (myDevice.ProductionDate != value)
                                    {
                                        //属性变更了
                                        attriButeChanged = true;
                                    }
                                    myDevice.ProductionDate = value;
                                }
                            }
                            //电源
                            if (data.AttributeId == 7)
                            {
                                myDevice.PowerSource = data.AttriButeData;
                            }
                            //序列号
                            if (data.AttributeId == 13)
                            {
                                if (data.AttriButeDataHex.Length > 2)
                                {
                                    string value;
                                    if (Common.LocalDevice.Current.IsHdlDevice(myDevice) == false)
                                    {
                                        //第三方设备
                                        value = data.AttriButeDataHex.Substring(2);
                                    }
                                    else
                                    {
                                        //河东设备
                                        value = UserCenterLogic.TranslateHexadecimalIntoText(data.AttriButeDataHex.Substring(2));
                                    }
                                    if (myDevice.SerialNumber != value)
                                    {
                                        //属性变更了
                                        attriButeChanged = true;
                                    }
                                    myDevice.SerialNumber = value;
                                }
                            }
                        }
                        //如果属性变更了
                        if (attriButeChanged == true && myDevice.IsCustomizeImage == false)
                        {
                            //UI重新生成
                            myDevice.IconPath = string.Empty;
                            myDevice.ReSave();
                        }
                    }
                }
                #endregion
            }
            else if (deviceEpoint == 200)
            {
                var localOta = Common.LocalDevice.Current.GetOTADevice(deviceAddr);
                if (localOta != null)
                {
                    #region ■ 固件版本
                    //固件版本
                    if (report.DeviceStatusReport.CluterID == (int)Cluster_ID.Ota)
                    {
                        foreach (var data in report.DeviceStatusReport.AttriBute)
                        {
                            //镜像版本
                            if (data.AttributeId == (int)AttriButeId.ImgVersion)
                            {
                                localOta.ImgVersion = data.AttriButeData;
                            }
                            //硬件版本
                            if (data.AttributeId == (int)AttriButeId.mgHWversion)
                            {
                                localOta.HwVersion = data.AttriButeData;
                            }
                            //镜像ID
                            if (data.AttributeId == (int)AttriButeId.ImgTypeId)
                            {
                                localOta.ImgTypeId = data.AttriButeData;
                            }
                        }
                        localOta.ReSave();
                    }
                    #endregion
                }
            }
            this.DeviceReportPush(report, ReceiveComandDiv.A设备属性上报);
        }
        #endregion
        #region ■ 传感器上报_________________________
        /// <summary>
        /// 传感器设备上报
        /// </summary>
        /// <param name="receiveData"></param>
        private void SensorDeviceReportPush(JObject receiveData)
        {
            var ias = new IASZone() { DeviceAddr = receiveData.Value<string>("DeviceAddr"), DeviceEpoint = receiveData.Value<int>("Epoint") };
            ias.iASInfo = Newtonsoft.Json.JsonConvert.DeserializeObject<IASZone.IASInfoData>(receiveData["Data"].ToString());
            //如果没有添加入安防
            if (HdlSafeguardLogic.Current.GetZoneIdByIASZone(ias) != -1)
            {
                //保存安防报警信息到本地
                HdlAlarmsLogic.Current.SaveSafeguardAlarmInfo(ias);
            }
            //处理网关上报的数据,然后变更本地缓存
            var locadevice = Common.LocalDevice.Current.GetDevice(ias.DeviceAddr, ias.DeviceEpoint);
            if (locadevice != null)
            {
                ((IASZone)locadevice).iASInfo = ias.iASInfo;
                //如果接收到上报,即说明这个传感器是在线的
                locadevice.IsOnline = 1;
                //记录回复时间
                locadevice.LastDateTime = DateTime.Now;
            }
            this.DeviceReportPush(ias, ReceiveComandDiv.A传感器上报);
            //显示有新消息的特效
            this.ShowHadNewMessageAppeal();
        }
        #endregion
        #region ■ 门锁上报___________________________
        /// <summary>
        /// 门锁上报
        /// </summary>
        /// <param name="receiveData"></param>
        private void DoorLockDeviceReportPush(JObject receiveData)
        {
            if (UserCenterResourse.UserInfo.AuthorityNo == 1)
            {
                var device = Common.LocalDevice.Current.GetDevice(receiveData.Value<string>("DeviceAddr"), receiveData.Value<int>("Epoint"));
                if (device.Type != DeviceType.DoorLock)
                {
                    //它不是门锁
                    return;
                }
                var info = Newtonsoft.Json.JsonConvert.DeserializeObject<DoorLockAlarmsResult>(receiveData["Data"].ToString());
                if (info.Clusterid == 257)
                {
                    //216:锁上设置的常开
                    if (info.AlarmCode == 216)
                    {
                        HdlThreadLogic.Current.RunMain(() =>
                        {
                            //更新门锁涉及的常开/常关的界面
                            if (UserCenter.DoorLock.DoorLockCommonInfo.UpdateCurrentDoorlockAction != null)
                            {
                                UserCenter.DoorLock.DoorLockCommonInfo.UpdateCurrentDoorlockAction(device.DeviceAddr, true);
                            }
                        });
                    }
                }
                //显示有新消息的特效
                this.ShowHadNewMessageAppeal();
            }
        }
        #endregion
        #region ■ 设备在线状态更新反馈_______________
        /// <summary>
        /// 设备在线状态更新反馈
        /// </summary>
        /// <param name="receiveData"></param>
        private void DeviceOnlineChangePush(JObject receiveData)
        {
            if (this.dicDeviceEvent.Count == 0)
            {
                //没有添加监听
                return;
            }
            var tempDevice = new CommonDevice() { DeviceAddr = receiveData.Value<string>("DeviceAddr"), DeviceEpoint = receiveData.Value<int>("Epoint") };
            tempDevice.IsOnline = Convert.ToInt32(receiveData["Data"]["IsOnline"].ToString());
            //处理网关上报的数据,然后变更本地缓存
            var locadevice = Common.LocalDevice.Current.GetDevicesByMac(tempDevice.DeviceAddr);
            for (int i = 0; i < locadevice.Count; i++)
            {
                bool onlineChanged = locadevice[i].IsOnline != tempDevice.IsOnline;
                locadevice[i].IsOnline = tempDevice.IsOnline;
                //记录回复时间
                locadevice[i].LastDateTime = DateTime.Now;
                if (onlineChanged == true)
                {
                    //在线状态变更了,才保存
                    locadevice[i].ReSave();
                }
            }
            this.DeviceReportPush(tempDevice, ReceiveComandDiv.A设备在线上报);
        }
        #endregion
        #region ■ 设备控制状态反馈___________________
        /// <summary>
        /// 设备控制状态反馈
        /// </summary>
        /// <param name="receiveData"></param>
        private void DeviceControlResponePush(JObject receiveData)
        {
            if (this.dicDeviceEvent.Count == 0)
            {
                //没有添加监听
                return;
            }
            var tempDevice = new CommonDevice() { DeviceAddr = receiveData.Value<string>("DeviceAddr"), DeviceEpoint = receiveData.Value<int>("Epoint") };
            this.DeviceReportPush(tempDevice, ReceiveComandDiv.A节点控制反馈);
        }
        #endregion
        #region ■ 布防_______________________________
        /// <summary>
        /// 布防推送
        /// </summary>
        /// <param name="receiveData"></param>
        private void SetSafetyGarrisonPush(JObject receiveData)
        {
            var data = Newtonsoft.Json.JsonConvert.DeserializeObject<Safeguard.EnableModeResponseData>(receiveData["Data"].ToString());
            if (data.Result == 0)
            {
                var garrison = GarrisonMode.None;
                //在家布防
                if (data.ModeId == 1) { garrison = GarrisonMode.AtHome; }
                //离家布防
                else if (data.ModeId == 2) { garrison = GarrisonMode.RemoveHome; }
                else { return; }
                //保存报警信息然后推送到界面上
                HdlAlarmsLogic.Current.SaveSafeguardAlarmInfo(garrison);
                if (UserCenterResourse.DicActionForm.ContainsKey("SafetyManagementMainForm") == true)
                {
                    //推送
                    var form = (Safety.SafetyManagementMainForm)UserCenterResourse.DicActionForm["SafetyManagementMainForm"];
                    form?.GarrisonModePush(garrison);
                }
                //显示有新消息的特效
                this.ShowHadNewMessageAppeal();
            }
        }
        #endregion
        #region ■ 撤防_______________________________
        /// <summary>
        /// 撤防推送
        /// </summary>
        /// <param name="receiveData"></param>
        private void RemoveSafetyGarrisonPush(JObject receiveData)
        {
            var data = Newtonsoft.Json.JsonConvert.DeserializeObject<Safeguard.WithdrawModeResponseData>(receiveData["Data"].ToString());
            if (data.Result == 0)
            {
                //保存报警信息然后推送到界面上
                HdlAlarmsLogic.Current.SaveSafeguardAlarmInfo(GarrisonMode.RemoveGarrison);
                if (UserCenterResourse.DicActionForm.ContainsKey("SafetyManagementMainForm") == true)
                {
                    //推送
                    var form = (Safety.SafetyManagementMainForm)UserCenterResourse.DicActionForm["SafetyManagementMainForm"];
                    form?.GarrisonModePush(GarrisonMode.RemoveGarrison);
                }
                //显示有新消息的特效
                this.ShowHadNewMessageAppeal();
            }
        }
        #endregion
        #region ■ 通过外部方式布防撤防_______________
        /// <summary>
        /// 通过外部方式布防撤防
        /// </summary>
        /// <param name="receiveData">接收的数据</param>
        private void SecurityEnOrWithdrawSucceedReport(JObject receiveData)
        {
            var data = Newtonsoft.Json.JsonConvert.DeserializeObject<SecurityEnOrWithdrawResult>(receiveData["Data"].ToString());
            if (data.EnOrWithdraw == -1 || data.ModeId == -1 || data.OperationWay == -1)
            {
                return;
            }
            var garrison = GarrisonMode.None;
            if (data.EnOrWithdraw == 0)
            {
                //在家布防
                if (data.ModeId == 1) { garrison = GarrisonMode.AtHome; }
                //离家布防
                else if (data.ModeId == 2) { garrison = GarrisonMode.RemoveHome; }
            }
            else if (data.EnOrWithdraw == 1)
            {
                //撤防
                garrison = GarrisonMode.RemoveGarrison;
            }
            string appendText = string.Empty;
            //自动化
            if (data.OperationWay == 0) { appendText = "(" + Language.StringByID(R.MyInternationalizationString.uLogicOperation) + ")"; }
            //按键操作
            else if (data.OperationWay == 1) { appendText = "(" + Language.StringByID(R.MyInternationalizationString.uPanelOperation) + ")"; }
            //保存报警信息然后推送到界面上
            HdlAlarmsLogic.Current.SaveSafeguardAlarmInfo(garrison, appendText);
            if (UserCenterResourse.DicActionForm.ContainsKey("SafetyManagementMainForm") == true)
            {
                //推送
                var form = (Safety.SafetyManagementMainForm)UserCenterResourse.DicActionForm["SafetyManagementMainForm"];
                form?.GarrisonModePush(garrison);
            }
            //显示有新消息的特效
            this.ShowHadNewMessageAppeal();
        }
        /// <summary>
        /// 通过外部方式布防撤防的接收结果
        /// </summary>
        private class SecurityEnOrWithdrawResult
        {
            /// <summary>
            /// 0:布防成功  1:撤防成功
            /// </summary>
            public int EnOrWithdraw = -1;
            /// <summary>
            /// 安防模式id
            /// </summary>
            public int ModeId = -1;
            /// <summary>
            /// 外部布撤防方式-> 0:执行逻辑动作  1:按键操作
            /// </summary>
            public int OperationWay = -1;
        }
        #endregion
        #region ■ 逻辑触发上报_______________________
        /// <summary>
        /// 逻辑触发上报
        /// </summary>
        /// <param name="receiveData"></param>
        private void LogicExecutePush(JObject receiveData)
        {
            //显示有新消息的特效
            this.ShowHadNewMessageAppeal();
            // 逻辑执行常开模式失效的情况
            if (UserCenterResourse.UserInfo.AuthorityNo == 1)
            {
                //自动化执行 常开关闭
                var data = Newtonsoft.Json.JsonConvert.DeserializeObject<LogicPushResult>(receiveData["Data"].ToString());
                if (data != null && data.ActionData != null)
                {
                    if (data.ActionData.Actiontype == 8 && data.ActionData.PassDataString == "055704010113")
                    {
                        var deviceAddr = data.ActionData.MacStr;
                        var device = Common.LocalDevice.Current.GetDevicesByMac(deviceAddr, false);
                        if (device.Count > 0 && device[0].Type != DeviceType.DoorLock)
                        {
                            return;
                        }
                        HdlThreadLogic.Current.RunThread(async () =>
                        {
                            HdlThreadLogic.Current.RunMain(() =>
                            {
                                //提示门锁已经失效
                                new Tip() { MaxWidth = 150, Text = Language.StringByID(R.MyInternationalizationString.NormallyClosed), Direction = AMPopTipDirection.None, CloseTime = 1 }.Show(Common.CommonPage.Instance);
                                //更新门锁涉及的常开/常关的界面
                                if (UserCenter.DoorLock.DoorLockCommonInfo.UpdateCurrentDoorlockAction != null)
                                {
                                    UserCenter.DoorLock.DoorLockCommonInfo.UpdateCurrentDoorlockAction(deviceAddr, false);
                                }
                            });
                        });
                    }
                }
            }
        }
        #endregion
        #region ■ 场景触发上报_______________________
        /// <summary>
        /// 场景触发上报
        /// </summary>
        /// <param name="receiveData"></param>
        private void SceneExecPush(JObject receiveData)
        {
            //目前不处理场景上报内容
            //显示有新消息的特效
            this.ShowHadNewMessageAppeal();
        }
        #endregion
        #region ■ 添加设备事件_______________________
        /// <summary>
        /// 添加获取设备属性的事件(属性上报的对象:device.DeviceStatusReport)
        /// </summary>
        /// <param name="mainKeys">标识事件的主键(可以随便填,主要是针对多个界面一起使用的情况)</param>
        /// <param name="comand">命令区分</param>
        /// <param name="action">
        /// <para>当接收到网关回复之后的回调函数</para>
        /// <para>设备属性上报的对象:device.DeviceStatusReport</para>
        /// <para>传感器上报的对象:ias.iASInfo</para>
        /// <para>设备在线上报的对象:device.IsOnline</para></param>
        public void AddAttributeEvent(string mainKeys, ReceiveComandDiv comand, Action<CommonDevice> action)
        {
            lock (this.dicDeviceEvent)
            {
                if (this.dicDeviceEvent.ContainsKey(mainKeys) == true)
                {
                    this.RemoveEvent(mainKeys);
                }
                this.dicDeviceEvent[mainKeys] = action;
                this.dicCommandDiv[mainKeys] = comand;
            }
        }
        #endregion
        #region ■ 移除设备监听_______________________
        /// <summary>
        /// 移除事件
        /// </summary>
        /// <param name="mainKeys">标识事件的主键(可以随便填,主要是针对多个界面一起使用的情况)</param>
        public void RemoveEvent(string mainKeys)
        {
            lock (this.dicDeviceEvent)
            {
                if (this.dicDeviceEvent.ContainsKey(mainKeys) == true)
                {
                    var action = this.dicDeviceEvent[mainKeys];
                    this.dicDeviceEvent.Remove(mainKeys);
                    this.dicCommandDiv.Remove(mainKeys);
                    action = null;
                }
            }
        }
        /// <summary>
        /// 移除全部的事件
        /// </summary>
        public void RemoveAllEvent()
        {
            lock (this.dicDeviceEvent)
            {
                var list = new HashSet<string>();
                foreach (var keys in this.dicDeviceEvent.Keys)
                {
                    list.Add(keys);
                }
                foreach (var keys in list)
                {
                    //需要慢慢一个一个的释放Action,听说
                    this.RemoveEvent(keys);
                }
            }
        }
        #endregion
        #region ■ 一般方法___________________________
        /// <summary>
        /// 设备上报推送(调用此方法,他会推送到各自的界面)
        /// </summary>
        /// <param name="common"></param>
        /// <param name="comand"></param>
        public void DeviceReportPush(CommonDevice common, ReceiveComandDiv comand)
        {
            if (this.dicDeviceEvent.Count == 0)
            {
                //没有添加监听
                return;
            }
            //lock (this.dicDeviceEvent)
            {
                var list = new List<Action<CommonDevice>>();
                try
                {
                    foreach (string keys in this.dicDeviceEvent.Keys)
                    {
                        if (this.dicCommandDiv[keys] != comand)
                        {
                            //命令区分不一致,则不调用回调函数
                            continue;
                        }
                        //命令区分一致时,则调用回调函数
                        list.Add(this.dicDeviceEvent[keys]);
                    }
                }
                catch { return; }
                //有可能在回调函数中移除了事件,导致报错,所以先收集,再调用
                foreach (var action in list)
                {
                    try
                    {
                        action?.Invoke(common);
                    }
                    catch (Exception ex)
                    {
                        //Log出力
                        string msg = "推送错误! 当前激活的界面[" + UserCenterResourse.NowActionFormID + "]";
                        HdlLogLogic.Current.WriteLog(ex, msg);
                    }
                }
            }
        }
        /// <summary>
        /// 是否存在指定的事件
        /// </summary>
        /// <param name="mainkeys"></param>
        /// <returns></returns>
        public bool IsEsixt(string mainkeys)
        {
            return this.dicCommandDiv.ContainsKey(mainkeys);
        }
        /// <summary>
        /// 显示有新消息的特效
        /// </summary>
        private void ShowHadNewMessageAppeal()
        {
            //有新消息(特效还在时,不需要再处理)
            if (ControlCommonResourse.HadNewMessage == false)
            {
                HdlThreadLogic.Current.RunMain(() =>
                {
                    for (int i = 0; i < ControlCommonResourse.listMessageManaContr.Count; i++)
                    {
                        //显示角标特效
                        ControlCommonResourse.listMessageManaContr[i].IsSelected = true;
                    }
                    ControlCommonResourse.HadNewMessage = true;
                });
            }
        }
        #endregion
    }
    /// <param name="gatewayId">网关ID</param>
    /// <param name="topic">整个主题</param>
    /// <param name="reportTopic">上报数据的主题</param>
    /// <param name="msgData">接收的数据</param>
    public void GatewayOverallMsgReceive(string gatewayId, string topic, string reportTopic, string msgData)
    {
      if (topic == "AppNoLogin")
      {
        HdlThreadLogic.Current.RunMain(() =>
        {
          //登录密匙已经过期,请重新登录
          string msg = Language.StringByID(R.MyInternationalizationString.uTokenIsOldAndLoginAgain);
          var contr = new ShowMsgControl(ShowMsgType.Tip, msg);
          contr.Show();
          UserCenterLogic.ReLoginAgain(UserCenterResourse.UserInfo.Account, false);
        });
        return;
      }
      else if (topic == "ZigbeeGateWayToClient/" + Common.Config.Instance.ConnEmqClientId + "/Push/NotifySqueeze")
      {
        HdlThreadLogic.Current.RunMain(() =>
        {
          //此帐号已在别处登录,您被迫下线
          string msg = Language.StringByID(R.MyInternationalizationString.uHadBeenLoginAndOffLine);
          var contr = new ShowMsgControl(ShowMsgType.Tip, msg);
          contr.Show();
          UserCenterLogic.ReLoginAgain(UserCenterResourse.UserInfo.Account, false);
        });
        return;
      }
      else if (topic == "YouIpAndPortNoRecord")
      {
        HdlThreadLogic.Current.RunMain(() =>
        {
          //您当前的IP及端口在云端不存在,请重新登录!
          string msg = Language.StringByID(R.MyInternationalizationString.uYouIpAndPortNoRecord);
          var contr = new ShowMsgControl(ShowMsgType.Tip, msg);
          contr.Show();
          UserCenterLogic.ReLoginAgain(UserCenterResourse.UserInfo.Account, false);
        });
        return;
      }
      else if (topic == "ZigbeeGateWayToClient/" + Common.Config.Instance.Home.Id + "_" + Common.Config.Instance.Guid + "/PrimaryUserDelYou")
      {
        HdlThreadLogic.Current.RunMain(() =>
        {
          //分享住宅已更改,请联系管理员!
          string msg = Language.StringByID(R.MyInternationalizationString.uShardResidenceHadDeletePleaseTakeToAdmin);
          var contr = new ShowMsgControl(ShowMsgType.Tip, msg);
          contr.Show();
          UserCenterLogic.ReLoginAgain(UserCenterResourse.UserInfo.Account, false);
        });
        return;
      }
      else if (topic == "ZigbeeGateWayToClient/" + Common.Config.Instance.Guid + "/Push/Update")
      {
        HdlThreadLogic.Current.RunMain(() =>
        {
          //您的权限已经变更,请重新登陆
          string msg = Language.StringByID(R.MyInternationalizationString.uYouAccessHadChangedPleaseTakeToAdmin);
          var contr = new ShowMsgControl(ShowMsgType.Tip, msg);
          contr.Show();
          UserCenterLogic.ReLoginAgain(UserCenterResourse.UserInfo.Account, false);
        });
        return;
      }
      else if (UserCenterResourse.UserInfo.AuthorityNo == 3)
      {
        if (topic == "ZigbeeGateWayToClient/" + Common.Config.Instance.Guid + "/Push/Deleted"
        || topic == "ZigbeeGateWayToClient/" + Common.Config.Instance.Guid + "/Push/DeletedShareData")
        {
          HdlThreadLogic.Current.RunMain(() =>
          {
            //分享数据已经变更,请重新登陆
            string msg = Language.StringByID(R.MyInternationalizationString.uShardDataIsChangedPleaseLoginAgain);
            var contr = new ShowMsgControl(ShowMsgType.Tip, msg);
            contr.Show();
            UserCenterLogic.ReLoginAgain(UserCenterResourse.UserInfo.Account, false);
          });
          return;
        }
      }
      try
      {
        if (HdlGatewayLogic.Current.IsGatewayExist(gatewayId) == false)
        {
          //不是自己绑定的网关,则不处理
          return;
        }
        //设备属性上报
        if (reportTopic == "DeviceStatusReport")
        {
          //设备属性上报
          this.DeviceAttributeReportPush(JObject.Parse(msgData));
        }
        //传感器上报
        else if (reportTopic == "IASInfoReport")
        {
          this.SensorDeviceReportPush(JObject.Parse(msgData));
        }
        //门锁上报
        else if (topic == gatewayId + "/Alarms/SendAlarmInform")
        {
          this.DoorLockDeviceReportPush(JObject.Parse(msgData));
        }
        //通过外部方式布防撤防成功时报告
        else if (topic == gatewayId + "/Security/EnOrWithdrawSucceedReport")
        {
          this.SecurityEnOrWithdrawSucceedReport(JObject.Parse(msgData));
        }
        //设备在线状态更新反馈
        else if (reportTopic == "OnlineStatusChange_Respon")
        {
          this.DeviceOnlineChangePush(JObject.Parse(msgData));
        }
        //设备控制状态反馈
        else if (reportTopic == "DeviceDefaultAck")
        {
          this.DeviceControlResponePush(JObject.Parse(msgData));
        }
        //撤防
        else if (topic == gatewayId + "/Security/WithdrawMode_Respon")
        {
          this.RemoveSafetyGarrisonPush(JObject.Parse(msgData));
        }
        //布防
        else if (topic == gatewayId + "/Security/EnableMode_Respon")
        {
          this.SetSafetyGarrisonPush(JObject.Parse(msgData));
        }
        //逻辑触发上报
        else if (topic == gatewayId + "/Logic/Execute_Respon")
        {
          this.LogicExecutePush(JObject.Parse(msgData));
        }
        //场景触发上报
        else if (topic == gatewayId + "/Scene/Exec_Respon")
        {
          this.SceneExecPush(null);
        }
        //网关接收事件
        else if (gatewayId == this.GatewayReceiveId)
        {
          this.GatewayReceiveEvent?.Invoke(topic, msgData);
        }
      }
      catch (Exception ex)
      {
        //Log出力
        HdlLogLogic.Current.WriteLog(ex);
      }
    }
    #endregion
    #region ■ 设备属性上报_______________________
    /// <summary>
    /// 接收命令区分
    /// 设备属性上报
    /// </summary>
    public enum ReceiveComandDiv
    {
        /// <summary>
        /// 设备属性上报
        /// </summary>
        A设备属性上报 = 1,
        /// <summary>
        /// 传感器上报
        /// </summary>
        A传感器上报 = 2,
        /// <summary>
        /// 设备在线上报
        /// </summary>
        A设备在线上报 = 3,
        /// <summary>
        /// 当客户端发送控制设备指令,如打开或关闭设备、调节亮度、颜色。如果被控制的节点设备在线,节点设备将反馈
        /// </summary>
        A节点控制反馈 = 4
    }
    /// <param name="receiveData"></param>
    private void DeviceAttributeReportPush(JObject receiveData)
    {
      if (this.dicDeviceEvent.Count == 0)
      {
        //没有添加监听
        return;
      }
      var deviceAddr = receiveData.Value<string>("DeviceAddr");
      var deviceEpoint = receiveData.Value<int>("Epoint");
      var report = new CommonDevice { DeviceAddr = deviceAddr, DeviceEpoint = deviceEpoint };
      report.DeviceStatusReport = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.DeviceStatusReportData>(receiveData["Data"].ToString());
      if (report.DeviceStatusReport.AttriBute.Count == 0)
      {
        //网关有些奇葩,没有属性它也会发过来
        return;
      }
      var tempList = Common.LocalDevice.Current.GetDevicesByMac(report.DeviceAddr, false);
      var res = Common.LocalDevice.Current.GetMyDeviceEnumInfo(tempList);
      if (res.ConcreteType == Common.DeviceConcreteType.Airer)
      {
        //晾衣架特殊处理,本地只存了端点1,其余2~5端点都不存
        deviceEpoint = 1;
      }
      //处理网关上报的数据,然后变更本地缓存
      var locadevice = Common.LocalDevice.Current.GetDevice(deviceAddr, deviceEpoint);
      if (locadevice != null)
      {
        //有反馈,这个设备肯定是在线的
        locadevice.IsOnline = 1;
        locadevice.LastDateTime = DateTime.Now;
        #region ■ 开关功能
        //晾衣架回路2,3,4,5都是CluterID是6 ,但是功能不是开关
        if (locadevice.Type == DeviceType.Airer)
        {
          if (report.DeviceStatusReport.CluterID == 6)
          {
            foreach (var attData in report.DeviceStatusReport.AttriBute)
            {
              locadevice.DeviceStatusReport = report.DeviceStatusReport;
              if (attData.AttributeId == 0)
              {
                //注意晾衣架回路上报都端点都是被替换为回路1,所以这里用上报都回路
                switch (report.DeviceEpoint)
                {
                  //照明
                  case 2:
                    ((Airer)locadevice).OnOffStatus = report.DeviceStatusReport.AttriBute[0].AttriButeData;
                    break;
                  //风干
                  case 3:
                    ((Airer)locadevice).WindOnOffStatus = report.DeviceStatusReport.AttriBute[0].AttriButeData;
                    break;
                  //烘干
                  case 4:
                    ((Airer)locadevice).DryOnOffStatus = report.DeviceStatusReport.AttriBute[0].AttriButeData;
                    break;
                  //消毒
                  case 5:
                    ((Airer)locadevice).DisinfectOnOffStatus = report.DeviceStatusReport.AttriBute[0].AttriButeData;
                    break;
                }
              }
              //晾衣架(风干/烘干/消毒)设置的剩余多少时间触发
              else if (attData.AttributeId == 16386)
              {
                if (report.DeviceStatusReport.AttriBute.Count > 2)
                {
                  //注意晾衣架回路上报都端点都是被替换为回路1,所以这里用上报都回路
                  switch (report.DeviceEpoint)
                  {
                    //风干
                    case 3:
                      ((Airer)locadevice).WindRemainTime = report.DeviceStatusReport.AttriBute[1].AttriButeData;
                      break;
                    //烘干
                    case 4:
                      ((Airer)locadevice).DryRemainTime = report.DeviceStatusReport.AttriBute[1].AttriButeData;
                      break;
                    //消毒
                    case 5:
                      ((Airer)locadevice).DisinfectRemainTime = report.DeviceStatusReport.AttriBute[1].AttriButeData;
                      break;
                  }
                }
              }
              //晾衣架(风干/烘干/消毒)设置的默认时间
              else if (attData.AttributeId == 16385)
              {
                if (report.DeviceStatusReport.AttriBute.Count > 3)
                {
                  //注意晾衣架回路上报都端点都是被替换为回路1,所以这里用上报都回路
                  switch (report.DeviceEpoint)
                  {
                    //风干
                    case 3:
                      ((Airer)locadevice).WindTime = report.DeviceStatusReport.AttriBute[2].AttriButeData;
                      break;
                    //烘干
                    case 4:
                      ((Airer)locadevice).DryTime = report.DeviceStatusReport.AttriBute[2].AttriButeData;
                      break;
                    //消毒
                    case 5:
                      ((Airer)locadevice).DisinfectTime = report.DeviceStatusReport.AttriBute[2].AttriButeData;
                      break;
                  }
                }
              }
              //已经接收到状态
              locadevice.HadReadDeviceStatu = true;
            }
          }
        }
        else
        {
          //开关功能
          if (report.DeviceStatusReport.CluterID == 6)
          {
            if (locadevice is LightBase)
            {
              locadevice.DeviceStatusReport = report.DeviceStatusReport;
              ((LightBase)locadevice).OnOffStatus = report.DeviceStatusReport.AttriBute[0].AttriButeData;
              //已经接收到状态
              locadevice.HadReadDeviceStatu = true;
            }
          }
        }
        #endregion
        #region ■ 电量推送
        //电量推送
        if (report.DeviceStatusReport.CluterID == 1)
        {
          foreach (var attData in report.DeviceStatusReport.AttriBute)
          {
            //电量
            if (attData.AttributeId == 33)
            {
              string receiptData = string.Empty;
              //两个两个位置替换
              for (int i = attData.AttriButeDataHex.Length - 1; i >= 0; i = i - 2)
              {
                receiptData += attData.AttriButeDataHex[i - 1].ToString() + attData.AttriButeDataHex[i].ToString();
              }
              int batteryValue = Convert.ToInt32(receiptData, 16);
              //低于20%,则代表电量低
              locadevice.IsBatteryDown = batteryValue < 20;
            }
            //已经接收到状态
            locadevice.HadReadDeviceStatu = true;
          }
        }
        #endregion
        #region ■ 蜂鸣器推送
        //蜂鸣器数据
        else if (report.DeviceStatusReport.CluterID == 1282)
        {
          //mini夜灯
          if (Common.LocalDevice.Current.IsMiniLight(locadevice) == true)
          {
            foreach (var attData in report.DeviceStatusReport.AttriBute)
            {
              if (attData.AttributeId == 0)
              {
                //这个是报警持续时间(大于2秒时,标记为还在响着)
                ((ColorTemperatureLight)locadevice).IsBuzzerRing = attData.AttriButeData > 2 ? true : false;
              }
            }
          }
        }
        #endregion
        #region ■ 窗帘数据
        //窗帘数据
        else if (report.DeviceStatusReport.CluterID == 258)
        {
          //窗帘类型
          if (report.DeviceStatusReport.AttriBute[0].AttributeId == 0)
          {
            locadevice.DeviceStatusReport = report.DeviceStatusReport;
            ((Rollershade)locadevice).WcdType = report.DeviceStatusReport.AttriBute[0].AttriButeData;
            //这个东西要保存
            locadevice.ReSave();
          }
          //窗帘百分比
          else if (report.DeviceStatusReport.AttriBute[0].AttributeId == 8)
          {
            locadevice.DeviceStatusReport = report.DeviceStatusReport;
            ((Rollershade)locadevice).WcdCurrentPositionLiftPercentage = report.DeviceStatusReport.AttriBute[0].AttriButeData;
            //已经接收到状态
            locadevice.HadReadDeviceStatu = true;
          }
        }
        #endregion
        #region ■ 空调和新风数据
        //空调数据
        else if (report.DeviceStatusReport.CluterID == 513)
        {
          locadevice.DeviceStatusReport = report.DeviceStatusReport;
          foreach (var attData in report.DeviceStatusReport.AttriBute)
          {
            var curTemp = attData.AttriButeData / 100;
            if (attData.AttributeId == 0)
            {
              //此属性表明室内当前的温度 * 100,实际温度为“LocalTemperature / 100”,单位:℃
              ((AC)locadevice).currentLocalTemperature = curTemp;
              //已经接收到状态
              locadevice.HadReadDeviceStatu = true;
            }
            else if (attData.AttributeId == 17)
            {
              //此属性表明室内当前的温度 * 100,实际温度为“LocalTemperature / 100”,单位:℃
              ((AC)locadevice).currentCoolingSetpoint = curTemp;
              //已经接收到状态
              locadevice.HadReadDeviceStatu = true;
            }
            else if (attData.AttributeId == 18)
            {
              //此属性表明此设备当前的制热温度,实际温度为“HeatingSetpoint / 100”,单位:℃。
              ((AC)locadevice).currentHeatingSetpoint = curTemp;
              //已经接收到状态
              locadevice.HadReadDeviceStatu = true;
            }
            else if (attData.AttributeId == 28)
            {
              //此属性描述恒温设备正处于哪种模式
              ((AC)locadevice).currentSystemMode = attData.AttriButeData;
              //已经接收到状态
              locadevice.HadReadDeviceStatu = true;
            }
            else if (attData.AttributeId == 4096)
            {
              //此属性表明此设备当前的自动温度,实际温度为“AutoSetpoint / 100”,单位:℃。
              ((AC)locadevice).currentAutoSetpoint = curTemp;
              //已经接收到状态
              locadevice.HadReadDeviceStatu = true;
            }
            else if (attData.AttributeId == 4097)
            {
              //过虑网清洗标志:42
              ((AC)locadevice).CleanStatu = attData.AttriButeData == 42;
            }
            else if (attData.AttributeId == 4099)
            {
              //转换为二进制
              var value = Convert.ToString(attData.AttriButeData, 2).PadLeft(16, '0');
              //这五个设置是放在后面的
              value = value.Substring(value.Length - 5, 5);
              for (int i = 0; i < value.Length; i++)
              {
                //自定义的空调模式
                ((AC)locadevice).listSupportMode[i] = Convert.ToInt32(value[i].ToString());
              }
              locadevice.ReSave();
            }
          }
        }
        //空调数据
        else if (report.DeviceStatusReport.CluterID == 514)
        {
          locadevice.DeviceStatusReport = report.DeviceStatusReport;
          foreach (var attData in report.DeviceStatusReport.AttriBute)
          {
            //区分是空调还是新风
            var device = Shared.Common.LocalDevice.Current.GetDevice(report.DeviceAddr, report.DeviceEpoint);
            if (device.Type == DeviceType.FreshAir)
            {
              if (attData.AttributeId == 0)
              {
                switch (attData.AttriButeData)
                {
                  case 0:
                  case 4:
                    ((FreshAir)locadevice).currentFanStatus = attData.AttriButeData;
                    break;
                  case 1:
                  case 2:
                  case 3:
                    ((FreshAir)locadevice).currentFanSpeed = attData.AttriButeData;
                    break;
                  case 5:
                  case 15:
                    ((FreshAir)locadevice).currentFanMode = attData.AttriButeData;
                    break;
                }
                //已经接收到状态
                locadevice.HadReadDeviceStatu = true;
              }
            }
            else
            {
              if (attData.AttributeId == 0)
              {
                //风扇模式
                ((AC)locadevice).currentFanMode = attData.AttriButeData;
                //已经接收到状态
                locadevice.HadReadDeviceStatu = true;
              }
              else if (attData.AttributeId == 4096)
              {
                //风扇扫风
                ((AC)locadevice).currentFanSwingMode = attData.AttriButeData;
                //已经接收到状态
                locadevice.HadReadDeviceStatu = true;
              }
              else if (attData.AttributeId == 4097)
              {
                //转换为二进制
                var value = Convert.ToString(attData.AttriButeData, 2).PadLeft(16, '0');
                //这个设置是放在后面的
                value = value.Substring(value.Length - 1, 1);
                //启用摆风功能
                ((AC)locadevice).UseSwingFunction = value == "1";
                locadevice.ReSave();
              }
            }
          }
        }
        #endregion
        #region ■ 亮度数据
        //亮度数据
        else if (report.DeviceStatusReport.CluterID == 8)
        {
          locadevice.DeviceStatusReport = report.DeviceStatusReport;
          if (report.DeviceStatusReport.AttriBute[0].AttributeId == 0)
          {
            if (locadevice.Type == DeviceType.DimmableLight)
            {
              //此属性表明当前亮度程度
              ((DimmableLight)locadevice).Level = report.DeviceStatusReport.AttriBute[0].AttriButeData;
            }
            else if (locadevice.Type == DeviceType.ColorTemperatureLight)
            {
              //此属性表明当前亮度程度
              ((ColorTemperatureLight)locadevice).Level = report.DeviceStatusReport.AttriBute[0].AttriButeData;
            }
            //已经接收到状态
            locadevice.HadReadDeviceStatu = true;
            //if (locadevice is LightBase)
            //{
            //    //当接收到亮度值时,默认打开
            //    ((LightBase)locadevice).OnOffStatus = 1;
            //}
          }
        }
        #endregion
        #region ■ 色温数据
        //色温数据
        else if (report.DeviceStatusReport.CluterID == 768)
        {
          locadevice.DeviceStatusReport = report.DeviceStatusReport;
          if (report.DeviceStatusReport.AttriBute[0].AttributeId == 0)
          {
            if (locadevice.Type == DeviceType.ColorTemperatureLight)
            {
              //此属性表明当前色温
              int value = report.DeviceStatusReport.AttriBute[0].AttriButeData != 0 ? 1000000 / report.DeviceStatusReport.AttriBute[0].AttriButeData : 0;
              ((ColorTemperatureLight)locadevice).ColorTemperature = value;
            }
            //已经接收到状态
            locadevice.HadReadDeviceStatu = true;
          }
        }
        #endregion
        #region ■ 温度数据
        //温度数据
        else if (report.DeviceStatusReport.CluterID == 1026)
        {
          foreach (var attData in report.DeviceStatusReport.AttriBute)
          {
            //温度
            if (attData.AttributeId == (int)AttriButeId.MeasuredValue)
            {
              decimal temperatrue = 0;
              string receiptData = string.Empty;
              //两个两个位置替换
              for (int i = attData.AttriButeDataHex.Length - 1; i >= 0; i = i - 2)
              {
                receiptData += attData.AttriButeDataHex[i - 1].ToString() + attData.AttriButeDataHex[i].ToString();
              }
              //有符号(会出现负数)
              if (attData.AttriButeDataType == 40 || attData.AttriButeDataType == 41)
              {
                //小数点需要一位
                string strValue = Convert.ToInt16(receiptData, 16).ToString();
                strValue = strValue.Substring(0, strValue.Length - 1);
                temperatrue = Convert.ToDecimal(strValue.Insert(strValue.Length - 1, "."));
              }
              //无符号(不会出现负数)
              else if (attData.AttriButeDataType == 32 || attData.AttriButeDataType == 33)
              {
                ushort shortData = Convert.ToUInt16(receiptData, 16);
                if (shortData > 32767)
                {
                  //负数(特殊处理)
                  string strValue = (shortData - 65536).ToString();
                  //小数点需要一位
                  strValue = strValue.Substring(0, strValue.Length - 1);
                  temperatrue = Convert.ToDecimal(strValue.Insert(strValue.Length - 1, "."));
                }
                else
                {
                  //小数点需要一位
                  string strValue = shortData.ToString();
                  strValue = strValue.Substring(0, strValue.Length - 1);
                  temperatrue = Convert.ToDecimal(strValue.Insert(strValue.Length - 1, "."));
                }
              }
              //温度传感器
              if (locadevice is TemperatureSensor)
              {
                ((TemperatureSensor)locadevice).currentTemperature = temperatrue;
              }
              //PM2.5传感器
              else if (locadevice is PMSensor)
              {
                ((PMSensor)locadevice).currentTemperature = (int)temperatrue;
              }
              //已经接收到状态
              locadevice.HadReadDeviceStatu = true;
              //温度值需要保存
              locadevice.ReSave();
            }
          }
        }
        #endregion
        #region ■ 湿度数据
        //湿度数据
        else if (report.DeviceStatusReport.CluterID == 1029)
        {
          foreach (var attData in report.DeviceStatusReport.AttriBute)
          {
            //湿度
            if (attData.AttributeId == (int)AttriButeId.MeasuredValue)
            {
              decimal humidity = 0;
              string receiptData = string.Empty;
              //两个两个位置替换
              for (int i = attData.AttriButeDataHex.Length - 1; i >= 0; i = i - 2)
              {
                receiptData += attData.AttriButeDataHex[i - 1].ToString() + attData.AttriButeDataHex[i].ToString();
              }
              //有符号(会出现负数)
              if (attData.AttriButeDataType == 40 || attData.AttriButeDataType == 41)
              {
                //小数点需要一位
                string strValue = Convert.ToInt16(receiptData, 16).ToString();
                strValue = strValue.Substring(0, strValue.Length - 1);
                humidity = Convert.ToDecimal(strValue.Insert(strValue.Length - 1, "."));
              }
              //无符号(不会出现负数)
              else if (attData.AttriButeDataType == 32 || attData.AttriButeDataType == 33)
              {
                //小数点需要一位 湿度不会出现负数
                string strValue = Convert.ToUInt16(receiptData, 16).ToString();
                strValue = strValue.Substring(0, strValue.Length - 1);
                humidity = Convert.ToDecimal(strValue.Insert(strValue.Length - 1, "."));
              }
              //湿度传感器
              if (locadevice is TemperatureSensor)
              {
                ((TemperatureSensor)locadevice).currentHumidity = humidity;
              }
              //新风的湿度传感器
              else if (locadevice is HumiditySensor)
              {
                ((HumiditySensor)locadevice).currentHumidity = humidity;
              }
              //PM2.5传感器
              else if (locadevice is PMSensor)
              {
                ((PMSensor)locadevice).currentHumidity = (int)humidity;
              }
              //已经接收到状态
              locadevice.HadReadDeviceStatu = true;
              //湿度值需要保存
              locadevice.ReSave();
            }
          }
        }
        #endregion
        #region ■ PM2.5数据
        //PM2.5数据
        else if (report.DeviceStatusReport.CluterID == 1066)
        {
          foreach (var attData in report.DeviceStatusReport.AttriBute)
          {
            //PM2.5
            if (attData.AttributeId == (int)AttriButeId.MeasuredValue)
            {
              if (attData.AttriButeDataType == 57)
              {
                ((PMSensor)locadevice).currentPmData = attData.AttriButeData;
              }
            }
            //已经接收到状态
            locadevice.HadReadDeviceStatu = true;
          }
        }
        #endregion
        #region ■ 设备基础信息
        else if (report.DeviceStatusReport.CluterID == 0)
        {
          var listLocalDevice = Common.LocalDevice.Current.GetDevicesByMac(deviceAddr, false);
          //属性都是一样的
          foreach (var myDevice in listLocalDevice)
          {
            //属性是否改变
            bool attriButeChanged = false;
            foreach (var data in report.DeviceStatusReport.AttriBute)
            {
              //生产商名字
              if (data.AttributeId == 4 && data.AttriButeDataHex.Length > 2)
              {
                if (data.AttriButeDataHex.Length > 2)
                {
                  var value = UserCenterLogic.TranslateHexadecimalIntoText(data.AttriButeDataHex.Substring(2));
                  if (myDevice.ManufacturerName != value)
                  {
                    //属性变更了
                    attriButeChanged = true;
                  }
                  myDevice.ManufacturerName = value;
                }
              }
              //型号码(也叫模块ID)
              if (data.AttributeId == 5)
              {
                if (data.AttriButeDataHex.Length > 2)
                {
                  var value = UserCenterLogic.TranslateHexadecimalIntoText(data.AttriButeDataHex.Substring(2));
                  if (myDevice.ModelIdentifier != value)
                  {
                    //属性变更了
                    attriButeChanged = true;
                  }
                  myDevice.ModelIdentifier = value;
                }
              }
              //生产日期
              if (data.AttributeId == 6)
              {
                if (data.AttriButeDataHex.Length > 2)
                {
                  var value = UserCenterLogic.TranslateHexadecimalIntoText(data.AttriButeDataHex.Substring(2));
                  if (myDevice.ProductionDate != value)
                  {
                    //属性变更了
                    attriButeChanged = true;
                  }
                  myDevice.ProductionDate = value;
                }
              }
              //电源
              if (data.AttributeId == 7)
              {
                myDevice.PowerSource = data.AttriButeData;
              }
              //序列号
              if (data.AttributeId == 13)
              {
                if (data.AttriButeDataHex.Length > 2)
                {
                  string value;
                  if (Common.LocalDevice.Current.IsHdlDevice(myDevice) == false)
                  {
                    //第三方设备
                    value = data.AttriButeDataHex.Substring(2);
                  }
                  else
                  {
                    //河东设备
                    value = UserCenterLogic.TranslateHexadecimalIntoText(data.AttriButeDataHex.Substring(2));
                  }
                  if (myDevice.SerialNumber != value)
                  {
                    //属性变更了
                    attriButeChanged = true;
                  }
                  myDevice.SerialNumber = value;
                }
              }
            }
            //如果属性变更了
            if (attriButeChanged == true && myDevice.IsCustomizeImage == false)
            {
              //UI重新生成
              myDevice.IconPath = string.Empty;
              myDevice.ReSave();
            }
          }
        }
        #endregion
      }
      else if (deviceEpoint == 200)
      {
        var localOta = Common.LocalDevice.Current.GetOTADevice(deviceAddr);
        if (localOta != null)
        {
          #region ■ 固件版本
          //固件版本
          if (report.DeviceStatusReport.CluterID == (int)Cluster_ID.Ota)
          {
            foreach (var data in report.DeviceStatusReport.AttriBute)
            {
              //镜像版本
              if (data.AttributeId == (int)AttriButeId.ImgVersion)
              {
                localOta.ImgVersion = data.AttriButeData;
              }
              //硬件版本
              if (data.AttributeId == (int)AttriButeId.mgHWversion)
              {
                localOta.HwVersion = data.AttriButeData;
              }
              //镜像ID
              if (data.AttributeId == (int)AttriButeId.ImgTypeId)
              {
                localOta.ImgTypeId = data.AttriButeData;
              }
            }
            localOta.ReSave();
          }
          #endregion
        }
      }
      this.DeviceReportPush(report, ReceiveComandDiv.A设备属性上报);
    }
    #endregion
    #region ■ 传感器上报_________________________
    /// <summary>
    /// 传感器设备上报
    /// </summary>
    /// <param name="receiveData"></param>
    private void SensorDeviceReportPush(JObject receiveData)
    {
      var ias = new IASZone() { DeviceAddr = receiveData.Value<string>("DeviceAddr"), DeviceEpoint = receiveData.Value<int>("Epoint") };
      ias.iASInfo = Newtonsoft.Json.JsonConvert.DeserializeObject<IASZone.IASInfoData>(receiveData["Data"].ToString());
      //如果没有添加入安防
      if (HdlSafeguardLogic.Current.GetZoneIdByIASZone(ias) != -1)
      {
        //保存安防报警信息到本地
        HdlAlarmsLogic.Current.SaveSafeguardAlarmInfo(ias);
      }
      //处理网关上报的数据,然后变更本地缓存
      var locadevice = Common.LocalDevice.Current.GetDevice(ias.DeviceAddr, ias.DeviceEpoint);
      if (locadevice != null)
      {
        ((IASZone)locadevice).iASInfo = ias.iASInfo;
        //如果接收到上报,即说明这个传感器是在线的
        locadevice.IsOnline = 1;
        //记录回复时间
        locadevice.LastDateTime = DateTime.Now;
      }
      this.DeviceReportPush(ias, ReceiveComandDiv.A传感器上报);
      //显示有新消息的特效
      this.ShowHadNewMessageAppeal();
    }
    #endregion
    #region ■ 门锁上报___________________________
    /// <summary>
    /// 门锁上报
    /// </summary>
    /// <param name="receiveData"></param>
    private void DoorLockDeviceReportPush(JObject receiveData)
    {
      if (UserCenterResourse.UserInfo.AuthorityNo == 1)
      {
        var device = Common.LocalDevice.Current.GetDevice(receiveData.Value<string>("DeviceAddr"), receiveData.Value<int>("Epoint"));
        if (device.Type != DeviceType.DoorLock)
        {
          //它不是门锁
          return;
        }
        var info = Newtonsoft.Json.JsonConvert.DeserializeObject<DoorLockAlarmsResult>(receiveData["Data"].ToString());
        if (info.Clusterid == 257)
        {
          //216:锁上设置的常开
          if (info.AlarmCode == 216)
          {
            HdlThreadLogic.Current.RunMain(() =>
            {
              //更新门锁涉及的常开/常关的界面
              if (UserCenter.DoorLock.DoorLockCommonInfo.UpdateCurrentDoorlockAction != null)
              {
                UserCenter.DoorLock.DoorLockCommonInfo.UpdateCurrentDoorlockAction(device.DeviceAddr, true);
              }
            });
          }
        }
        //显示有新消息的特效
        this.ShowHadNewMessageAppeal();
      }
    }
    #endregion
    #region ■ 设备在线状态更新反馈_______________
    /// <summary>
    /// 设备在线状态更新反馈
    /// </summary>
    /// <param name="receiveData"></param>
    private void DeviceOnlineChangePush(JObject receiveData)
    {
      if (this.dicDeviceEvent.Count == 0)
      {
        //没有添加监听
        return;
      }
      var tempDevice = new CommonDevice() { DeviceAddr = receiveData.Value<string>("DeviceAddr"), DeviceEpoint = receiveData.Value<int>("Epoint") };
      tempDevice.IsOnline = Convert.ToInt32(receiveData["Data"]["IsOnline"].ToString());
      //处理网关上报的数据,然后变更本地缓存
      var locadevice = Common.LocalDevice.Current.GetDevicesByMac(tempDevice.DeviceAddr);
      for (int i = 0; i < locadevice.Count; i++)
      {
        bool onlineChanged = locadevice[i].IsOnline != tempDevice.IsOnline;
        locadevice[i].IsOnline = tempDevice.IsOnline;
        //记录回复时间
        locadevice[i].LastDateTime = DateTime.Now;
        if (onlineChanged == true)
        {
          //在线状态变更了,才保存
          locadevice[i].ReSave();
        }
      }
      this.DeviceReportPush(tempDevice, ReceiveComandDiv.A设备在线上报);
    }
    #endregion
    #region ■ 设备控制状态反馈___________________
    /// <summary>
    /// 设备控制状态反馈
    /// </summary>
    /// <param name="receiveData"></param>
    private void DeviceControlResponePush(JObject receiveData)
    {
      if (this.dicDeviceEvent.Count == 0)
      {
        //没有添加监听
        return;
      }
      var tempDevice = new CommonDevice() { DeviceAddr = receiveData.Value<string>("DeviceAddr"), DeviceEpoint = receiveData.Value<int>("Epoint") };
      this.DeviceReportPush(tempDevice, ReceiveComandDiv.A节点控制反馈);
    }
    #endregion
    #region ■ 布防_______________________________
    /// <summary>
    /// 布防推送
    /// </summary>
    /// <param name="receiveData"></param>
    private void SetSafetyGarrisonPush(JObject receiveData)
    {
      var data = Newtonsoft.Json.JsonConvert.DeserializeObject<Safeguard.EnableModeResponseData>(receiveData["Data"].ToString());
      if (data.Result == 0)
      {
        var garrison = GarrisonMode.None;
        //在家布防
        if (data.ModeId == 1) { garrison = GarrisonMode.AtHome; }
        //离家布防
        else if (data.ModeId == 2) { garrison = GarrisonMode.RemoveHome; }
        else { return; }
        //保存报警信息然后推送到界面上
        HdlAlarmsLogic.Current.SaveSafeguardAlarmInfo(garrison);
        if (UserCenterResourse.DicActionForm.ContainsKey("SafetyManagementMainForm") == true)
        {
          //推送
          var form = (Safety.SafetyManagementMainForm)UserCenterResourse.DicActionForm["SafetyManagementMainForm"];
          form?.GarrisonModePush(garrison);
        }
        //显示有新消息的特效
        this.ShowHadNewMessageAppeal();
      }
    }
    #endregion
    #region ■ 撤防_______________________________
    /// <summary>
    /// 撤防推送
    /// </summary>
    /// <param name="receiveData"></param>
    private void RemoveSafetyGarrisonPush(JObject receiveData)
    {
      var data = Newtonsoft.Json.JsonConvert.DeserializeObject<Safeguard.WithdrawModeResponseData>(receiveData["Data"].ToString());
      if (data.Result == 0)
      {
        //保存报警信息然后推送到界面上
        HdlAlarmsLogic.Current.SaveSafeguardAlarmInfo(GarrisonMode.RemoveGarrison);
        if (UserCenterResourse.DicActionForm.ContainsKey("SafetyManagementMainForm") == true)
        {
          //推送
          var form = (Safety.SafetyManagementMainForm)UserCenterResourse.DicActionForm["SafetyManagementMainForm"];
          form?.GarrisonModePush(GarrisonMode.RemoveGarrison);
        }
        //显示有新消息的特效
        this.ShowHadNewMessageAppeal();
      }
    }
    #endregion
    #region ■ 通过外部方式布防撤防_______________
    /// <summary>
    /// 通过外部方式布防撤防
    /// </summary>
    /// <param name="receiveData">接收的数据</param>
    private void SecurityEnOrWithdrawSucceedReport(JObject receiveData)
    {
      var data = Newtonsoft.Json.JsonConvert.DeserializeObject<SecurityEnOrWithdrawResult>(receiveData["Data"].ToString());
      if (data.EnOrWithdraw == -1 || data.ModeId == -1 || data.OperationWay == -1)
      {
        return;
      }
      var garrison = GarrisonMode.None;
      if (data.EnOrWithdraw == 0)
      {
        //在家布防
        if (data.ModeId == 1) { garrison = GarrisonMode.AtHome; }
        //离家布防
        else if (data.ModeId == 2) { garrison = GarrisonMode.RemoveHome; }
      }
      else if (data.EnOrWithdraw == 1)
      {
        //撤防
        garrison = GarrisonMode.RemoveGarrison;
      }
      string appendText = string.Empty;
      //自动化
      if (data.OperationWay == 0) { appendText = "(" + Language.StringByID(R.MyInternationalizationString.uLogicOperation) + ")"; }
      //按键操作
      else if (data.OperationWay == 1) { appendText = "(" + Language.StringByID(R.MyInternationalizationString.uPanelOperation) + ")"; }
      //保存报警信息然后推送到界面上
      HdlAlarmsLogic.Current.SaveSafeguardAlarmInfo(garrison, appendText);
      if (UserCenterResourse.DicActionForm.ContainsKey("SafetyManagementMainForm") == true)
      {
        //推送
        var form = (Safety.SafetyManagementMainForm)UserCenterResourse.DicActionForm["SafetyManagementMainForm"];
        form?.GarrisonModePush(garrison);
      }
      //显示有新消息的特效
      this.ShowHadNewMessageAppeal();
    }
    /// <summary>
    /// 通过外部方式布防撤防的接收结果
    /// </summary>
    private class SecurityEnOrWithdrawResult
    {
      /// <summary>
      /// 0:布防成功  1:撤防成功
      /// </summary>
      public int EnOrWithdraw = -1;
      /// <summary>
      /// 安防模式id
      /// </summary>
      public int ModeId = -1;
      /// <summary>
      /// 外部布撤防方式-> 0:执行逻辑动作  1:按键操作
      /// </summary>
      public int OperationWay = -1;
    }
    #endregion
    #region ■ 逻辑触发上报_______________________
    /// <summary>
    /// 逻辑触发上报
    /// </summary>
    /// <param name="receiveData"></param>
    private void LogicExecutePush(JObject receiveData)
    {
      //显示有新消息的特效
      this.ShowHadNewMessageAppeal();
      // 逻辑执行常开模式失效的情况
      if (UserCenterResourse.UserInfo.AuthorityNo == 1)
      {
        //自动化执行 常开关闭
        var data = Newtonsoft.Json.JsonConvert.DeserializeObject<LogicPushResult>(receiveData["Data"].ToString());
        if (data != null && data.ActionData != null)
        {
          if (data.ActionData.Actiontype == 8 && data.ActionData.PassDataString == "055704010113")
          {
            var deviceAddr = data.ActionData.MacStr;
            var device = Common.LocalDevice.Current.GetDevicesByMac(deviceAddr, false);
            if (device.Count > 0 && device[0].Type != DeviceType.DoorLock)
            {
              return;
            }
            HdlThreadLogic.Current.RunThread(async () =>
            {
              HdlThreadLogic.Current.RunMain(() =>
                          {
                            //提示门锁已经失效
                            new Tip() { MaxWidth = 150, Text = Language.StringByID(R.MyInternationalizationString.NormallyClosed), Direction = AMPopTipDirection.None, CloseTime = 1 }.Show(Common.CommonPage.Instance);
                            //更新门锁涉及的常开/常关的界面
                            if (UserCenter.DoorLock.DoorLockCommonInfo.UpdateCurrentDoorlockAction != null)
                            {
                              UserCenter.DoorLock.DoorLockCommonInfo.UpdateCurrentDoorlockAction(deviceAddr, false);
                            }
                          });
            });
          }
        }
      }
    }
    #endregion
    #region ■ 场景触发上报_______________________
    /// <summary>
    /// 场景触发上报
    /// </summary>
    /// <param name="receiveData"></param>
    private void SceneExecPush(JObject receiveData)
    {
      //目前不处理场景上报内容
      //显示有新消息的特效
      this.ShowHadNewMessageAppeal();
    }
    #endregion
    #region ■ 添加设备事件_______________________
    /// <summary>
    /// 添加获取设备属性的事件(属性上报的对象:device.DeviceStatusReport)
    /// </summary>
    /// <param name="mainKeys">标识事件的主键(可以随便填,主要是针对多个界面一起使用的情况)</param>
    /// <param name="comand">命令区分</param>
    /// <param name="action">
    /// <para>当接收到网关回复之后的回调函数</para>
    /// <para>设备属性上报的对象:device.DeviceStatusReport</para>
    /// <para>传感器上报的对象:ias.iASInfo</para>
    /// <para>设备在线上报的对象:device.IsOnline</para></param>
    public void AddAttributeEvent(string mainKeys, ReceiveComandDiv comand, Action<CommonDevice> action)
    {
      lock (this.dicDeviceEvent)
      {
        if (this.dicDeviceEvent.ContainsKey(mainKeys) == true)
        {
          this.RemoveEvent(mainKeys);
        }
        this.dicDeviceEvent[mainKeys] = action;
        this.dicCommandDiv[mainKeys] = comand;
      }
    }
    /// <summary>
    /// 添加网关接收事件(action只能存在一个,与AddAttributeEvent不共存,AddAttributeEvent优先)
    /// </summary>
    /// <param name="i_gatewayId">网关id</param>
    /// <param name="action">只能存在一个action (参数1:主题 参数2:推送消息)</param>
    public void AddGatewayReceiveEvent(string i_gatewayId, Action<string, string> action)
    {
      //添加事件
      this.GatewayReceiveEvent = action;
      this.GatewayReceiveId = i_gatewayId;
    }
    #endregion
    #region ■ 移除设备监听_______________________
    /// <summary>
    /// 移除事件
    /// </summary>
    /// <param name="mainKeys">标识事件的主键(可以随便填,主要是针对多个界面一起使用的情况)</param>
    public void RemoveEvent(string mainKeys)
    {
      lock (this.dicDeviceEvent)
      {
        if (this.dicDeviceEvent.ContainsKey(mainKeys) == true)
        {
          var action = this.dicDeviceEvent[mainKeys];
          this.dicDeviceEvent.Remove(mainKeys);
          this.dicCommandDiv.Remove(mainKeys);
          action = null;
        }
      }
    }
    /// <summary>
    /// 移除全部的事件
    /// </summary>
    public void RemoveAllEvent()
    {
      lock (this.dicDeviceEvent)
      {
        var list = new HashSet<string>();
        foreach (var keys in this.dicDeviceEvent.Keys)
        {
          list.Add(keys);
        }
        foreach (var keys in list)
        {
          //需要慢慢一个一个的释放Action,听说
          this.RemoveEvent(keys);
        }
      }
    }
    /// <summary>
    /// 移除网关接收事件(只能存在一个事件)
    /// </summary>
    public void RemoveGatewayReceiveEvent()
    {
      this.GatewayReceiveEvent = null;
      this.GatewayReceiveId = null;
    }
    #endregion
    #region ■ 一般方法___________________________
    /// <summary>
    /// 设备上报推送(调用此方法,他会推送到各自的界面)
    /// </summary>
    /// <param name="common"></param>
    /// <param name="comand"></param>
    public void DeviceReportPush(CommonDevice common, ReceiveComandDiv comand)
    {
      if (this.dicDeviceEvent.Count == 0)
      {
        //没有添加监听
        return;
      }
      //lock (this.dicDeviceEvent)
      {
        var list = new List<Action<CommonDevice>>();
        try
        {
          foreach (string keys in this.dicDeviceEvent.Keys)
          {
            if (this.dicCommandDiv[keys] != comand)
            {
              //命令区分不一致,则不调用回调函数
              continue;
            }
            //命令区分一致时,则调用回调函数
            list.Add(this.dicDeviceEvent[keys]);
          }
        }
        catch { return; }
        //有可能在回调函数中移除了事件,导致报错,所以先收集,再调用
        foreach (var action in list)
        {
          try
          {
            action?.Invoke(common);
          }
          catch (Exception ex)
          {
            //Log出力
            string msg = "推送错误! 当前激活的界面[" + UserCenterResourse.NowActionFormID + "]";
            HdlLogLogic.Current.WriteLog(ex, msg);
          }
        }
      }
    }
    /// <summary>
    /// 是否存在指定的事件
    /// </summary>
    /// <param name="mainkeys"></param>
    /// <returns></returns>
    public bool IsEsixt(string mainkeys)
    {
      return this.dicCommandDiv.ContainsKey(mainkeys);
    }
    /// <summary>
    /// 显示有新消息的特效
    /// </summary>
    private void ShowHadNewMessageAppeal()
    {
      //有新消息(特效还在时,不需要再处理)
      if (ControlCommonResourse.HadNewMessage == false)
      {
        HdlThreadLogic.Current.RunMain(() =>
        {
          for (int i = 0; i < ControlCommonResourse.listMessageManaContr.Count; i++)
          {
            //显示角标特效
            ControlCommonResourse.listMessageManaContr[i].IsSelected = true;
          }
          ControlCommonResourse.HadNewMessage = true;
        });
      }
    }
    #endregion
  }
  /// <summary>
  /// 接收命令区分
  /// </summary>
  public enum ReceiveComandDiv
  {
    /// <summary>
    /// 设备属性上报
    /// </summary>
    A设备属性上报 = 1,
    /// <summary>
    /// 传感器上报
    /// </summary>
    A传感器上报 = 2,
    /// <summary>
    /// 设备在线上报
    /// </summary>
    A设备在线上报 = 3,
    /// <summary>
    /// 当客户端发送控制设备指令,如打开或关闭设备、调节亮度、颜色。如果被控制的节点设备在线,节点设备将反馈
    /// </summary>
    A节点控制反馈 = 4
  }
}