| | |
| | | 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; |
| | | |
| | |
| | | /// 湿度 |
| | | /// </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> |
| | |
| | | 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 |
| | | } |
| | | } |