| | |
| | | using System.Collections.Generic; |
| | | using System.Text; |
| | | using Newtonsoft.Json.Linq; |
| | | using Shared; |
| | | |
| | | namespace ZigBee.Device |
| | | { |
| | |
| | | { |
| | | #region 需要保存的变量 |
| | | |
| | | /// <summary>
|
| | | /// 是否是自定义图片
|
| | | /// <summary> |
| | | /// 是否是自定义图片 |
| | | /// </summary> |
| | | public bool IsCustomizeImage = false; |
| | | /// <summary> |
| | |
| | | { |
| | | get |
| | | { |
| | | if (string.IsNullOrEmpty(IconPath))
|
| | | {
|
| | | return string.Empty;
|
| | | if (string.IsNullOrEmpty(IconPath)) |
| | | { |
| | | return string.Empty; |
| | | } |
| | | var pathArr = IconPath.Split('.'); |
| | | if (pathArr == null || string.IsNullOrEmpty(pathArr[0])) |
| | |
| | | /// <para>262:Light sensor,光照传感器</para> |
| | | /// <para>1026:sensor,传感器,具体类型的传感器DeviceType来区分</para> |
| | | /// </summary> |
| | | public int DeviceID;
|
| | | /// <summary>
|
| | | /// <para>2020.09.21追加:为了对应第三方设备,以及之后的多设备ID问题,追加的变量</para>
|
| | | /// <para>这是个特殊的,并且不保存在文件当中的ID, DeviceType由此值映射出来</para>
|
| | | /// <para>当设备是河东设备时,它与DeviceID相等</para>
|
| | | /// <para>当是真正的第三方设备时,它有可能与DeviceID不相等</para>
|
| | | /// <para>比如:2和256都是继电器,那么【DeviceID为2 或者 DeviceID为256】 而 【ExDeviceID固定为2】,【DeviceType为OnOffOutput】</para>
|
| | | /// <para>通俗来说:DeviceID是实际正确的ID,而【ExDeviceID是一种所属概念的ID】</para>
|
| | | public int DeviceID; |
| | | /// <summary> |
| | | /// <para>2020.09.21追加:为了对应第三方设备,以及之后的多设备ID问题,追加的变量</para> |
| | | /// <para>这是个特殊的,并且不保存在文件当中的ID, DeviceType由此值映射出来</para> |
| | | /// <para>当设备是河东设备时,它与DeviceID相等</para> |
| | | /// <para>当是真正的第三方设备时,它有可能与DeviceID不相等</para> |
| | | /// <para>比如:2和256都是继电器,那么【DeviceID为2 或者 DeviceID为256】 而 【ExDeviceID固定为2】,【DeviceType为OnOffOutput】</para> |
| | | /// <para>通俗来说:DeviceID是实际正确的ID,而【ExDeviceID是一种所属概念的ID】</para> |
| | | /// </summary> |
| | | [Newtonsoft.Json.JsonIgnore] |
| | | public int ExDeviceID; |
| | |
| | | /// 0:设备不在线 |
| | | /// <para>1:设备在线</para> |
| | | /// </summary> |
| | | public int IsOnline;
|
| | | /// <summary>
|
| | | /// 1:路由设备
|
| | | /// <para>2:终端设备,电池设备</para>
|
| | | /// </summary>
|
| | | public int IsOnline; |
| | | /// <summary> |
| | | /// 1:路由设备 |
| | | /// <para>2:终端设备,电池设备</para> |
| | | /// </summary> |
| | | public int ZigbeeType; |
| | | /// <summary> |
| | | /// 固件版本 |
| | |
| | | /// <summary> |
| | | /// 输出簇列表 |
| | | /// </summary> |
| | | public List<OutClusterObj> OutClusterList = new List<OutClusterObj>();
|
| | | public List<OutClusterObj> OutClusterList = new List<OutClusterObj>(); |
| | | /// <summary> |
| | | /// 用于记录设备最新上报的属性状态信息 |
| | | /// </summary> |
| | |
| | | /// 是否已经读取了设备状态(此属性是给主页使用的) |
| | | /// </summary> |
| | | [Newtonsoft.Json.JsonIgnore] |
| | | public bool HadReadDeviceStatu = false;
|
| | |
|
| | | public bool HadReadDeviceStatu = false; |
| | | |
| | | /// <summary> |
| | | /// 是否是低电量(这个变量目前是给传感器用的) |
| | | /// </summary> |
| | |
| | | #endregion |
| | | |
| | | #region 设备保存及生成 |
| | |
|
| | | /// <summary>
|
| | | /// 由设备字符串比特恢复设备对象
|
| | | /// </summary>
|
| | | /// <param name="intDeviceType">设备DeviceType的整型值</param>
|
| | | /// <param name="strDeviceByte">设备Json文件转为比特后再转为的字符串</param>
|
| | | |
| | | /// <summary> |
| | | /// 由设备字符串比特恢复设备对象 |
| | | /// </summary> |
| | | /// <param name="intDeviceType">设备DeviceType的整型值</param> |
| | | /// <param name="strDeviceByte">设备Json文件转为比特后再转为的字符串</param> |
| | | /// <returns></returns> |
| | | public static CommonDevice CommonDeviceByByteString(int intDeviceType, string strDeviceByte) |
| | | {
|
| | | //这是河东的特殊端点,不需要处理
|
| | | if (intDeviceType == 49408)
|
| | | {
|
| | | return null;
|
| | | { |
| | | //这是河东的特殊端点,不需要处理 |
| | | if (intDeviceType == 49408) |
| | | { |
| | | return null; |
| | | } |
| | | |
| | | CommonDevice device = null; |
| | |
| | | } |
| | | else if (intDeviceType == (int)DeviceType.OnOffOutput || intDeviceType == 256) |
| | | { |
| | | device = Newtonsoft.Json.JsonConvert.DeserializeObject<ToggleLight>(strDeviceByte);
|
| | | device = Newtonsoft.Json.JsonConvert.DeserializeObject<ToggleLight>(strDeviceByte); |
| | | device.ExDeviceID = (int)DeviceType.OnOffOutput; |
| | | } |
| | | else if (intDeviceType == (int)DeviceType.ColorDimmerSwitch) |
| | |
| | | else if (intDeviceType == (int)DeviceType.DoorLock) |
| | | { |
| | | device = Newtonsoft.Json.JsonConvert.DeserializeObject<DoorLock>(strDeviceByte); |
| | | }
|
| | | } |
| | | else if (intDeviceType == (int)DeviceType.TemperatureSensor) |
| | | { |
| | | device = Newtonsoft.Json.JsonConvert.DeserializeObject<TemperatureSensor>(strDeviceByte); |
| | |
| | | else if (intDeviceType == (int)DeviceType.ColorTemperatureLight) |
| | | { |
| | | device = Newtonsoft.Json.JsonConvert.DeserializeObject<ColorTemperatureLight>(strDeviceByte); |
| | | }
|
| | | } |
| | | else if (intDeviceType == (int)DeviceType.Buzzer) |
| | | { |
| | | device = Newtonsoft.Json.JsonConvert.DeserializeObject<Buzzer>(strDeviceByte); |
| | |
| | | { |
| | | device = Newtonsoft.Json.JsonConvert.DeserializeObject<DimmerSwitch>(strDeviceByte); |
| | | } |
| | | else if (intDeviceType == (int)DeviceType.Airer) |
| | | { |
| | | device = Newtonsoft.Json.JsonConvert.DeserializeObject<Airer>(strDeviceByte); |
| | | } |
| | | else |
| | | {
|
| | | { |
| | | device = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice>(strDeviceByte); |
| | | } |
| | | |
| | | //这是河东的特殊端点,不需要处理 |
| | | if (device.DeviceEpoint == 242 && intDeviceType == 97)
|
| | | {
|
| | | return null;
|
| | | if (device.DeviceEpoint == 242 && intDeviceType == 97) |
| | | { |
| | | return null; |
| | | } |
| | | |
| | | if (device.ExDeviceID == 0)
|
| | | {
|
| | | //赋初始值
|
| | | device.ExDeviceID = device.DeviceID;
|
| | | if (device.ExDeviceID == 0) |
| | | { |
| | | //赋初始值 |
| | | device.ExDeviceID = device.DeviceID; |
| | | } |
| | | |
| | | //能少存一个变量就少存一个 |
| | |
| | | //展示模板时,不允许保存文件(防止属性上报用的) |
| | | return; |
| | | } |
| | | if (IconPath == string.Empty)
|
| | | {
|
| | | //保存设备图标(这里会保存一次,下面就不用保存了)
|
| | | this.SaveDeviceIcon();
|
| | | return;
|
| | | if (IconPath == string.Empty) |
| | | { |
| | | //保存设备图标(这里会保存一次,下面就不用保存了) |
| | | this.SaveDeviceIcon(); |
| | | return; |
| | | } |
| | | Shared.Common.Global.WriteFileByBytesByHomeId(FilePath, System.Text.Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(this))); |
| | | }
|
| | |
|
| | | } |
| | | |
| | | /// <summary> |
| | | /// 判断是否是空气质量传感器 |
| | | /// </summary> |
| | | /// <param name="dev"></param> |
| | | /// <returns></returns> |
| | | public bool isAirQualitySensor(CommonDevice dev) |
| | | { |
| | | bool hasT = false; |
| | | bool hasH = false; |
| | | bool hasPM = false; |
| | | bool hasCo2 = false; |
| | | foreach (var clu in dev.InClusterList) |
| | | { |
| | | switch (clu.InCluster) |
| | | { |
| | | case 1026: |
| | | hasT = true; |
| | | break; |
| | | case 1029: |
| | | hasH = true; |
| | | break; |
| | | case 1037: |
| | | hasCo2 = true; |
| | | break; |
| | | case 1066: |
| | | hasPM = true; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (hasT == true && hasH == true && hasPM == true && hasCo2 == true) |
| | | { |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 保存设备图标 |
| | | /// </summary> |
| | |
| | | { |
| | | if (IconPath == string.Empty) |
| | | { |
| | | //干接点
|
| | | if (this.Type == DeviceType.OnOffSwitch)
|
| | | {
|
| | | IconPath = "Device/DryContact.png";
|
| | | }
|
| | | //干接点 |
| | | if (this.Type == DeviceType.OnOffSwitch) |
| | | { |
| | | IconPath = "Device/DryContact.png"; |
| | | } |
| | | else if (this.Type == DeviceType.ColorDimmableLight) |
| | | { |
| | | //彩灯 |
| | | IconPath = "Device/ColorLight.png"; |
| | | }
|
| | | } |
| | | else if (this.Type == DeviceType.DimmableLight) |
| | | { |
| | | //调光器 |
| | | IconPath = "Device/Light.png"; |
| | | }
|
| | | else if (this.Type == DeviceType.ColorTemperatureLight)
|
| | | {
|
| | | //色温灯
|
| | | IconPath = "Device/ColorLightTemperature.png";
|
| | | } |
| | | else if (this.Type == DeviceType.ColorTemperatureLight) |
| | | { |
| | | //色温灯 |
| | | IconPath = "Device/ColorLightTemperature.png"; |
| | | } |
| | | else if (this.Type == DeviceType.OnOffOutput) |
| | | { |
| | |
| | | //湿度传感器 |
| | | IconPath = "Device/SensorHumidity.png"; |
| | | } |
| | | else if (this.Type == DeviceType.TemperatureSensor)
|
| | | {
|
| | | if (((TemperatureSensor)this).SensorDiv == 1)
|
| | | {
|
| | | //温度传感器
|
| | | IconPath = "Device/SensorTemperature.png";
|
| | | }
|
| | | else if (((TemperatureSensor)this).SensorDiv == 2)
|
| | | {
|
| | | //湿度传感器
|
| | | IconPath = "Device/SensorHumidity.png";
|
| | | }
|
| | | else if (this.Type == DeviceType.TemperatureSensor) |
| | | { |
| | | if (isAirQualitySensor(this)) |
| | | { |
| | | //空气质量传感器 |
| | | IconPath = "Device/AirQualitySensorEpoint.png"; |
| | | } |
| | | else |
| | | { |
| | | if (((TemperatureSensor)this).SensorDiv == 1) |
| | | { |
| | | //温度传感器 |
| | | IconPath = "Device/SensorTemperature.png"; |
| | | } |
| | | else if (((TemperatureSensor)this).SensorDiv == 2) |
| | | { |
| | | //湿度传感器 |
| | | IconPath = "Device/SensorHumidity.png"; |
| | | } |
| | | } |
| | | } |
| | | else if (this.Type != DeviceType.UnKown)
|
| | | {
|
| | | //其他的图标有点特殊
|
| | | string unSelectPic = string.Empty;
|
| | | string selectPic = string.Empty;
|
| | | Shared.Common.LocalDevice.Current.GetDeviceObjectIcon(new List<CommonDevice> { this }, ref unSelectPic, ref selectPic);
|
| | | IconPath = unSelectPic;
|
| | | }
|
| | | else if (this.Type != DeviceType.UnKown) |
| | | { |
| | | //其他的图标有点特殊 |
| | | string unSelectPic = string.Empty; |
| | | string selectPic = string.Empty; |
| | | Shared.Common.LocalDevice.Current.GetDeviceObjectIcon(new List<CommonDevice> { this }, ref unSelectPic, ref selectPic); |
| | | IconPath = unSelectPic; |
| | | } |
| | | Shared.Common.Global.WriteFileByBytesByHomeId(FilePath, System.Text.Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(this))); |
| | | } |
| | | }
|
| | |
|
| | | } |
| | | |
| | | #endregion |
| | | |
| | | #region 输入输出镞定义 |
| | |
| | | /// 驱动代码。为0时,表示zigbee协调器设备。其他值表示为虚拟驱动设备 |
| | | /// </summary> |
| | | public int DriveCode; |
| | | /// <summary>
|
| | | /// 厂商名称
|
| | | /// <summary> |
| | | /// 厂商名称 |
| | | /// </summary> |
| | | public string ManufacturerName = string.Empty; |
| | | /// <summary>
|
| | | /// 模块ID
|
| | | /// <summary> |
| | | /// 模块ID |
| | | /// </summary> |
| | | public string ModelIdentifier = string.Empty; |
| | | /// <summary>
|
| | | /// 好像是序列号
|
| | | /// <summary> |
| | | /// 好像是序列号 |
| | | /// </summary> |
| | | public string ProductCode = string.Empty; |
| | | /// <summary>
|
| | | /// 设备功能类型(空气开关和继电器专用)
|
| | | /// <summary> |
| | | /// 设备功能类型(空气开关和继电器专用) |
| | | /// </summary> |
| | | public int FunctionType = -1; |
| | | /// <summary> |
| | |
| | | /// 设置可写属性的值 |
| | | /// </summary> |
| | | /// <returns>The writable value async.</returns> |
| | | /// <param name="gateway">Gateway.</param> |
| | | /// <param name="clusterID">要配置的属性所在的cluster.</param> |
| | | /// <param name="setWritableValue">设置可写属性的数据</param> |
| | | public async System.Threading.Tasks.Task<SetWritableValueResponAllData> SetWritableValueAsync(ZigBee.Device.ZbGateway gateway, int clusterID, SetWritableValueData setWritableValue) |
| | | public async System.Threading.Tasks.Task<SetWritableValueResponAllData> SetWritableValueAsync(int clusterID, SetWritableValueData setWritableValue) |
| | | { |
| | | if (gateway == null || setWritableValue == null) |
| | | if (Gateway == null || setWritableValue == null) |
| | | { |
| | | return null; |
| | | } |
| | |
| | | } |
| | | } |
| | | }; |
| | | gateway.Actions += action; |
| | | Gateway.Actions += action; |
| | | System.Console.WriteLine("SetWritableValue_Actions 启动" + "_" + System.DateTime.Now.ToString()); |
| | | |
| | | try |
| | |
| | | var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", DeviceEpoint }, { "Cluster_ID", clusterID }, { "Command", 120 } }; |
| | | var data = new JObject { { "Undivided", setWritableValue.Undivided }, { "AttributeId", setWritableValue.AttributeId }, { "AttributeDataType", setWritableValue.AttributeDataType }, { "AttributeData", setWritableValue.AttributeData } }; |
| | | jObject.Add("Data", data); |
| | | gateway.Send("SetWritableValue", jObject.ToString()); |
| | | Gateway.Send("SetWritableValue", jObject.ToString()); |
| | | } |
| | | catch { } |
| | | |
| | |
| | | { |
| | | d = new SetWritableValueResponAllData { errorMessageBase = " 回复超时,请重新操作" }; |
| | | } |
| | | gateway.Actions -= action; |
| | | Gateway.Actions -= action; |
| | | System.Console.WriteLine("SetWritableValue_Actions 退出" + System.DateTime.Now.ToString()); |
| | | |
| | | return d; |
| | |
| | | public static void DebugPrintLog(string msg, bool flage = true) |
| | | { |
| | | #if DEBUG |
| | | if (flage == true) |
| | | { |
| | | if (msg.Contains("DeviceStatusReport") == false) |
| | | { |
| | | System.Console.WriteLine(msg + " " + System.DateTime.Now.ToLongTimeString() + " " + System.DateTime.Now.Millisecond); |
| | | } |
| | | } |
| | | if (flage == true) |
| | | { |
| | | if (msg.Contains("DeviceStatusReport") == false) |
| | | { |
| | | System.Console.WriteLine(msg + " " + System.DateTime.Now.ToLongTimeString() + " " + System.DateTime.Now.Millisecond); |
| | | } |
| | | } |
| | | #endif |
| | | } |
| | | |