HDL Home App 第二版本 旧平台金堂用 正在使用
黄学彪
2020-12-31 fe3b2466c68b5db70d38e78039703add3b8b1dfe
ZigbeeApp/Shared/Phone/ZigBee/Device/TemperatureSensor.cs
@@ -1,12 +1,19 @@
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()
        {
            this.Type = DeviceType.TemperatureSensor;
        }
        /// <summary>
        /// 因为这两个东西共用同一个设备ID,所以 1:温度传感器  2:湿度传感器
        /// 因为这两个东西共用同一个设备ID,所以 1:温度传感器  2:湿度传感器
        /// </summary>
        public int SensorDiv = 1;
@@ -18,12 +25,72 @@
        /// 湿度
        /// </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>
        [Newtonsoft.Json.JsonIgnore]
        public Dictionary<int, LedTimeData> AirQualitySensorLedTimeList = new Dictionary<int, LedTimeData> { };
        public TemperatureSensor()
        #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)
        {
            this.Type = DeviceType.TemperatureSensor ;
            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>
@@ -38,5 +105,473 @@
                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
    }
}