黄学彪
2019-10-18 97e259d966cb5cb5d73c105d5dbaadcc1f920614
ZigbeeApp/Shared/Phone/ZigBee/Device/DoorLock.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@@ -27,8 +28,32 @@
        public List<Shared.Phone.UserCenter.MemberInfoRes> localAllAccountList = new List<Shared.Phone.UserCenter.MemberInfoRes> { };
        public static int RemoteUnlockCount = 3;//远程开锁次数限制
        public static string RemoteUnlockPassword = string.Empty;//远程开锁密码
        public static string LocalTempPassword = string.Empty;//本地生成的临时密码
        public static DateTime maxValue = DateTime.MaxValue;
        public static DateTime minValue = DateTime.MinValue;
        #region 临时密码信息
        /// <summary>
        /// 临时密码本地存储对象
        /// </summary>
        public TempPasswordObj tempPasswordObj = new TempPasswordObj();
        /// <summary>
        /// 临时密码本地对象
        /// </summary>
        [System.Serializable]
        public class TempPasswordObj
        {
            /// <summary>
            /// 门锁有效时间
            /// </summary>
            public int validTime;
            /// <summary>
            /// 门锁时间
            /// </summary>
            public int times;
        }
        #endregion
        /// <summary>
        /// 门锁编程事件通知
@@ -370,6 +395,7 @@
        }
        #endregion
        #region  与网关通讯接口
        #region 门锁操作事件通知
        /// <summary>
        /// 门锁操作事件通知
@@ -671,29 +697,137 @@
        }
        #endregion
        #region 临时密码信息
        #region 矫正门锁时间
        /// <summary>
        /// 临时密码本地存储对象
        /// 矫正门锁时间
        /// </summary>
        public TempPasswordObj tempPasswordObj = new TempPasswordObj();
        /// <returns>The writable value async.</returns>
        /// <param name="timestamp">矫正门锁的时间</param>
        public async System.Threading.Tasks.Task<SetWritableValueResponAllData> RectifyDoorLockTimeAsync(int timestamp)
        {
            if (Gateway == null)
            {
                return null;
            }
            return await System.Threading.Tasks.Task.Run(async () =>
            {
                SetWritableValueResponAllData d = null;
                Action<string, string> action = (topic, message) =>
                {
                    var gatewayID = topic.Split('/')[0];
                    var jobject = Newtonsoft.Json.Linq.JObject.Parse(message);
                    if (topic == gatewayID + "/" + "Error_Respon")
                    {
                        var gatewayTemp = new ZbGateway() { Time = jobject.Value<int>("Time"), DataID = jobject.Value<int>("Data_ID"), CurrentGateWayId = Gateway.getGatewayBaseInfo.gwID };
                        var temp = Newtonsoft.Json.JsonConvert.DeserializeObject<ZbGateway.ErrorResponData>(jobject["Data"].ToString());
                        if (temp == null)
                        {
                            d = new SetWritableValueResponAllData { errorMessageBase = "网关错误回复,且数据是空" };
                        }
                        else
                        {
                            d = new SetWritableValueResponAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) };
                        }
                    }
                    if (topic == gatewayID + "/" + "SetWritableValue_Respon")
                    {
                        var gatewayTemp = new ZbGateway() { DeviceID = jobject.Value<int>("Device_ID"), DeviceAddr = jobject.Value<string>("DeviceAddr"), DeviceEpoint = jobject.Value<int>("Epoint"), DataID = jobject.Value<int>("Data_ID"), CurrentGateWayId = Gateway.getGatewayBaseInfo.gwID };
                        var tempData = Newtonsoft.Json.JsonConvert.DeserializeObject<SetWritableValueResponData>(jobject["Data"].ToString());
                        if (tempData == null)
                        {
                            d = new SetWritableValueResponAllData { errorMessageBase = "网关返回的数据为空" };
                        }
                        else
                        {
                            d = new SetWritableValueResponAllData { setWritableValueResponData = tempData };
                            DebugPrintLog($"UI收到通知后的主题_{ topic}");
                        }
                    }
                };
                Gateway.Actions += action;
                DebugPrintLog("SetWritableValue_Actions 启动" + "_" + System.DateTime.Now.ToString());
                try
                {
                    var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", DeviceEpoint }, { "Cluster_ID", 10 }, { "Command", 120 } };
                    var data = new JObject { { "Undivided", 0 }, { "AttributeId", 0 }, { "AttributeDataType", 226 }, { "AttributeData", timestamp } };
                    jObject.Add("Data", data);
                    Gateway.Send("SetWritableValue", jObject.ToString());
                }
                catch { }
                var dateTime = DateTime.Now;
                while ((DateTime.Now - dateTime).TotalMilliseconds < WaitReceiveDataTime)
                {
                    await System.Threading.Tasks.Task.Delay(10);
                    if (d != null)
                    {
                        break;
                    }
                }
                if ((DateTime.Now - dateTime).TotalMilliseconds > WaitReceiveDataTime)
                {
                    d = new SetWritableValueResponAllData { errorMessageBase = " 回复超时,请重新操作" };
                }
                Gateway.Actions -= action;
                DebugPrintLog("SetWritableValue_Actions 退出" + System.DateTime.Now.ToString());
                return d;
            });
        }
        /// <summary>
        /// 临时密码本地对象
        /// 网关版本信息,网关反馈信息
        /// </summary>
        public SetWritableValueResponAllData setWritableValueResponAllData;
        /// <summary>
        /// 网关版本信息,网关反馈信息
        /// </summary>
        [System.Serializable]
        public class TempPasswordObj
        public class SetWritableValueResponAllData
        {
            /// <summary>
            /// 门锁有效时间
            /// 错误信息
            /// </summary>
            public int validTime;
            public string errorMessageBase;
            /// <summary>
            /// 门锁时间
            /// 网关信息错误反馈
            /// <para>当网关接收到客户端信息后,出现以下异常情况将反馈错误。</para>
            /// </summary>
            public int times;
            public ErrorResponData errorResponData;
            /// <summary>
            /// 网关版本信息
            /// </summary>
            public SetWritableValueResponData setWritableValueResponData;
        }
        /// <summary>
        /// 设置可写属性的值的数据
        /// </summary>
        [System.Serializable]
        public class SetWritableValueResponData
        {
            /// <summary>
            /// 配置属性所在的cluster
            /// </summary>
            public int Cluster;
            /// <summary>
            /// 0:配置成功(若配置成功,下面的AttributeId字段不存在)
            ///<para>134:不支持该属性</para>
            ///<para>135:无效的属性值</para>
            ///<para>141:无效的数据类型</para>
            /// </summary>
            public int Status;
        }
        #endregion
        #endregion
        #region 私有命令
        #region 与设备通讯接口(私有命令)
        #region 用户管理控制
        ///<summary >
