HDL Home App 第二版本 旧平台金堂用 正在使用
ZigbeeApp/Shared/Phone/ZigBee/Device/TemperatureSensor.cs
old mode 100755 new mode 100644
@@ -1,27 +1,576 @@
using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json.Linq;
namespace ZigBee.Device
{
    public class TemperatureSensor: CommonDevice
  public class TemperatureSensor : CommonDevice
  {
    public TemperatureSensor()
    {
        /// <summary>
        /// 因为这两个东西共用同一个设备ID,所以 1:温度传感器  2:湿度传感器
        /// </summary>
        public int SensorDiv = 1;
        public TemperatureSensor()
        {
            this.Type = DeviceType.TemperatureSensor ;
        }
        /// <summary>
        /// 读取温/湿度
        /// </summary>
        public void ReadTemperature()
        {
            ReadAttri(Device.Cluster_ID.TemperatureMeasurement, AttriButeId.MeasuredValue );
            ReadAttri(Device.Cluster_ID.RelativeHumidityMeasurement, AttriButeId.MeasuredValue);
        }
      this.Type = DeviceType.TemperatureSensor;
    }
    /// <summary>
    /// 因为这两个东西共用同一个设备ID,所以 1:温度传感器  2:湿度传感器
    /// </summary>
    public int SensorDiv = 1;
    /// <summary>
    /// 温度
    /// </summary>
    public decimal currentTemperature = 0;
    /// <summary>
    /// 湿度
    /// </summary>
    public decimal currentHumidity = 0;
    /// <summary>
    /// 当前PM2.5值
    /// </summary>
    public decimal currentPmData = 0;
    /// <summary>
    /// 当前CO2
    /// </summary>
    public decimal currentCO2 = 0;
    /// <summary>
    /// 开光状态:0=关,1=开,
    /// </summary>
    [Newtonsoft.Json.JsonIgnore]
    public int OnOffStatus = 0;
    /// <summary>
    /// 空气质量传感器时间失效列表
    /// key:序号,value:LedTimeData
    /// </summary>
    public Dictionary<int, LedTimeData> AirQualitySensorLedTimeList = new Dictionary<int, LedTimeData> { };
    #region 开关
    ///<summary >
    ///开关控制(仅用于cluster=6的设备)
    /// <para>设备支持cluster=6的设备才能调用该接口</para>
    /// <para>command的值</para>
    ///<para>0 : 关闭</para>
    ///<para>1: 打开</para>
    ///<para>2:取反</para>
    /// </summary>
    public void SwitchControl(int command)
    {
      try
      {
        var jobject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", DeviceEpoint }, { "Cluster_ID", 6 }, { "Command", command }, { "SendMode", 2 } };
        Gateway?.Send(("DeviceControl"), jobject.ToString());
        System.Console.WriteLine("SwitchControl_发送数据" + "_" + jobject.ToString() + "_" + System.DateTime.Now.ToString());
      }
      catch { }
    }
    /// <summary>
    /// 发送获取灯光状态命令
    /// </summary>
    /// <param name="device">窗帘</param>
    public void SendSwitchStatuComand()
    {
      var jObject = new Newtonsoft.Json.Linq.JObject
            {
                { "DeviceAddr",DeviceAddr },
                { "Epoint",DeviceEpoint },
                { "Cluster_ID", (int)Cluster_ID.Switch },
                { "Command", 108 }
            };
      var attriBute = new Newtonsoft.Json.Linq.JArray
            {
               new Newtonsoft.Json.Linq.JObject
               {
                 { "AttriButeId", (int)AttriButeId.Switch}
               }
            };
      var data = new Newtonsoft.Json.Linq.JObject { { "AttriBute", attriBute } };
      jObject.Add("Data", data);
      Gateway?.Send(("GetDeviceStatus"), jObject.ToString());
    }
    #endregion
    /// <summary>
    /// 读取温/湿度
    /// </summary>
    public void ReadTemperatureOrHumidity()
    {
      if (SensorDiv == 1)
      {
        ReadAttri(Device.Cluster_ID.TemperatureMeasurement, AttriButeId.MeasuredValue);
      }
      else if (SensorDiv == 2)
      {
        ReadAttri(Device.Cluster_ID.RelativeHumidityMeasurement, AttriButeId.MeasuredValue);
      }
    }
    /// <summary>
    /// 空气质量等级(1:优;2:良;3:污染)
    /// </summary>
    /// <param name="tempera"></param>
    /// <returns></returns>
    public int AirQuality(TemperatureSensor tempera)
    {
      //空气质量
      int curQuality = 0;
      //pm等级(1:优;2:良;3:轻度污染;4:重度污染;)
      int pmQuality = 0;
      //co2等级(1:优(清晰);2:良(浑浊);3:轻度污染(缺氧);4:重度污染(严重缺氧);)
      int co2Quality = 0;
      //温度
      string temperature = string.Empty;
      //湿度
      string humidity = string.Empty;
      //PM2.5
      string pm = string.Empty;
      //CO2
      string co2 = string.Empty;
      if (tempera.currentPmData <= 35 && tempera.currentPmData >= 0)
      {
        pmQuality = 1;
      }
      else if (tempera.currentPmData <= 75 && tempera.currentPmData > 35)
      {
        pmQuality = 2;
      }
      else if (tempera.currentPmData <= 115 && tempera.currentPmData > 75)
      {
        pmQuality = 3;
      }
      else if (tempera.currentPmData > 115)
      {
        pmQuality = 4;
      }
      else
      {
        pmQuality = 0;
      }
      if (tempera.currentCO2 <= 1000 && tempera.currentCO2 >= 0)
      {
        co2Quality = 1;
      }
      else if (tempera.currentCO2 <= 2000 && tempera.currentCO2 > 1000)
      {
        co2Quality = 2;
      }
      else if (tempera.currentCO2 <= 5000 && tempera.currentCO2 > 2000)
      {
        co2Quality = 3;
      }
      else if (tempera.currentCO2 > 5000)
      {
        co2Quality = 4;
      }
      else
      {
        co2Quality = 0;
      }
      if (co2Quality == 1 && pmQuality == 1)
      {
        curQuality = 1;
      }
      else if (co2Quality == 2 || pmQuality == 2)
      {
        curQuality = 2;
      }
      else
      {
        curQuality = 3;
      }
      return curQuality;
    }
    #region led时间
    ///<summary >
    /// 配置led失能时间
    /// <para>number:序号</para>
    /// </summary>
    public async System.Threading.Tasks.Task<ResponseAllData> SetAirQualitySensorLedTime(LedTimeData ledTimeData)
    {
      ResponseAllData result = null;
      if (Gateway == null)
      {
        return result;
      }
      return await System.Threading.Tasks.Task.Run(async () =>
      {
        Action<string, string> action = (topic, message) =>
        {
          var gatewayID = topic.Split('/')[0];
          var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
          if (topic == gatewayID + "/" + "ZbDataPassthrough")
          {
            var clientDataPassthroughResponseData = Newtonsoft.Json.JsonConvert.DeserializeObject<ClientDataPassthroughResponseData>(jobject["Data"].ToString());
            if (clientDataPassthroughResponseData != null)
            {
              if (clientDataPassthroughResponseData?.PassData != null)
              {
                var data = clientDataPassthroughResponseData.PassData;
                if (data.Length == 16)
                {
                  var command = data[4].ToString() + data[5].ToString() + data[2].ToString() + data[3].ToString();
                  if (command == "0002")
                  {
                    var tempD = new ResponseData();
                    tempD.command = data[12].ToString() + data[13].ToString() + data[10].ToString() + data[11].ToString();
                    tempD.status = Convert.ToInt32(data[14].ToString() + data[15].ToString(), 16);
                    if (tempD.command == "0412")
                    {
                      result = new ResponseAllData { responseData = tempD };
                      System.Console.WriteLine($"UI收到通知后的主题_command:0400_{ topic}");
                    }
                  }
                }
              }
            }
          }
        };
        Gateway.Actions += action;
        System.Console.WriteLine("ClientDataPassthrough_Actions 启动" + System.DateTime.Now.ToString());
        try
        {
          var passData = SetAirQualitySensorLedTimeDataStr(ledTimeData);
          var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
          var data = new JObject { { "PassData", passData } };
          jObject.Add("Data", data);
          Gateway.Send(("ClientDataPassthrough"), jObject.ToString());
        }
        catch { }
        var dateTime = DateTime.Now;
        while ((DateTime.Now - dateTime).TotalMilliseconds < 9000)// WaitReceiveDataTime)
        {
          await System.Threading.Tasks.Task.Delay(10);
          if (result != null)
          {
            break;
          }
        }
        if ((DateTime.Now - dateTime).TotalMilliseconds > WaitReceiveDataTime)
        {
          result = null;
        }
        Gateway.Actions -= action;
        System.Console.WriteLine("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString());
        return result;
      });
    }
    /// <summary>
    ///配置led失能时间数据
    /// </summary>
    string SetAirQualitySensorLedTimeDataStr(LedTimeData ledTimeData)
    {
      string data = "";
      string dataLength = "10";
      string dataComand1 = "12";
      string dataComand2 = "04";
      string dataSerialNum = "01";
      string addDataLength = "6";
      string serialNum = "";
      string sEnable = "";
      string startHour = "";
      string startMin = "";
      string endHour = "";
      string endMin = "";
      string remark = "";
      try
      {
        if (ledTimeData == null)
        {
          return "";
        }
        int dataLength1 = 10;
        int addDataLength1 = 6;
        if (!string.IsNullOrEmpty(ledTimeData.remark))
        {
          var reamarkGwBytes = System.Text.Encoding.UTF8.GetBytes(ledTimeData.remark);
          int len = 36 < reamarkGwBytes.Length ? 36 : reamarkGwBytes.Length;
          dataLength1 += len;
          addDataLength1 += len;
        }
        dataLength = Convert.ToString(dataLength1, 16);
        if (dataLength.Length == 1)
        {
          dataLength = "0" + dataLength;
        }
        addDataLength = Convert.ToString(addDataLength1, 16);
        if (addDataLength.Length == 1)
        {
          addDataLength = "0" + addDataLength;
        }
        //因为只有0~4个序号,总共5个
        serialNum = "0" + ledTimeData.serialNum.ToString();
        if (ledTimeData.enable == 1)
        {
          sEnable = "01";
        }
        else
        {
          sEnable = "00";
        }
        startHour = Convert.ToString(ledTimeData.startHour, 16);
        if (startHour.Length == 1)
        {
          startHour = "0" + startHour;
        }
        startMin = Convert.ToString(ledTimeData.startMin, 16);
        if (startMin.Length == 1)
        {
          startMin = "0" + startMin;
        }
        endHour = Convert.ToString(ledTimeData.endHour, 16);
        if (endHour.Length == 1)
        {
          endHour = "0" + endHour;
        }
        endMin = Convert.ToString(ledTimeData.endMin, 16);
        if (endMin.Length == 1)
        {
          endMin = "0" + endMin;
        }
        remark = StringToHexString(ledTimeData.remark);
        data = dataLength + dataComand1 + dataComand2 + dataSerialNum + addDataLength +
          serialNum + sEnable + startHour + startMin + endHour + endMin + remark;
      }
      catch { };
      return data;
    }
    private string StringToHexString(string s)
    {
      var reamarkGwBytes = System.Text.Encoding.UTF8.GetBytes(s);
      int len = 36 < reamarkGwBytes.Length ? 36 : reamarkGwBytes.Length;
      var bytes = new byte[len];
      System.Array.Copy(reamarkGwBytes, 0, bytes, 0, len);
      string result = string.Empty;
      for (int i = 0; i < bytes.Length; i++)//逐字节变为16进制字符
      {
        string temp = Convert.ToString(bytes[i], 16);
        if (temp.Length == 1)
        {
          temp = "0" + temp;
        }
        result += temp;
      }
      return result;
    }
    private string HexStringToString(string hs)
    {
      //以%分割字符串,并去掉空字符
      string[] chars = hs.Split(new char[] { '%' }, StringSplitOptions.RemoveEmptyEntries);
      byte[] b = new byte[chars.Length];
      //逐个字符变为16进制字节数据
      for (int i = 0; i < chars.Length; i++)
      {
        b[i] = Convert.ToByte(chars[i], 16);
      }
      //按照指定编码将字节数组变为字符串
      return System.Text.Encoding.UTF8.GetString(b);
    }
    private string StringToHexString1(string s)
    {
      var bytes = new byte[36];
      var reamarkGwBytes = System.Text.Encoding.UTF8.GetBytes(s);
      System.Array.Copy(reamarkGwBytes, 0, bytes, 0, 36 < reamarkGwBytes.Length ? 36 : reamarkGwBytes.Length);
      string result = string.Empty;
      for (int i = 0; i < bytes.Length; i++)//逐字节变为16进制字符,以%隔开
      {
        result += "%" + Convert.ToString(bytes[i], 16);
      }
      return result;
    }
    private string HexStringToString1(string hs)
    {
      //以%分割字符串,并去掉空字符
      string[] chars = hs.Split(new char[] { '%' }, StringSplitOptions.RemoveEmptyEntries);
      byte[] b = new byte[chars.Length];
      //逐个字符变为16进制字节数据
      for (int i = 0; i < chars.Length; i++)
      {
        b[i] = Convert.ToByte(chars[i], 16);
      }
      //按照指定编码将字节数组变为字符串
      return System.Text.Encoding.UTF8.GetString(b);
    }
    ///<summary >
    /// 获取led失能时间
    /// <para>number:序号</para>
    /// </summary>
    public async System.Threading.Tasks.Task<LedTimeData> ReadAirQualitySensorLedTime(int number)
    {
      LedTimeData result = null;
      if (Gateway == null)
      {
        return result;
      }
      return await System.Threading.Tasks.Task.Run(async () =>
      {
        Action<string, string> action = (topic, message) =>
        {
          var gatewayID = topic.Split('/')[0];
          var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
          if (topic == gatewayID + "/" + "ZbDataPassthrough")
          {
            var clientDataPassthroughResponseData = Newtonsoft.Json.JsonConvert.DeserializeObject<ClientDataPassthroughResponseData>(jobject["Data"].ToString());
            if (clientDataPassthroughResponseData != null)
            {
              if (clientDataPassthroughResponseData?.PassData != null)
              {
                var data = clientDataPassthroughResponseData.PassData;
                var command = data[4].ToString() + data[5].ToString() + data[2].ToString() + data[3].ToString();
                if (command == "0413")
                {
                  result = new LedTimeData();
                  result.serialNum = Convert.ToInt32(data[10].ToString() + data[11].ToString(), 16);
                  result.enable = Convert.ToInt32(data[12].ToString() + data[13].ToString(), 16);
                  result.startHour = Convert.ToInt32(data[14].ToString() + data[15].ToString(), 16);
                  result.startMin = Convert.ToInt32(data[16].ToString() + data[17].ToString(), 16);
                  result.endHour = Convert.ToInt32(data[18].ToString() + data[19].ToString(), 16);
                  result.endMin = Convert.ToInt32(data[20].ToString() + data[21].ToString(), 16);
                  string remark = data.Substring(22, data.Length - 22);
                  var bytes = new byte[remark.Length / 2];
                  for (int i = 0; i < bytes.Length; i++)
                  {
                    bytes[i] = (byte)Convert.ToInt32(remark.Substring(i * 2, 2), 16);
                  }
                  result.remark = System.Text.Encoding.UTF8.GetString(bytes);
                }
              }
            }
          }
        };
        Gateway.Actions += action;
        System.Console.WriteLine("ClientDataPassthrough_Actions 启动" + System.DateTime.Now.ToString());
        try
        {
          var passData = ReadAirQualitySensorLedTimeDataStr(number);
          var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", 200 }, { "Cluster_ID", 64513 }, { "Command", 0 } };
          var data = new JObject { { "PassData", passData } };
          jObject.Add("Data", data);
          Gateway.Send(("ClientDataPassthrough"), jObject.ToString());
        }
        catch { }
        var dateTime = DateTime.Now;
        while ((DateTime.Now - dateTime).TotalMilliseconds < 9000)// WaitReceiveDataTime)
        {
          await System.Threading.Tasks.Task.Delay(10);
          if (result != null)
          {
            break;
          }
        }
        if ((DateTime.Now - dateTime).TotalMilliseconds > WaitReceiveDataTime)
        {
          result = null;
        }
        Gateway.Actions -= action;
        System.Console.WriteLine("ClientDataPassthrough_Actions 退出" + System.DateTime.Now.ToString());
        return result;
      });
    }
    /// <summary>
    /// 获取led失能时间
    /// </summary>
    string ReadAirQualitySensorLedTimeDataStr(int number)
    {
      string data = "";
      string dataLength = "05";
      string dataComand1 = "11";
      string dataComand2 = "04";
      string dataSerialNum = "01";
      string addDataLength = "01";
      string num = "";
      try
      {
        if (number == 1)
        {
          num = "01";
        }
        else
        {
          num = "00";
        }
        data = dataLength + dataComand1 + dataComand2 + dataSerialNum + addDataLength +
          num;
      }
      catch { };
      return data;
    }
    /// <summary>
    /// 配置led失能时间数据
    /// </summary>
    [System.Serializable]
    public class LedTimeData
    {
      /// <summary>
      /// 序号(正常序号0~4,共5个)
      /// </summary>
      public int serialNum = -1;
      /// <summary>
      /// 使能位
      /// <para>0-无效 1--有效</para>
      /// </summary>
      public int enable = 0;
      /// <summary>
      /// 起始时
      /// </summary>
      public int startHour;
      /// <summary>
      /// 起始分
      /// </summary>
      public int startMin;
      /// <summary>
      /// 结束时
      /// </summary>
      public int endHour;
      /// <summary>
      /// 结束分
      /// </summary>
      public int endMin;
      /// <summary>
      /// 备注
      /// </summary>
      public string remark;
    }
    #endregion
  }
}