HDL Home App 第二版本 旧平台金堂用 正在使用
ZigbeeApp/Shared/Phone/UserCenter/CommonBase/Logic/HdlDeviceCommonLogic.cs
New file
@@ -0,0 +1,309 @@
using System;
using System.Collections.Generic;
using System.Text;
using ZigBee.Device;
namespace Shared.Phone.UserCenter
{
  /// <summary>
  /// 设备的共通逻辑
  /// </summary>
  public class HdlDeviceCommonLogic
  {
    #region ■ 变量声明___________________________
    /// <summary>
    /// 设备的共通逻辑
    /// </summary>
    private static HdlDeviceCommonLogic m_Current = null;
    /// <summary>
    /// 设备的共通逻辑
    /// </summary>
    public static HdlDeviceCommonLogic Current
    {
      get
      {
        if (m_Current == null)
        {
          m_Current = new HdlDeviceCommonLogic();
        }
        return m_Current;
      }
      set
      {
        m_Current = value;
      }
    }
    #endregion
    #region ■ 发送数据___________________________
    /// <summary>
    /// 发送数据到网关,并接受网关返回的数据(非透传,ReceiptData为返回值)
    /// </summary>
    /// <param name="device">设备对象</param>
    /// <param name="sendTopic">发送的主题</param>
    /// <param name="sendData">需要发送的数据  JObject.ToString()的东西</param>
    /// <param name="receiptTopic">指定接收哪个主题</param>
    /// <param name="waitTime">超时时间(秒)</param>
    /// <returns>网关返回的数据</returns>
    public ReceiptGatewayResult SendJobjectDataToGateway(CommonDevice device, string sendTopic, string sendData, string receiptTopic, int waitTime = 5)
    {
      //发送数据到网关,并接受网关返回的数据
      return this.SendJobjectDataToGateway(device, sendTopic, sendData, new List<string>() { receiptTopic }, waitTime);
    }
    /// <summary>
    /// 发送数据到网关,并接受网关返回的数据(非透传),listReceiptData为返回值(全部主题全部接收得到,才会返回,不然会返回超时)
    /// </summary>
    /// <param name="device">设备对象</param>
    /// <param name="sendTopic">发送的主题</param>
    /// <param name="sendData">需要发送的数据  JObject.ToString()的东西</param>
    /// <param name="listReceiptTopic">指定接收哪些主题</param>
    /// <param name="waitTime">超时时间(秒)</param>
    /// <returns>网关返回的数据</returns>
    public ReceiptGatewayResult SendJobjectDataToGateway(CommonDevice device, string sendTopic, string sendData, List<string> listReceiptTopic, int waitTime = 5)
    {
      var reResult = new ReceiptGatewayResult();
      reResult.listReceiptData = new string[listReceiptTopic.Count];
      reResult.JsonData = new string[listReceiptTopic.Count];
      var myGateway = device.Gateway;
      if (myGateway == null)
      {
        //获取网关对象失败
        reResult.ErrorMsg = Language.StringByID(R.MyInternationalizationString.uGetGatewayTagartFail);
        reResult.ErrorMsgDiv = -1;
        return reResult;
      }
      //网关ID
      string gatewayID = device.Gateway.GwId;
      //错误主题
      string errorTopic = gatewayID + "/" + "Error_Respon";
      //检测对象的主题
      for (int i = 0; i < listReceiptTopic.Count; i++)
      {
        listReceiptTopic[i] = gatewayID + "/" + listReceiptTopic[i];
      }
      //蓝才刚整了个同一个主题可能会推送多个过来的机能
      var listCheckTopic = new HashSet<string>();
      Action<string, string> receiptAction = (topic, message) =>
      {
        var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
        //网关回复错误
        if (topic == errorTopic)
        {
          var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.ErrorResponData>(jobject["Data"].ToString());
          reResult.ErrorMsg = HdlCheckLogic.Current.CheckCommonErrorCode(temp.Error);
        }
        //如果是指定的主题
        for (int i = 0; i < listReceiptTopic.Count; i++)
        {
          if (topic == listReceiptTopic[i])
          {
            if (listCheckTopic.Contains(topic) == true)
            {
              //这里写这个东西是有点用处的
              continue;
            }
            string deviceMac = jobject["DeviceAddr"].ToString();
            int deviceEpoint = 200;
            if (jobject.Property("Epoint") != null)
            {
              //拥有此键值
              deviceEpoint = Convert.ToInt32(jobject["Epoint"].ToString());
            }
            if (device.DeviceAddr != deviceMac)
            {
              //不是同一个东西Mac
              return;
            }
            if (device.DeviceEpoint != deviceEpoint && deviceEpoint != 200)
            {
              //不是同一个东西,这里应该需要特殊处理200端点
              return;
            }
            reResult.listReceiptData[i] = jobject["Data"].ToString();
            if (jobject.Property("Time") != null)
            {
              //需要移除time这个字段
              jobject.Remove("Time");
            }
            reResult.JsonData[i] = jobject.ToString();
            if (listCheckTopic.Contains(topic) == false)
            {
              //加到检测主题对象中
              listCheckTopic.Add(topic);
            }
          }
        }
      };
      myGateway.Actions += receiptAction;
      //发送数据
      myGateway.Send(sendTopic, sendData);
      //超时时间
      int TimeOut = 0;
      waitTime = 20 * waitTime;
      while (listCheckTopic.Count != listReceiptTopic.Count && TimeOut < waitTime)
      {
        //全部接收才退出
        System.Threading.Thread.Sleep(50);
        TimeOut++;
      }
      myGateway.Actions -= receiptAction;
      receiptAction = null;
      int receveCount = listCheckTopic.Count;
      if (receveCount > 1)
      {
        //看看里面有没有重复的
        var listTemp = new HashSet<string>();
        foreach (var value in listCheckTopic)
        {
          if (listTemp.Contains(value) == false)
          {
            listTemp.Add(value);
          }
        }
        receveCount = listTemp.Count;
      }
      if (receveCount != listReceiptTopic.Count)
      {
        reResult.ErrorMsgDiv = 0;
      }
      else
      {
        //正常接收到网关返回的数据
        if (reResult.listReceiptData.Length == 1)
        {
          //如果只有一个主题,则替换变量
          reResult.ReceiptData = reResult.listReceiptData[0];
        }
      }
      return reResult;
    }
    /// <summary>
    /// 发送数据到网关,并接受网关返回的数据(透传专用)
    /// </summary>
    /// <param name="device">设备对象</param>
    /// <param name="sendData">需要发送的数据  JObject.ToString()的东西</param>
    /// <param name="receiptCommand">指定接收命令符</param>
    /// <param name="receiptDataLength">指定接收数据的长度</param>
    /// <param name="waitTime">超时时间(秒)</param>
    /// <param name="listReceiptLength">附加检测数据接收长度,当接收的长度在这列表里面时,代表接收成功(旨在对应新旧设备,透传回复的长度可能不同)</param>
    /// <returns>网关返回的数据</returns>
    public ReceiptGatewayResult SendJobjectDataToGateway2(CommonDevice device, string sendData, string receiptCommand, int receiptDataLength,
        int waitTime = 5, List<int> listReceiptLength = null)
    {
      var reResult = new ReceiptGatewayResult();
      var myGateway = device.Gateway;
      if (myGateway == null)
      {
        //获取网关对象失败
        reResult.ErrorMsg = Language.StringByID(R.MyInternationalizationString.uGetGatewayTagartFail);
        reResult.ErrorMsgDiv = -1;
        return reResult;
      }
      //网关ID
      string gatewayID = device.Gateway.GwId;
      //错误主题
      string errorTopic = gatewayID + "/" + "Error_Respon";
      //检测对象的主题
      string checkTopic = gatewayID + "/ZbDataPassthrough";
      Action<string, string> receiptAction = (topic, message) =>
      {
        var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
        //网关回复错误
        if (topic == errorTopic)
        {
          var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.ErrorResponData>(jobject["Data"].ToString());
          reResult.ErrorMsg = HdlCheckLogic.Current.CheckCommonErrorCode(temp.Error);
        }
        //如果是指定的主题
        if (topic == checkTopic)
        {
          string deviceMac = jobject["DeviceAddr"].ToString();
          int deviceEpoint = 200;
          if (jobject.Property("Epoint") != null)
          {
            //拥有此键值
            deviceEpoint = Convert.ToInt32(jobject["Epoint"].ToString());
          }
          if (device.DeviceAddr != deviceMac)
          {
            //不是同一个东西Mac
            return;
          }
          if (device.DeviceEpoint != deviceEpoint && deviceEpoint != 200)
          {
            //不是同一个东西,这里应该需要特殊处理200端点
            return;
          }
          var responseData = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.ClientDataPassthroughResponseData>(jobject["Data"].ToString());
          //长度不一致
          if (responseData.PassData.Length != receiptDataLength)
          {
            if (listReceiptLength == null)
            {
              //如果没有附加检测长度,则直接返回
              return;
            }
            if (listReceiptLength.Contains(responseData.PassData.Length) == false)
            {
              //如果附加的检测长度里面,还不存在的话,直接返回
              return;
            }
          }
          var command = responseData.PassData[4].ToString()
                    + responseData.PassData[5].ToString()
                    + responseData.PassData[2].ToString()
                    + responseData.PassData[3].ToString();
          //并且是这个命令
          if (command == receiptCommand)
          {
            reResult.ReceiptData = responseData.PassData;
            reResult.JsonData = new string[1];
            if (jobject.Property("Time") != null)
            {
              //需要移除time这个字段
              jobject.Remove("Time");
            }
            reResult.JsonData[0] = jobject.ToString();
          }
        }
      };
      myGateway.Actions += receiptAction;
      //发送数据
      myGateway.Send("ClientDataPassthrough", sendData);
      //超时时间
      int TimeOut = 0;
      waitTime = 20 * waitTime;
      while (reResult.ReceiptData == null && TimeOut < waitTime)
      {
        System.Threading.Thread.Sleep(50);
        TimeOut++;
      }
      myGateway.Actions -= receiptAction;
      receiptAction = null;
      if (reResult.ReceiptData == null)
      {
        //超时
        reResult.ErrorMsgDiv = 0;
      }
      return reResult;
    }
    #endregion
  }
}