@@ -1126,7 +1260,7 @@
                                        tempD.command = Convert.ToInt32(data[10].ToString() + data[11].ToString() + data[12].ToString() + data[13].ToString(), 16);
                                        tempD.status = Convert.ToInt32(data[14].ToString() + data[15].ToString(), 16);
                                        result = new ResponseAllData { responseData = tempD };
                                        System.Console.WriteLine($"UI收到通知后的主题_command:0400_{ topic}");
                                        DebugPrintLog($"UI收到通知后的主题_command:0400_{ topic}");
                                    }
                                }
                            }
@@ -1255,7 +1389,7 @@
                                        tempD.command = Convert.ToInt32(data[10].ToString() + data[11].ToString() + data[12].ToString() + data[13].ToString(), 16);
                                        tempD.status = Convert.ToInt32(data[14].ToString() + data[15].ToString(), 16);
                                        result = new TempPasswordResponseAllData { responseData = tempD };
                                        System.Console.WriteLine($"UI收到通知后的主题_command:0400_{ topic}");
                                        DebugPrintLog($"UI收到通知后的主题_command:0400_{ topic}");
                                    }
                                }
                            }
@@ -1318,20 +1452,35 @@
                pawStr = pawStr.PadLeft(8, '0');
                for (int i = 6; i >= 0; i = i - 2)
                {
                    passwordStr += passwordStr.Substring(i, 2);
                    passwordStr += pawStr.Substring(i, 2);
                }
                var startTimeStr = System.Convert.ToString(GetUnixTimeStamp(startTime, false), 16);
                var endTimeStr = System.Convert.ToString(GetUnixTimeStamp(endTime, false), 16);
                double dStartTimeStr = startTime.ToOADate();
                Byte[] bStartTimeStr = BitConverter.GetBytes(dStartTimeStr);
                StringBuilder sb = new StringBuilder();
                Array.Reverse(bStartTimeStr);
                foreach (byte b in bStartTimeStr)
                    sb.AppendFormat("{0:x2}", b);
                var startTimeStr = sb.ToString();
                for (int i = 6; i >= 0; i = i - 2)
                {
                    vaildTimeStr += startTimeStr.Substring(i, 2);
                    invalidTimeStr += endTimeStr.Substring(i, 2);
                    //invalidTimeStr += endTimeStr.Substring(i, 2);
                }
                //var startTimeStr = Shared.Phone.UserCenter.DoorLock.DoorLockCommonInfo.GetUnixTimeStamp(startTime);
                //var endTimeStr = Shared.Phone.UserCenter.DoorLock.DoorLockCommonInfo.GetUnixTimeStamp(startTime);
                //var startTimeInt = System.Convert.ToInt64(startTimeStr, 16).ToString();
                //var endTimeInt = System.Convert.ToInt64(endTimeStr, 16).ToString();
                data = dataLength + dataComand1 + dataComand2 + dataSerialNum + addDataLength +
                   passwordStr + vaildTimeStr + vaildTimeStr;
            }
            catch { };
            catch (Exception ex)
            {
                var mess = ex.Message;
            };
            return data;
        }
@@ -1734,30 +1883,6 @@
        }
        #endregion
        /// <summary>
        /// 获取从格林威治时间到当前某一时刻的总毫秒数
        /// </summary>
        /// <param name="dateTime">北京时间</param>
        /// <param name="accurateToMilliseconds">精确到毫秒,否到秒</param>
        /// <returns>返回一个长整数时间戳</returns>
        public static long GetUnixTimeStamp(DateTime dateTime, bool accurateToMilliseconds)
        {
            DateTime startTime = TimeZoneInfo.ConvertTimeToUtc(new DateTime(1970, 1, 1, 8, 0, 0));//北京所在东八区
            DateTime endTime = TimeZoneInfo.ConvertTimeToUtc(dateTime);
            return (long)(accurateToMilliseconds ? (endTime - startTime).TotalMilliseconds : (endTime - startTime).TotalSeconds);
        }
        /// <summary>
        /// 将UNIX时间戳转为北京时间
        /// </summary>
        /// <param name="unixTimeStamp">时间戳</param>
        /// <param name="accurateToMilliseconds">精确到毫秒,佛为秒</param>
        /// <returns></returns>
        public static DateTime GetLocalTime(int unixTimeStamp, bool accurateToMilliseconds)
        {
            DateTime startTime = TimeZoneInfo.ConvertTimeToUtc(new DateTime(1970, 1, 1, 8, 0, 0));//北京所在东八区
            return (accurateToMilliseconds ? startTime.AddMilliseconds(unixTimeStamp) : startTime.AddSeconds(unixTimeStamp)).ToLocalTime();
        }
        #endregion
    }
}