using System; using System.Collections.Generic; using System.Text; using Newtonsoft.Json.Linq; namespace ZigBee.Device { [System.Serializable] public class Logic { /// /// 当前主网关ID /// public string GateWayId; /// /// 入网设备信息 /// public int DataID; /// /// 网关反馈的时间戳 /// public int Time; [System.Serializable] public class LogicBase { /// /// 逻辑id,逻辑的唯一标识。如果该逻辑已经存在,则将原来逻辑覆盖。 ///若忽略该字段或该字段为0:网关自动为该逻辑分配一个未被使用的id。 /// public int LogicId; } /// /// 网关信息错误反馈 /// 当网关接收到客户端信息后,出现以下异常情况将反馈错误。 /// ErrorResponData errResponData; /// /// 网关信息错误反馈 /// 当网关接收到客户端信息后,出现以下异常情况将反馈错误。 /// [System.Serializable] public class ErrorResponData { /// /// Error参数含义 ///1:网关无法解析命令数据。 ///2:协调器正在升级或备份/恢复数据 ///3:操作设备/组/场景不存在 ///4:其他错误 ///5:数据传输错误(在某次客户端向网关发送数据的过程中,网关在合理时间范围内接收客户端数据不完整导致该错误发生。如客户端向网关一次发送100个字节的数据,但网关等待接收了一秒只接收了80个字节。发生该错误,网关将主动关闭客户端连接) /// public int Error; } /// /// 网关信息错误反馈的内容 /// static string ErrorMess(int err) { string message = ""; switch (err) { case 1: message = " 网关无法解析命令数据。"; break; case 2: message = " 协调器正在升级或备份 / 恢复数据。"; break; case 3: message = "操作设备 / 组 / 场景不存在"; break; case 4: message = " 其他错误"; break; case 5: message = " 数据传输错误(在某次客户端向网关发送数据的过程中,网关在合理时间范围内接收客户端数据不完整导致该错误发生。如客户端向网关一次发送100个字节的数据,但网关等待接收了一秒只接收了80个字节。发生该错误,网关将主动关闭客户端连接)"; break; default: break; } return message; } #region 当前没有主网关,无法进行逻辑操作 /// ///当前没有主网关,无法进行逻辑操作 /// public GetLogicErrorData getLogicError; /// ///当前没有主网关,无法进行逻辑操作 /// [System.Serializable] public class GetLogicErrorData { /// /// 1:网关不是主网关,无法进行该操作。 /// public int Error; } #endregion #region 在从网关中发场景的命令的反馈 /// ///在从网关中发场景的命令的反馈 /// public SceneErrorRespon sceneErrorRespon; /// ///在从网关中发场景的命令的反馈 /// [System.Serializable] public class SceneErrorRespon { /// /// 非主网关不能使用场景指令。 /// public int Data_ID; } #endregion #region 添加或修改逻辑. /// /// 添加或修改逻辑 /// public static async System.Threading.Tasks.Task AddLogicAsync(AddLogicData addLogicData) { return await System.Threading.Tasks.Task.Run(async () => { AddLogicResponseAllData allData =null; if (ZbGateway.MainGateWay == null) { allData = new AddLogicResponseAllData { errorMessageBase = "当前没有主网关" }; return allData; } Action 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("Time"), DataID = jobject.Value("Data_ID"), CurrentGateWayId = ZbGateway.MainGateWay.getGatewayBaseInfo.gwID }; var temp = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (temp == null) { allData = new AddLogicResponseAllData { errorMessageBase = "网关错误回复,且数据是空" }; } else { allData = new AddLogicResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "Logic/AddLogic_Respon") { try { var logic = new Logic() { DataID = jobject.Value("Data_ID"), GateWayId = ZbGateway.MainGateWay.CurrentGateWayId }; var tempTimeAttribute = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["TimeAttribute"].ToString()); var tempData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (tempData != null) { var conditions = Newtonsoft.Json.Linq.JArray.Parse(jobject["Data"]["Conditions"].ToString()); allData = new AddLogicResponseAllData { }; var tempD = new GetLogicInfoResponseData { }; for (int m = 0; conditions != null && m < conditions.Count; m++) { var condition = conditions[m]; switch (condition["Type"].ToString()) { case "0": tempD.Conditions.Add(Newtonsoft.Json.JsonConvert.DeserializeObject(condition.ToString())); break; case "1": tempD.Conditions.Add(Newtonsoft.Json.JsonConvert.DeserializeObject(condition.ToString())); break; case "2": tempD.Conditions.Add(Newtonsoft.Json.JsonConvert.DeserializeObject(condition.ToString())); break; case "3": tempD.Conditions.Add(Newtonsoft.Json.JsonConvert.DeserializeObject(condition.ToString())); break; case "4": tempD.Conditions.Add(Newtonsoft.Json.JsonConvert.DeserializeObject(condition.ToString())); break; case "5": tempD.Conditions.Add(Newtonsoft.Json.JsonConvert.DeserializeObject(condition.ToString())); break; } } if (tempTimeAttribute != null) { tempD.TimeAttribute = tempTimeAttribute; } if (tempData.LogicName != null) { tempD.LogicName = tempData.LogicName; } if (tempData.Actions != null) { tempD.Actions = tempData.Actions; } tempD.LogicId = tempData.LogicId; tempD.IsEnable = tempData.IsEnable; tempD.Relationship = tempData.Relationship; tempD.Result = tempData.Result; allData.getLogicInfoResponseData = tempD; var info = ZbGateway.LogicList.Find((Logic.GetLogicInfoResponseData obj) => obj.LogicId == tempData.LogicId); if (info == null) { ZbGateway.LogicList.Add(allData.getLogicInfoResponseData); } else { info.LogicName = tempD.LogicName; info.Result = tempD.Result; info.Relationship = tempD.Relationship; info.IsEnable = tempD.IsEnable; info.Conditions = tempD.Conditions; info.Actions = tempD.Actions; info.TimeAttribute = tempD.TimeAttribute; } System.Console.WriteLine($"收到通知后的主题_{ topic}"); } } catch(Exception ex){ var mess = ex.Message; } } }; ZbGateway.MainGateWay.Actions += action; System.Console.WriteLine("Logic/AddLogic_Actions 启动" + System.DateTime.Now.ToString()); try { if (addLogicData != null) { var bytes = new byte[32]; var reamarkGwBytes = System.Text.Encoding.UTF8.GetBytes(addLogicData.LogicName); System.Array.Copy(reamarkGwBytes, 0, bytes, 0, 32 < reamarkGwBytes.Length ? 32 : reamarkGwBytes.Length); addLogicData.LogicName = System.Text.Encoding.UTF8.GetString(bytes); var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 2000 } }; var data = new JObject { }; var conditionsList = new JArray { }; foreach (var conInfo in addLogicData.Conditions) { switch (conInfo.Type) { case 0: var timeConditionsObj = conInfo as TimeConditionsInfo; var tInfo = new JObject { ["Type"] = timeConditionsObj.Type, ["IsValid"] = timeConditionsObj.IsValid, ["DateType"] = timeConditionsObj.DateType, ["StartHour"] = timeConditionsObj.StartHour, ["StartMin"] = timeConditionsObj.StartMin, ["AdjustTime"] = timeConditionsObj.AdjustTime, ["RemindTime"] = timeConditionsObj.RemindTime, ["EnDelay"] = timeConditionsObj.EnDelay, ["DelayTime"] = timeConditionsObj.DelayTime }; conditionsList.Add(tInfo); break; case 1: var deviceConditionsObj = conInfo as DeviceConditionsInfo; var dInfo = new JObject { ["Type"] = deviceConditionsObj.Type, ["IsValid"] = deviceConditionsObj.IsValid, ["MacAddr"] = deviceConditionsObj.MacAddr, ["Epoint"] = deviceConditionsObj.Epoint, ["Cluster_ID"] = deviceConditionsObj.Cluster_ID, ["AttriButeId"] = deviceConditionsObj.AttriButeId, ["AttriButeData1"] = deviceConditionsObj.AttriButeData1, ["AttriButeData2"] = deviceConditionsObj.AttriButeData2, ["Range"] = deviceConditionsObj.Range, }; conditionsList.Add(dInfo); break; case 2: var logicConditionsObj = conInfo as LogicConditionsInfo; var lInfo = new JObject { ["Type"] = logicConditionsObj.Type, ["IsValid"] = logicConditionsObj.IsValid, ["Condition_LogicId"] = logicConditionsObj.Condition_LogicId, }; conditionsList.Add(lInfo); break; case 3: var cConditionsObj = conInfo as CounterConditionsInfo; var cInfo = new JObject { ["Type"] = cConditionsObj.Type, ["IsValid"] = cConditionsObj.IsValid, ["MacAddr"] = cConditionsObj.MacAddr, ["Epoint"] = cConditionsObj.Epoint, ["Cluster_ID"] = cConditionsObj.Cluster_ID, ["AttriButeId"] = cConditionsObj.AttriButeId, ["AttriButeData1"] = cConditionsObj.AttriButeData1, ["AttriButeData2"] = cConditionsObj.AttriButeData2, ["Range"] = cConditionsObj.Range, ["Number"] = cConditionsObj.Number, ["Time"] = cConditionsObj.Time, ["Cycle"] = cConditionsObj.Cycle, }; conditionsList.Add(cInfo); break; case 4: var cdConditionsObj = conInfo as CountdownConditionsInfo; var cdInfo = new JObject { ["Type"] = cdConditionsObj.Type, ["IsValid"] = cdConditionsObj.IsValid, ["Time"] = cdConditionsObj.Time, }; conditionsList.Add(cdInfo); break; case 5: var tbConditionsObj = conInfo as TimeBucketConditionsInfo; var tbInfo = new JObject { ["Type"] = tbConditionsObj.Type, ["IsValid"] = tbConditionsObj.IsValid, ["StartHour"] = tbConditionsObj.StartHour, ["StartMin"] = tbConditionsObj.StartMin, ["StopHour"] = tbConditionsObj.StopHour, ["StopMin"] = tbConditionsObj.StopMin, }; conditionsList.Add(tbInfo); break; case 6: var sConditionsObj = conInfo as SecurityConditionsInfo; var sInfo = new JObject { ["Type"] = sConditionsObj.Type, ["IsValid"] = sConditionsObj.IsValid, ["EnOrWithdrawMode"] = sConditionsObj.EnOrWithdrawMode, ["ModeId"] = sConditionsObj.ModeId, }; conditionsList.Add(sInfo); break; } } var actionsList = new JArray { }; foreach (var actInfo in addLogicData.Actions) { switch (actInfo.LinkType) { case 0: var taskList = new JArray { }; foreach (var taskInfo in actInfo.TaskList) { var info = new JObject{ { "TaskType", taskInfo.TaskType}, { "Data1", taskInfo.Data1}, { "Data2",taskInfo.Data2} }; taskList.Add(info); } var tInfo = new JObject { ["LinkType"] = actInfo.LinkType, ["DeviceAddr"] = actInfo.DeviceAddr, ["Epoint"] = actInfo.Epoint, ["Time"] = actInfo.Time, ["taskList"] = taskList, }; actionsList.Add(tInfo); break; case 2: var dInfo = new JObject { ["LinkType"] = actInfo.LinkType, ["DeviceAddr"] = int.Parse(actInfo.DeviceAddr), ["ConditionId"] = actInfo.ConditionId, ["EnableCondition"] = actInfo.EnableCondition, }; actionsList.Add(dInfo); break; case 4: var lInfo = new JObject { ["LinkType"] = actInfo.LinkType, ["EnableLogic"] = actInfo.EnableLogic, }; actionsList.Add(lInfo); break; case 5: var cInfo = new JObject { ["LinkType"] = actInfo.LinkType, ["DeviceAddr"] = int.Parse(actInfo.DeviceAddr), ["ConditionId"] = actInfo.ConditionId, ["EnableCondition"] = actInfo.EnableCondition, }; actionsList.Add(cInfo); break; case 6: var cdInfo = new JObject { ["LinkType"] = actInfo.LinkType, ["SecuritySetting"] = actInfo.SecuritySetting, ["SecurityModeId"] = actInfo.SecurityModeId, ["CheckIASStatus"] = actInfo.CheckIASStatus, ["IsDelayStart"] = actInfo.IsDelayStart, ["Password"] = actInfo.Password, }; actionsList.Add(cdInfo); break; } } var selectMonthList = new JArray { }; foreach (var sm in addLogicData.TimeAttribute.SelectMonDate) { var aad = sm; selectMonthList.Add(sm); } var dataAttribute = new JObject { { "Calendar",addLogicData.TimeAttribute.Calendar}, { "Repeat", addLogicData.TimeAttribute.Repeat} , { "WeekDay", addLogicData.TimeAttribute.WeekDay} , { "SetYear",addLogicData.TimeAttribute.SetYear} , { "MonthDate", addLogicData.TimeAttribute.MonthDate} , { "SelectMonDate", selectMonthList } }; data = new JObject { { "LogicId",addLogicData.LogicId}, { "IsEnable", addLogicData.IsEnable} , { "LogicName", addLogicData.LogicName} , { "Relationship",addLogicData.Relationship} , { "TimeAttribute", dataAttribute} , { "Conditions", conditionsList }, { "Actions", actionsList } }; jObject.Add("Data", data); ZbGateway.MainGateWay?.Send("Logic/AddLogic", jObject.ToString()); } } catch { } var dateTime = DateTime.Now; while ((DateTime.Now - dateTime).TotalMilliseconds < 2000) { await System.Threading.Tasks.Task.Delay(10); if (allData != null) { break; } } if ((DateTime.Now - dateTime).TotalMilliseconds > 2000) { allData = new AddLogicResponseAllData { errorMessageBase = " 回复超时,请重新操作" }; } ZbGateway.MainGateWay.Actions -= action; System.Console.WriteLine("Logic/AddLogic_Actions 退出" + System.DateTime.Now.ToString()); return allData; }); } /// /// 添加或修改逻辑的数据,网关反馈信息 /// public AddLogicResponseAllData addLogicResponseAllData; /// /// 添加或修改逻辑的数据,网关反馈信息 /// [System.Serializable] public class AddLogicResponseAllData { /// /// 错误信息 /// public string errorMessageBase; /// /// 网关信息错误反馈 /// 当网关接收到客户端信息后,出现以下异常情况将反馈错误。 /// public ErrorResponData errorResponData; /// /// 添加或修改逻辑的数据 /// public GetLogicInfoResponseData getLogicInfoResponseData; } /// /// 添加或修改逻辑返回的数据 /// //public AddLogicResposeData addLogicResposeData; ///// ///// 添加或修改逻辑返回的数据 ///// //[System.Serializable] //public class AddLogicResposeData : LogicBase //{ // /// // /// 该逻辑是否被使能。 // ///0:禁用该逻辑 // ///1:使能该逻辑 // ///2: 只触发一次。触发后该字段将自动置为0,即禁用状态 // ///3:只失能一次。触发后,不执行逻辑动作,该字段自动置为1,等待下次触发。 // /// // public int IsEnable; // /// // /// 逻辑名称 // /// // public string LogicName; // /// // ///逻辑关系。 // ///0:满足所有条件触发动作 // ///1:满足其中一个条件触发动作 // /// // public int Relationship; // /// // /// 逻辑条件列表 // /// // public List Conditions = new List(); // /// // /// 条件满足后执行的动作列表 // /// // public List Actions = new List(); //} /// /// 添加或修改逻辑的数据 /// public AddLogicData addLogicData; /// /// 添加或修改逻辑的数据 /// [System.Serializable] public class AddLogicData : LogicBase { /// /// 逻辑名称 /// public string LogicName = ""; /// /// 该逻辑是否被使能。 ///0:禁用该逻辑 ///1:使能该逻辑 ///2: 只触发一次。触发后该字段将自动置为0,即禁用状态 ///3:只失能一次。触发后,不执行逻辑动作,该字段自动置为1,等待下次触发。 /// public int IsEnable = 1; /// ///逻辑关系。 ///0:满足所有条件触发动作 ///1:满足其中一个条件触发动作 /// public int Relationship; /// ///逻辑关系。 ///0:满足所有条件触发动作 ///1:满足其中一个条件触发动作 /// public TimeAttributeObj TimeAttribute=new TimeAttributeObj(); /// /// 逻辑条件列表 /// public List Conditions = new List(); /// /// 条件满足后执行的动作列表 /// public List Actions = new List(); } /// /// 描述逻辑时间属性 /// [System.Serializable] public class TimeAttributeObj { /// ///条件类型 ///0:阳历 1:农历 /// public int Calendar; /// /// 时间重复性:用于限制逻辑的执行时间 ///0:一次性,只执行一次,执行后IsEnable值置0 ///1:今年内执行 ///2:每天执行 ///3:每月执行 ///4:每年执行 ///5:周重复。 /// public int Repeat; /// /// 周工作模式(可或运算),当Repeat=5时有效,Repeat为其他值时可忽略该字段。 ///0x01 周一执行 ///0x02 周二执行 ///0x04 周三执行 ///0x08 周四执行 ///0x10 周五执行 ///0x20 周六执行 ///0x40 周日执行 ///0x7F 每天执行 ///数值可进行或运算,如周一、周三、周五执行,则为WeekDay=(0x01 || 0x04 || 0x10)= 0x15 即十进制 21。 /// /// The week day. public int WeekDay; /// ///当Repeat = 1时,该参数才有效。表示某个年份内才执行。如SetYear = 2020,则表示该条件2020内才会被执行。如果该字段被忽略或设定为 0 ,网关将自动填入今年的年份作为执行年份。 ///可忽略,默认为设定条件时的年份。 /// public int SetYear; /// ///条件类型 ///重复类型为每月执行时选择的日期。32位整型,bit值第0位到第30位分别代表每月的1号到31号,位值为1则表示该日期可执行逻辑,位值为0则该日期不可执行逻辑。如,MonthDate=91,则二进制值为:1011011 ,可知bit0=1,所以1号可执行。Bit1=1,所以2号可执行。Bit2=0,3号不可执行。Bit3和bit4为1所以4、5号可执行。Bit5为0,6号不可执行。Bit6为1,7号可执行。如果选择某段日期执行,可将这段日期号数对应的bit值全置1。如果3号到7号执行,则为二进制1111100,即MonthDate = 124。当Repeat =3时有效。Repeat不为3时,可忽略该参数。 /// public int MonthDate; /// ///重复类型为今年内执行或每年执行时选择执行的月份。 /// 选择执行的月份 ///0x01:1月执行;0x02:2月执行; ///0x04:3月执行;0x08:4月执行 ///0x10:5月执行;0x20:6月执行 ///0x40:7月执行;0x80:9月执行 ///0x100: 10月执行;0x200: 11月执行 ///0x400: 12月执行; ///数值可进行或运算,如一月、三月、五月执行,则为SelectMonth =(0x01 | 0x04 | 0x10)= 0x15 即十进制 21。 ///当Repeat = 1或4时有效。Repeat为其他值时可忽略该字段。 /// public int SelectMonth; /// ///重复类型为今年内执行或每年执行时选择执行的日期。 ///SelectMonDate[0] 到SelectMonDate[11]分别表示1月份到12月份选择的号数,类型为32位整数,数值的含义和MonthDate相同。 ///当Repeat = 1或4时有效。Repeat为其他值时可忽略该字段。 /// /// /// 逻辑条件列表 /// public List SelectMonDate = new List(); } [System.Serializable] public class ConditionBase { /// ///条件类型 ///0:时间点条件,在某个时间发生 ///1:设备状态变化条件 ///2:其他逻辑条件 ///3:计数器条件 ///4:倒计时 ///5:时间段条件 ///6:安防条件 /// public int Type; /// /// 该条件是否作为判断逻辑依据。当条件无效时,则忽略该条件。一个逻辑应该至少有一个有效条件用于判断逻辑是否成立,当一个逻辑所有条件无效时,该逻辑将永远不会生效。 ///0:无效(忽略条件)。 ///1:有效(启用条件)。 ///2:使能一次(条件成立一次后将被禁用,IsValid自动置为0)。 ///3:失能一次(条件第一次成立会被忽略,触发不了逻辑,然后IsValid自动置1。以后条件再成立将不会被忽略) /// public int IsValid = 1; /// /// 条件ID((当新增或修改逻辑条件时,该字段无效)) /// public int ConditionId ; } #endregion #region 修改逻辑信息. /// /// 修改逻辑信息 /// public static async System.Threading.Tasks.Task ReviseAttributeAsync(ReviseAttributeData reviseAttributeData) { return await System.Threading.Tasks.Task.Run(async () => { ReviseAttributeResponseAllData allData =null; if (ZbGateway.MainGateWay == null) { allData = new ReviseAttributeResponseAllData{ errorMessageBase = "当前没有主网关" }; return allData; } Action 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("Time"), DataID = jobject.Value("Data_ID"), CurrentGateWayId = ZbGateway.MainGateWay.getGatewayBaseInfo.gwID }; var temp = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (temp == null) { allData = new ReviseAttributeResponseAllData { errorMessageBase = "网关错误回复,且数据是空" }; } else { allData = new ReviseAttributeResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "Logic/ReviseAttribute_Respon") { try { var logic = new Logic() { DataID = jobject.Value("Data_ID"), GateWayId = ZbGateway.MainGateWay.CurrentGateWayId }; var tempTimeAttribute = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["TimeAttribute"].ToString()); var tempData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (tempData != null) { allData = new ReviseAttributeResponseAllData { }; var tempD = new ReviseAttributeResponseData { }; if (tempTimeAttribute != null) { tempD.TimeAttribute = tempTimeAttribute; } if (tempData.LogicName != null) { tempD.LogicName = tempData.LogicName; } tempD.LogicId = tempData.LogicId; tempD.IsEnable = tempData.IsEnable; tempD.Relationship = tempData.Relationship; tempD.Result = tempData.Result; allData.reviseAttributeResponseData = tempD; var info = ZbGateway.LogicList.Find((Logic.GetLogicInfoResponseData obj) => obj.LogicId == tempData.LogicId); if (info != null) { info.LogicName = tempD.LogicName; info.Result = tempD.Result; info.Relationship = tempD.Relationship; info.IsEnable = tempD.IsEnable; info.TimeAttribute = tempD.TimeAttribute; } System.Console.WriteLine($"收到通知后的主题_{ topic}"); }else{ allData = new ReviseAttributeResponseAllData { errorMessageBase = "网关返回的数据为空" }; } } catch (Exception ex) { var mess = ex.Message; } } }; ZbGateway.MainGateWay.Actions += action; System.Console.WriteLine("Logic/ReviseAttribute_Actions 启动" + "_" + ZbGateway.MainGateWay.getGatewayBaseInfo.gwID + System.DateTime.Now.ToString()); try { if (reviseAttributeData != null) { if(reviseAttributeData.LogicName!=null){ var bytes = new byte[32]; var reamarkGwBytes = System.Text.Encoding.UTF8.GetBytes(reviseAttributeData.LogicName); System.Array.Copy(reamarkGwBytes, 0, bytes, 0, 32 < reamarkGwBytes.Length ? 32 : reamarkGwBytes.Length); reviseAttributeData.LogicName = System.Text.Encoding.UTF8.GetString(bytes); } var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 2001 } }; var data = new JObject { }; var selectMonthList = new JArray { }; if(reviseAttributeData.TimeAttribute!=null&& reviseAttributeData.TimeAttribute.SelectMonDate != null) { foreach (var sm in reviseAttributeData.TimeAttribute.SelectMonDate) { var aad = sm; selectMonthList.Add(sm); } } var dataAttribute = new JObject { { "Calendar",reviseAttributeData.TimeAttribute.Calendar}, { "Repeat", reviseAttributeData.TimeAttribute.Repeat} , { "WeekDay", reviseAttributeData.TimeAttribute.WeekDay} , { "SetYear",reviseAttributeData.TimeAttribute.SetYear} , { "MonthDate", reviseAttributeData.TimeAttribute.MonthDate} , { "SelectMonDate", selectMonthList } }; data = new JObject { { "LogicId",reviseAttributeData.LogicId}, { "IsEnable", reviseAttributeData.IsEnable} , { "LogicName", reviseAttributeData.LogicName} , { "Relationship",reviseAttributeData.Relationship}, { "TimeAttribute", dataAttribute} }; jObject.Add("Data", data); ZbGateway.MainGateWay?.Send(("Logic/ReviseAttribute"), jObject.ToString()); } } catch { } var dateTime = DateTime.Now; while ((DateTime.Now - dateTime).TotalMilliseconds < 2000) { await System.Threading.Tasks.Task.Delay(10); if (allData != null) { break; } } if ((DateTime.Now - dateTime).TotalMilliseconds > 2000) { allData = new ReviseAttributeResponseAllData { errorMessageBase = " 回复超时,请重新操作" }; } ZbGateway.MainGateWay.Actions -= action; System.Console.WriteLine("Logic/ReviseAttribute_Actions 退出" + "_" + ZbGateway.MainGateWay.getGatewayBaseInfo.gwID + System.DateTime.Now.ToString()); return allData; }); } /// ///修改逻辑属性回复的所有数据,网关反馈信息 /// public ReviseAttributeResponseAllData reviseAttributeResponseAllData; /// /// 修改逻辑属性回复的所有数据 /// [System.Serializable] public class ReviseAttributeResponseAllData { /// /// 错误信息 /// public string errorMessageBase; /// /// 网关信息错误反馈 /// 当网关接收到客户端信息后,出现以下异常情况将反馈错误。 /// public ErrorResponData errorResponData; /// /// 修改逻辑属性 /// public ReviseAttributeResponseData reviseAttributeResponseData; } /// /// 修改逻辑属性回复的数据 /// public ReviseAttributeResponseData reviseAttributeResponseData; /// /// 修改逻辑属性回复的数据 /// [System.Serializable] public class ReviseAttributeResponseData : LogicBase { /// /// 修改结果: ///0:成功 ///1:失败,逻辑不存在 /// public int Result; /// /// 该逻辑是否被使能。 ///0:禁用该逻辑 ///1:使能该逻辑 ///2: 只触发一次。触发后该字段将自动置为0,即禁用状态 /// public int IsEnable; /// /// 逻辑名称 /// public string LogicName; /// /// 逻辑关系。 ///0:满足所有条件触发动作 ///1:满足其中一个条件触发动作 /// public int Relationship; /// /// 逻辑名称 /// public TimeAttributeObj TimeAttribute=new TimeAttributeObj(); } [System.Serializable] public class ReviseAttributeResponseBaseData : LogicBase { /// /// 修改结果: ///0:成功 ///1:失败,逻辑不存在 /// public int Result; /// /// 该逻辑是否被使能。 ///0:禁用该逻辑 ///1:使能该逻辑 ///2: 只触发一次。触发后该字段将自动置为0,即禁用状态 /// public int IsEnable; /// /// 逻辑名称 /// public string LogicName; /// /// 逻辑关系。 ///0:满足所有条件触发动作 ///1:满足其中一个条件触发动作 /// public int Relationship; } /// /// 修改逻辑属性的数据 /// public ReviseAttributeData reviseAttributeData; /// /// 修改逻辑属性回复的数据 /// [System.Serializable] public class ReviseAttributeData : LogicBase { /// /// 该逻辑是否被使能。 ///0:禁用该逻辑 ///1:使能该逻辑 ///2: 只触发一次。触发后该字段将自动置为0,即禁用状态 ///3:只失能一次。触发后,不执行逻辑动作,该字段自动置为1,等待下次触发。 ///不修改该属性时, 可忽略该字段 /// public int IsEnable; /// /// 逻辑名称 /// public string LogicName; /// /// 逻辑关系。 ///0:满足所有条件触发动作 ///1:满足其中一个条件触发动作 ///不修改该属性时,可忽略该字段 /// public int Relationship; /// /// 描述逻辑时间属性 ///和“1、添加或修改逻辑”的TimeAttribute字段格式相同。 ///不修改该属性时,可忽略该字段 /// public TimeAttributeObj TimeAttribute=new TimeAttributeObj(); } #endregion #region 通过逻辑id获取逻辑信息. /// /// 通过逻辑id获取逻辑信息 /// public static async System.Threading.Tasks.Task GetLogicInfoAsync(int logicId) { return await System.Threading.Tasks.Task.Run(async () => { GetLogicInfoResponseAllData allData = null; if (ZbGateway.MainGateWay == null) { allData = new GetLogicInfoResponseAllData { errorMessageBase = "当前没有主网关" }; return allData; } Action 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("Time"), DataID = jobject.Value("Data_ID"), CurrentGateWayId = ZbGateway.MainGateWay.getGatewayBaseInfo.gwID }; var temp = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (temp == null) { allData = new GetLogicInfoResponseAllData { errorMessageBase = "网关错误回复,且数据是空" }; } else { allData = new GetLogicInfoResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "Logic/GetLogicInfo_Respon") { try { var logic = new Logic() { DataID = jobject.Value("Data_ID"), GateWayId = ZbGateway.MainGateWay.CurrentGateWayId }; var tempTimeAttribute = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["TimeAttribute"].ToString()); var tempData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (tempData != null) { var conditions = Newtonsoft.Json.Linq.JArray.Parse(jobject["Data"]["Conditions"].ToString()); allData = new GetLogicInfoResponseAllData { }; var tempD = new GetLogicInfoResponseData { }; for (int m = 0; conditions != null && m < conditions.Count; m++) { var condition = conditions[m]; var ads = condition["Type"].ToString(); switch (condition["Type"].ToString()) { case "0": tempD.Conditions.Add(Newtonsoft.Json.JsonConvert.DeserializeObject(condition.ToString())); break; case "1": tempD.Conditions.Add(Newtonsoft.Json.JsonConvert.DeserializeObject(condition.ToString())); break; case "2": tempD.Conditions.Add(Newtonsoft.Json.JsonConvert.DeserializeObject(condition.ToString())); break; case "3": tempD.Conditions.Add(Newtonsoft.Json.JsonConvert.DeserializeObject(condition.ToString())); break; case "4": tempD.Conditions.Add(Newtonsoft.Json.JsonConvert.DeserializeObject(condition.ToString())); break; case "5": tempD.Conditions.Add(Newtonsoft.Json.JsonConvert.DeserializeObject(condition.ToString())); break; } } if (tempTimeAttribute != null) { tempD.TimeAttribute = tempTimeAttribute; } if (tempData.LogicName != null) { tempD.LogicName = tempData.LogicName; } if (tempData.Actions != null) { tempD.Actions = tempData.Actions; } tempD.LogicId = tempData.LogicId; tempD.IsEnable = tempData.IsEnable; tempD.Relationship = tempData.Relationship; tempD.Result = tempData.Result; allData.getLogicInfoResponseData = tempD; var info = ZbGateway.LogicList.Find((Logic.GetLogicInfoResponseData obj) => obj.LogicId == tempData.LogicId); if (info == null) { ZbGateway.LogicList.Add(allData.getLogicInfoResponseData); } else { info.LogicName = tempD.LogicName; info.Result = tempD.Result; info.Relationship = tempD.Relationship; info.IsEnable = tempD.IsEnable; info.Conditions = tempD.Conditions; info.Actions = tempD.Actions; info.TimeAttribute = tempD.TimeAttribute; } System.Console.WriteLine($"收到通知后的主题_{ topic}"); } } catch (Exception ex) { var mess = ex.Message; } } }; ZbGateway.MainGateWay.Actions += action; System.Console.WriteLine("Logic/GetLogicInfo_Actions 启动" + "_" + ZbGateway.MainGateWay.getGatewayBaseInfo.gwID + System.DateTime.Now.ToString()); try { var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 2002 } }; var data = new JObject { { "LogicId",logicId} }; jObject.Add("Data", data); ZbGateway.MainGateWay?.Send(("Logic/GetLogicInfo"), jObject.ToString()); } catch { } var dateTime = DateTime.Now; while ((DateTime.Now - dateTime).TotalMilliseconds < 4000) { await System.Threading.Tasks.Task.Delay(10); if (allData != null&& allData?.getLogicInfoResponseData!=null) { break; } } if ((DateTime.Now - dateTime).TotalMilliseconds > 4000) { allData = new GetLogicInfoResponseAllData { errorMessageBase = " 回复超时,请重新操作" }; } ZbGateway.MainGateWay.Actions -= action; System.Console.WriteLine("Logic/GetLogicInfo_Actions 退出" + "_" + ZbGateway.MainGateWay.getGatewayBaseInfo.gwID + System.DateTime.Now.ToString()); return allData; }); } /// ///通过逻辑id获取逻辑信息的所有数据,网关反馈信息 /// public GetLogicInfoResponseAllData getLogicInfoResponseAllData; /// /// 通过逻辑id获取逻辑信息回复的所有数据 /// [System.Serializable] public class GetLogicInfoResponseAllData { /// /// 错误信息 /// public string errorMessageBase; /// /// 网关信息错误反馈 /// 当网关接收到客户端信息后,出现以下异常情况将反馈错误。 /// public ErrorResponData errorResponData; /// /// 通过逻辑id获取逻辑信息回复的数据 /// public GetLogicInfoResponseData getLogicInfoResponseData; } /// ///通过逻辑id获取逻辑信息回复的数据 /// public GetLogicInfoResponseData getLogicInfoResponseData; /// /// 通过逻辑id获取逻辑信息回复的数据 /// [System.Serializable] public class GetLogicInfoResponseData : LogicBase { /// ///0:获取成功 ///1:该逻辑不存在。 ///以下所有字段只有在Result 为1时存在 /// public int Result; /// ///该逻辑是否被使能。 ///0:禁用该逻辑 ///1:使能该逻辑 ///2: 只触发一次。触发后该字段将自动置为0,即禁用状态。 /// public int IsEnable; /// ///逻辑名称 /// public string LogicName; /// ///逻辑关系。 ///0:满足所有条件触发动作 ///1:满足其中一个条件触发动作 /// public int Relationship; /// ///逻辑关系。 ///0:满足所有条件触发动作 ///1:满足其中一个条件触发动作 /// public TimeAttributeObj TimeAttribute = new TimeAttributeObj(); /// /// 逻辑条件列表 /// public List Conditions = new List(); /// /// 条件满足后执行的动作列表 /// public List Actions = new List(); } [System.Serializable] public class GetLogicInfoResponseBaseData : LogicBase { /// ///0:获取成功 ///1:该逻辑不存在。 ///以下所有字段只有在Result 为1时存在 /// public int Result; /// ///该逻辑是否被使能。 ///0:禁用该逻辑 ///1:使能该逻辑 ///2: 只触发一次。触发后该字段将自动置为0,即禁用状态。 /// public int IsEnable; /// ///逻辑名称 /// public string LogicName; /// ///逻辑关系。 ///0:满足所有条件触发动作 ///1:满足其中一个条件触发动作 /// public int Relationship; /// /// 逻辑条件列表 /// public List Conditions = new List(); /// /// 条件满足后执行的动作列表 /// public List Actions = new List(); } #endregion #region 获取逻辑列表. /// /// 获取逻辑列表 /// (当数量很多时,可能第一次获取失败,要到重新获取) /// public static async System.Threading.Tasks.Task GetLogicListAsync() { return await System.Threading.Tasks.Task.Run(async () => { GetLogicListResponseAllData allData = null; if (ZbGateway.MainGateWay == null) { allData = new GetLogicListResponseAllData { errorMessageBase = "当前没有主网关" }; return allData; } Action 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("Time"), DataID = jobject.Value("Data_ID"), CurrentGateWayId = ZbGateway.MainGateWay.getGatewayBaseInfo.gwID }; var temp = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (temp == null) { allData = new GetLogicListResponseAllData { errorMessageBase = "网关错误回复,且数据是空" }; } else { allData = new GetLogicListResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "Logic/GetLogicList_Respon") { var logic = new Logic() { DataID = jobject.Value("DataID"), GateWayId = ZbGateway.MainGateWay.CurrentGateWayId }; var tempBindList = Newtonsoft.Json.Linq.JArray.Parse(jobject["Data"]["LogicList"].ToString()); var tempData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (tempData == null) { allData = new GetLogicListResponseAllData { errorMessageBase = "网关返回的数据为空" }; } else { allData = new GetLogicListResponseAllData { getLogicListResponseData = tempData }; System.Console.WriteLine($"收到通知后的主题_{ topic}"); } } }; ZbGateway.MainGateWay.Actions += action; System.Console.WriteLine("Logic/GetLogicList_Actions 启动" + "_" + ZbGateway.MainGateWay.getGatewayBaseInfo.gwID + System.DateTime.Now.ToString()); try { var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 2004 } }; ZbGateway.MainGateWay?.Send(("Logic/GetLogicList"), jObject.ToString()); } catch { } var dateTime = DateTime.Now; while ((DateTime.Now - dateTime).TotalMilliseconds < 4000) { await System.Threading.Tasks.Task.Delay(10); if (allData != null) { break; } } if ((DateTime.Now - dateTime).TotalMilliseconds > 4000) { allData = new GetLogicListResponseAllData { errorMessageBase = " 回复超时,请重新操作" }; } ZbGateway.MainGateWay.Actions -= action; System.Console.WriteLine("Logic/GetLogicList_Actions 退出" + "_" + ZbGateway.MainGateWay.getGatewayBaseInfo.gwID + System.DateTime.Now.ToString()); return allData; }); } /// ///通过逻辑id获取逻辑信息的所有数据,网关反馈信息 /// public GetLogicListResponseAllData getLogicListResponseAllData; /// /// 通过逻辑id获取逻辑信息回复的所有数据 /// [System.Serializable] public class GetLogicListResponseAllData { /// /// 错误信息 /// public string errorMessageBase; /// /// 网关信息错误反馈 /// 当网关接收到客户端信息后,出现以下异常情况将反馈错误。 /// public ErrorResponData errorResponData; /// /// 通过逻辑id获取逻辑信息回复的数据 /// public GetLogicListResponseData getLogicListResponseData; } /// ///通过逻辑id获取逻辑信息回复的数据 /// public GetLogicListResponseData getLogicListResponseData; /// /// 通过逻辑id获取逻辑信息回复的数据 /// [System.Serializable] public class GetLogicListResponseData : LogicBase { /// /// 逻辑条件列表 /// public List LogicList = new List(); } /// /// 逻辑列表具体数据 /// [System.Serializable] public class LogicListData : LogicBase { /// /// 逻辑名称 /// public string LogicName; /// /// 该逻辑是否被使能。 ///0:禁用该逻辑 ///1:使能该逻辑 ///2: 只触发一次。触发后该字段将自动置为0,即禁用状态 /// public int IsEnable; /// ///逻辑关系。 ///0:满足所有条件触发动作 ///1:满足其中一个条件触发动作 /// public int Relationship; } #endregion #region 新增或修改逻辑条件. /// /// 新增或修改逻辑条件 /// ChangeConditionData中type有效,此时ConditionObj中的type无效 /// public static async System.Threading.Tasks.Task ChangeConditionAsync(ChangeConditionData changeConditionData) { return await System.Threading.Tasks.Task.Run(async () => { ChangeConditionResponseAllData allData = null; if (ZbGateway.MainGateWay == null) { allData = new ChangeConditionResponseAllData { errorMessageBase = "当前没有主网关" }; return allData; } Action 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("Time"), DataID = jobject.Value("Data_ID"), CurrentGateWayId = ZbGateway.MainGateWay.getGatewayBaseInfo.gwID }; var temp = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (temp == null) { allData = new ChangeConditionResponseAllData { errorMessageBase = "网关错误回复,且数据是空" }; } else { allData = new ChangeConditionResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "Logic/ChangeCondition_Respon") { var logic = new Logic() { DataID = jobject.Value("DataID"), GateWayId = ZbGateway.MainGateWay.CurrentGateWayId }; var tempData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (tempData == null) { allData = new ChangeConditionResponseAllData { errorMessageBase = "网关返回的数据为空" }; } else { switch (tempData.Type) { case 0: var timeObj = new ZigBee.Device.Logic.TimeConditionsInfo(); timeObj.IsValid = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["IsValid"].ToString()); timeObj.DateType = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["DateType"].ToString()); timeObj.StartHour = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["StartHour"].ToString()); timeObj.StartMin = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["StartMin"].ToString()); timeObj.AdjustTime = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["AdjustTime"].ToString()); timeObj.RemindTime = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["RemindTime"].ToString()); timeObj.EnDelay = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["EnDelay"].ToString()); timeObj.DelayTime = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["DelayTime"].ToString()); tempData.conditionObj = timeObj; break; case 1: var devObj = new ZigBee.Device.Logic.DeviceConditionsInfo(); devObj.IsValid = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["IsValid"].ToString()); devObj.Epoint = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["Epoint"].ToString()); devObj.Cluster_ID = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["Cluster_ID"].ToString()); devObj.AttriButeId = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["AttriButeId"].ToString()); devObj.AttriButeData1 = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["AttriButeData1"].ToString()); devObj.AttriButeData2 = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["AttriButeData2"].ToString()); devObj.Range = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["Range"].ToString()); var tempAddrObj =Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if(tempAddrObj.MacAddr != null) { devObj.MacAddr = tempAddrObj.MacAddr; } tempData.conditionObj = devObj; break; case 2: var logicObj = new ZigBee.Device.Logic.LogicConditionsInfo (); logicObj.IsValid = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["IsValid"].ToString()); logicObj.Condition_LogicId = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["Condition_LogicId"].ToString()); tempData.conditionObj = logicObj; break; case 3: var countObj = new ZigBee.Device.Logic.CounterConditionsInfo(); countObj.IsValid = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["IsValid"].ToString()); countObj.Epoint = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["Epoint"].ToString()); countObj.Cluster_ID = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["Cluster_ID"].ToString()); countObj.AttriButeId = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["AttriButeId"].ToString()); countObj.AttriButeData1 = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["AttriButeData1"].ToString()); countObj.AttriButeData2 = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["AttriButeData2"].ToString()); countObj.Range = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["Range"].ToString()); countObj.Number = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["Number"].ToString()); countObj.Time = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["Time"].ToString()); countObj.Cycle = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["Cycle"].ToString()); var tempAddrObj2 = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (tempAddrObj2.MacAddr != null) { countObj.MacAddr = tempAddrObj2.MacAddr; } tempData.conditionObj = countObj; break; case 4: var cdObj = new ZigBee.Device.Logic.CountdownConditionsInfo(); cdObj.IsValid = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["IsValid"].ToString()); cdObj.Time = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["Time"].ToString()); tempData.conditionObj = cdObj; break; case 5: var tbObj = new ZigBee.Device.Logic.TimeBucketConditionsInfo(); tbObj.IsValid = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["IsValid"].ToString()); tbObj.StartHour = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["StartHour"].ToString()); tbObj.StartMin = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["StartMin"].ToString()); tbObj.StopHour = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["StopHour"].ToString()); tbObj.StopMin = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["StopMin"].ToString()); tempData.conditionObj = tbObj; break; case 6: var securitybObj = new ZigBee.Device.Logic.SecurityConditionsInfo(); securitybObj.IsValid = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["IsValid"].ToString()); securitybObj.EnOrWithdrawMode = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["EnOrWithdrawMode"].ToString()); securitybObj.ModeId = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"]["ModeId"].ToString()); tempData.conditionObj = securitybObj; break; } allData = new ChangeConditionResponseAllData { changeConditionResponseData = tempData }; System.Console.WriteLine($"收到通知后的主题_{ topic}"); } } }; ZbGateway.MainGateWay.Actions += action; System.Console.WriteLine("Logic/GetLogicList_Actions 启动" + "_" + ZbGateway.MainGateWay.getGatewayBaseInfo.gwID + System.DateTime.Now.ToString()); try { if(changeConditionData!=null){ var dataPublish = new Dictionary { }; switch (changeConditionData.Type) { case 0: var timeConditionsObj = changeConditionData.conditionObj as TimeConditionsInfo; var dataPublish1 = new Dictionary { ["LogicId"] = changeConditionData.LogicId, ["ConditionId"] = changeConditionData.ConditionId, ["Type"] = changeConditionData.Type, ["IsValid"] = timeConditionsObj.IsValid, ["DateType"] = timeConditionsObj.DateType, ["StartHour"] = timeConditionsObj.StartHour, ["StartMin"] = timeConditionsObj.StartMin, ["AdjustTime"] = timeConditionsObj.AdjustTime, ["RemindTime"] = timeConditionsObj.RemindTime, ["EnDelay"] = timeConditionsObj.EnDelay, ["DelayTime"] = timeConditionsObj.DelayTime }; dataPublish = dataPublish1; break; case 1: var deviceConditionsObj = changeConditionData.conditionObj as DeviceConditionsInfo; var dataPublish2 = new Dictionary { ["LogicId"] = changeConditionData.LogicId, ["ConditionId"] = changeConditionData.ConditionId, ["Type"] = changeConditionData.Type, ["IsValid"] = deviceConditionsObj.IsValid, ["MacAddr"] = deviceConditionsObj.MacAddr, ["Epoint"] = deviceConditionsObj.Epoint, ["Cluster_ID"] = deviceConditionsObj.Cluster_ID, ["AttriButeId"] = deviceConditionsObj.AttriButeId, ["AttriButeData1"] = deviceConditionsObj.AttriButeData1, ["AttriButeData2"] = deviceConditionsObj.AttriButeData2, ["Range"] = deviceConditionsObj.Range, }; dataPublish = dataPublish2; break; case 2: var logicConditionsObj = changeConditionData.conditionObj as LogicConditionsInfo; var dataPublish3 = new Dictionary { ["LogicId"] = changeConditionData.LogicId, ["ConditionId"] = changeConditionData.ConditionId, ["Type"] = changeConditionData.Type, ["IsValid"] = logicConditionsObj.IsValid, ["Condition_LogicId"] = logicConditionsObj.Condition_LogicId, }; dataPublish = dataPublish3; break; case 3: var cConditionsObj = changeConditionData.conditionObj as CounterConditionsInfo; var dataPublish4 = new Dictionary { ["LogicId"] = changeConditionData.LogicId, ["ConditionId"] = changeConditionData.ConditionId, ["Type"] = changeConditionData.Type, ["IsValid"] = cConditionsObj.IsValid, ["MacAddr"] = cConditionsObj.MacAddr, ["Epoint"] = cConditionsObj.Epoint, ["Cluster_ID"] = cConditionsObj.Cluster_ID, ["AttriButeId"] = cConditionsObj.AttriButeId, ["AttriButeData1"] = cConditionsObj.AttriButeData1, ["AttriButeData2"] = cConditionsObj.AttriButeData2, ["Range"] = cConditionsObj.Range, ["Number"] = cConditionsObj.Number, ["Time"] = cConditionsObj.Time, ["Cycle"] = cConditionsObj.Cycle, }; dataPublish = dataPublish4; break; case 4: var cdConditionsObj = changeConditionData.conditionObj as CountdownConditionsInfo; var dataPublish5 = new Dictionary { ["LogicId"] = changeConditionData.LogicId, ["ConditionId"] = changeConditionData.ConditionId, ["Type"] = changeConditionData.Type, ["IsValid"] = cdConditionsObj.IsValid, ["Time"] = cdConditionsObj.Time, }; dataPublish = dataPublish5; break; case 5: var tbConditionsObj = changeConditionData.conditionObj as TimeBucketConditionsInfo; var dataPublish6 = new Dictionary { ["LogicId"] = changeConditionData.LogicId, ["ConditionId"] = changeConditionData.ConditionId, ["Type"] = changeConditionData.Type, ["IsValid"] = tbConditionsObj.IsValid, ["StartHour"] = tbConditionsObj.StartHour, ["StartMin"] = tbConditionsObj.StartMin, ["StopHour"] = tbConditionsObj.StopHour, ["StopMin"] = tbConditionsObj.StopMin, }; dataPublish = dataPublish6; break; case 6: var sConditionsObj = changeConditionData.conditionObj as SecurityConditionsInfo; var dataPublish7 = new Dictionary { ["LogicId"] = changeConditionData.LogicId, ["ConditionId"] = changeConditionData.ConditionId, ["Type"] = changeConditionData.Type, ["IsValid"] = sConditionsObj.IsValid, ["EnOrWithdrawMode"] = sConditionsObj.EnOrWithdrawMode, ["ModeId"] = sConditionsObj.ModeId, }; dataPublish = dataPublish7; break; } ZbGateway.MainGateWay?.Send("Logic/ChangeCondition", Device.Cluster_ID.Gateway, Command.LogicChangeCondition, Newtonsoft.Json.Linq.JObject.Parse(Newtonsoft.Json.JsonConvert.SerializeObject(dataPublish))); } }catch { } var dateTime = DateTime.Now; while ((DateTime.Now - dateTime).TotalMilliseconds < 2000) { await System.Threading.Tasks.Task.Delay(10); if (allData != null) { break; } } if ((DateTime.Now - dateTime).TotalMilliseconds > 2000) { allData = new ChangeConditionResponseAllData { errorMessageBase = " 回复超时,请重新操作" }; } ZbGateway.MainGateWay.Actions -= action; System.Console.WriteLine("Logic/GetLogicList_Actions 退出" + "_" + ZbGateway.MainGateWay.getGatewayBaseInfo.gwID + System.DateTime.Now.ToString()); return allData; }); } /// ///新增或修改逻辑条件所有数据,网关反馈信息 /// public ChangeConditionResponseAllData changeConditionResponseAllData; /// /// 新增或修改逻辑条件回复的所有数据 /// [System.Serializable] public class ChangeConditionResponseAllData { /// /// 错误信息 /// public string errorMessageBase; /// /// 网关信息错误反馈 /// 当网关接收到客户端信息后,出现以下异常情况将反馈错误。 /// public ErrorResponData errorResponData; /// /// 新增或修改逻辑条件回复的数据 /// public ChangeConditionResponseData changeConditionResponseData; } [System.Serializable] public class MacAddrData { /// /// 物理地址 /// public string MacAddr; } /// ///新增或修改逻辑条件回复的数据 /// public ChangeConditionResponseData changeConditionResponseData; /// /// 通新增或修改逻辑条件回复的数据 /// [System.Serializable] public class ChangeConditionResponseData : LogicBase { /// /// 条件id(当新增或修改逻辑条件时,该字段有效) /// public int ConditionId; /// /// 该条件是否作为判断逻辑依据。当条件无效时,则忽略该条件。一个逻辑应该至少有一个有效条件用于判断逻辑是否成立,当一个逻辑所有条件无效时,该逻辑将永远不会生效。 ///0:无效(忽略条件)。 ///1:有效(启用条件)。 ///2:使能一次(条件成立一次后将被禁用,IsValid自动置为0)。 ///3:失能一次(条件第一次成立会被忽略,触发不了逻辑,然后IsValid自动置1。以后条件再成立将不会被忽略) /// public int IsValid; /// ///条件类型 ///0:时间点条件,在某个时间发生 ///1:设备状态变化条件 ///2:其他逻辑条件 ///3:计数器条件 ///4:倒计时 ///5:时间段条件 /// public int Type; /// /// conditionObj:条件对象 /// public ConditionBase conditionObj; } /// /// 新增或修改逻辑条件的数据 /// public ChangeConditionData changeConditionData; /// /// 新增或修改逻辑条件的数据 /// [System.Serializable] public class ChangeConditionData : LogicBase { /// ///(注意必需填写)条件类型;(没填写数据可能不回复) ///0:时间点条件,在某个时间发生 ///1:设备状态变化条件 ///2:其他逻辑条件 ///3:计数器条件 ///4:倒计时 ///5:时间段条件 ///6:安防条件 /// public int Type; /// /// 条件id /// 新增时ConditionId=0,修改时传入对应的ConditionId /// public int ConditionId; /// /// conditionObj:条件对象 /// public ConditionBase conditionObj; } #endregion #region 删除/启用/禁用逻辑条件. /// /// 删除/启用/禁用逻辑条件 /// public static async System.Threading.Tasks.Task SetConditionAsync(SetConditionData setConditionData) { return await System.Threading.Tasks.Task.Run(async () => { SetConditionResponseAllData allData = null; if (ZbGateway.MainGateWay == null) { allData = new SetConditionResponseAllData { errorMessageBase = "当前没有主网关" }; return allData; } Action 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("Time"), DataID = jobject.Value("Data_ID"), CurrentGateWayId = ZbGateway.MainGateWay.getGatewayBaseInfo.gwID }; var temp = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (temp == null) { allData = new SetConditionResponseAllData { errorMessageBase = "网关错误回复,且数据是空" }; } else { allData = new SetConditionResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "Logic/SetCondition_Respon") { var logic = new Logic() { DataID = jobject.Value("DataID"), GateWayId = ZbGateway.MainGateWay.CurrentGateWayId }; var tempData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (tempData == null) { allData = new SetConditionResponseAllData { errorMessageBase = "网关返回的数据为空" }; } else { allData = new SetConditionResponseAllData { setConditionResponseData = tempData }; System.Console.WriteLine($"收到通知后的主题_{ topic}"); } } }; ZbGateway.MainGateWay.Actions += action; System.Console.WriteLine("Logic/SetCondition_Actions 启动" + "_" + ZbGateway.MainGateWay.getGatewayBaseInfo.gwID + System.DateTime.Now.ToString()); try { if(setConditionData !=null){ var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 2006 } }; var data = new JObject { { "LogicId",setConditionData.LogicId}, { "ConditionId", setConditionData.ConditionId} , { "Operation", setConditionData.Operation } }; jObject.Add("Data", data); ZbGateway.MainGateWay?.Send(("Logic/SetCondition"), jObject.ToString()); } } catch { } var dateTime = DateTime.Now; while ((DateTime.Now - dateTime).TotalMilliseconds < 2000) { await System.Threading.Tasks.Task.Delay(10); if (allData != null) { break; } } if ((DateTime.Now - dateTime).TotalMilliseconds > 2000) { allData = new SetConditionResponseAllData { errorMessageBase = " 回复超时,请重新操作" }; } ZbGateway.MainGateWay.Actions -= action; System.Console.WriteLine("Logic/SetCondition_Actions 退出" + "_" + ZbGateway.MainGateWay.getGatewayBaseInfo.gwID + System.DateTime.Now.ToString()); return allData; }); } /// ///删除/启用/禁用逻辑条件的所有数据,网关反馈信息 /// public SetConditionResponseAllData setConditionResponseAllData; /// /// 删除/启用/禁用逻辑条件回复的所有数据 /// [System.Serializable] public class SetConditionResponseAllData { /// /// 错误信息 /// public string errorMessageBase; /// /// 网关信息错误反馈 /// 当网关接收到客户端信息后,出现以下异常情况将反馈错误。 /// public ErrorResponData errorResponData; /// /// 删除/启用/禁用逻辑条件回复的数据 /// public SetConditionResponseData setConditionResponseData; } /// ///获取删除/启用/禁用逻辑条件的数据 /// public SetConditionResponseData setConditionResponseData; /// ///获取删除/启用/禁用逻辑条件的数据 /// [System.Serializable] public class SetConditionResponseData : LogicBase { /// /// 0:成功 ///1:失败,逻辑或条件不存在 /// public int Result; /// /// 条件id /// public int ConditionId; /// /// 0:忽略条件,将条件IsVaild置0。 ///1:启用条件,将条件IsVaild置1。 ///2:使能一次,将条件IsVaild置2(条件成立一次后将被禁用,IsValid自动置为0)。 ///3:失能一次,将条件IsVaild置3(条件第一次成立会被忽略,触发不了逻辑,然后IsValid自动置1。以后条件再成立将不会被忽略) ///4:删除条件。 /// public int Operation; } /// ///设置删除/启用/禁用逻辑条件的数据 /// public SetConditionData setConditionData; /// ///设置删除/启用/禁用逻辑条件的数据 /// [System.Serializable] public class SetConditionData : LogicBase { /// /// 条件id /// public int ConditionId; /// /// 0:忽略条件,将条件IsVaild置0。 ///1:启用条件,将条件IsVaild置1。 ///2:使能一次,将条件IsVaild置2(条件成立一次后将被禁用,IsValid自动置为0)。 ///3:失能一次,将条件IsVaild置3(条件第一次成立会被忽略,触发不了逻辑,然后IsValid自动置1。以后条件再成立将不会被忽略) ///4:删除条件。 /// public int Operation = 1; } #endregion #region 修改或新增动作任务. /// /// 修改或新增动作任务 /// public static async System.Threading.Tasks.Task ChangeActionAsync(ChangeActionData actionData) { return await System.Threading.Tasks.Task.Run(async () => { ChangeActionResponseAllData allData = null; if (ZbGateway.MainGateWay == null) { allData = new ChangeActionResponseAllData { errorMessageBase = "当前没有主网关" }; return allData; } Action 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("Time"), DataID = jobject.Value("Data_ID"), CurrentGateWayId = ZbGateway.MainGateWay.getGatewayBaseInfo.gwID }; var temp = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (temp == null) { allData = new ChangeActionResponseAllData { errorMessageBase = "网关错误回复,且数据是空" }; } else { allData = new ChangeActionResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "Logic/ChangeAction_Respon") { var logic = new Logic() { DataID = jobject.Value("DataID"), GateWayId = ZbGateway.MainGateWay.CurrentGateWayId }; var tempData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (tempData == null) { allData = new ChangeActionResponseAllData { errorMessageBase = "网关返回的数据为空" }; } else { allData = new ChangeActionResponseAllData { changeActionResponseData = tempData }; System.Console.WriteLine($"收到通知后的主题_{ topic}"); } } }; ZbGateway.MainGateWay.Actions += action; System.Console.WriteLine("Logic/ChangeAction_Actions 启动" + "_" + ZbGateway.MainGateWay.getGatewayBaseInfo.gwID + System.DateTime.Now.ToString()); try { if (actionData != null) { var dataPublish = new Dictionary { }; switch (actionData.LinkType) { case 0: var dataPublish0 = new Dictionary { ["LogicId"] = actionData.LogicId, ["LinkType"] = actionData.LinkType, ["DeviceAddr"] = actionData.DeviceAddr, ["Epoint"] = actionData.Epoint, ["TaskList"] = actionData.TaskList, ["Time"] = actionData.Time, }; dataPublish = dataPublish0; break; case 2: int sceneID = int.Parse(actionData.DeviceAddr); var dataPublish2 = new Dictionary { ["LogicId"] = actionData.LogicId, ["LinkType"] = actionData.LinkType, ["DeviceAddr"] = sceneID, ["Epoint"] = actionData.Epoint, }; dataPublish = dataPublish2; break; case 4: int conID = int.Parse(actionData.DeviceAddr); var dataPublish4 = new Dictionary //{ }; { ["LogicId"] = actionData.LogicId, ["LinkType"] = actionData.LinkType, ["DeviceAddr"] = conID, ["EnableLogic"] = actionData.EnableLogic, }; dataPublish = dataPublish4; break; case 5: int logID = int.Parse(actionData.DeviceAddr); var dataPublish5 = new Dictionary { ["LogicId"] = actionData.LogicId, ["LinkType"] = actionData.LinkType, ["DeviceAddr"] = logID, ["ConditionId"] = actionData.ConditionId, ["EnableCondition"] = actionData.EnableCondition, }; dataPublish = dataPublish5; break; case 6: int sID = int.Parse(actionData.DeviceAddr); var dataPublish6 = new Dictionary { ["LogicId"] = actionData.LogicId, ["LinkType"] = actionData.LinkType, ["SecuritySetting"] = actionData.SecuritySetting, ["SecurityModeId"] = actionData.SecurityModeId, ["CheckIASStatus"] = actionData.CheckIASStatus, ["IsDelayStart"] = actionData.IsDelayStart, ["Password"] = actionData.Password }; dataPublish = dataPublish6; break; } ZbGateway.MainGateWay?.Send("Logic/ChangeAction", Device.Cluster_ID.Gateway, Command.LogicChangeAction, Newtonsoft.Json.Linq.JObject.Parse(Newtonsoft.Json.JsonConvert.SerializeObject(dataPublish))); } } catch { } var dateTime = DateTime.Now; while ((DateTime.Now - dateTime).TotalMilliseconds < 2000) { await System.Threading.Tasks.Task.Delay(10); if (allData != null) { break; } } if ((DateTime.Now - dateTime).TotalMilliseconds > 2000) { allData = new ChangeActionResponseAllData { errorMessageBase = " 回复超时,请重新操作" }; } ZbGateway.MainGateWay.Actions -= action; System.Console.WriteLine("Logic/ChangeAction_Actions 退出" + "_" + ZbGateway.MainGateWay.getGatewayBaseInfo.gwID + System.DateTime.Now.ToString()); return allData; }); } /// ///修改或新增动作任务的所有数据,网关反馈信息 /// public ChangeActionResponseAllData changeActionResponseAllData; /// /// 修改或新增动作任务回复的所有数据 /// [System.Serializable] public class ChangeActionResponseAllData { /// /// 错误信息 /// public string errorMessageBase; /// /// 网关信息错误反馈 /// 当网关接收到客户端信息后,出现以下异常情况将反馈错误。 /// public ErrorResponData errorResponData; /// /// 修改或新增动作任务回复的数据 /// public ChangeActionResponseData changeActionResponseData; } /// ///修改或新增动作任务回复的数据 /// public ChangeActionResponseData changeActionResponseData; /// ///获取修改或新增动作任务的数据 /// [System.Serializable] public class ChangeActionResponseData : LogicBase { /// /// 0:成功 ///1:失败,逻辑不存在 ///2:失败,联动设备不存在 ///3:失败,联动的其他逻辑不存在。 ///5:操作的逻辑的条件不存在 ///6:布防撤防用户密码错误 ///7:安防模式不存在 /// public int Result; /// /// 添加的联动设备类型 ///0:联动设备为zigbee节点设备 ///2:联动设备为场景(恢复场景) ///4:使能失能其他逻辑 ///5:禁用或启用逻辑条件 ///6:安防模式操作 /// public int LinkType; /// /// 联动设备的地址: ///设备mac地址(字符),LinkType=0。 ///对场景操作,即恢复场景 为场景id(数值),LinkType为2。 ///对其他逻辑操作 为逻辑id(数值),LinkType=4 、LinkType= 5。 /// public string DeviceAddr; /// ///联动设备的端口号: ///和mac地址共同标识唯一的zigbee设备 数值范围0-255 ///场景和组设为null,或忽略该字段 /// public int Epoint; /// ///逻辑使能、失能。 ///当LinkType = 4时存在 ///0:失能逻辑。 ///1:使能逻辑。 ///2:只使能一次 ///3:只失能一次 /// public int EnableLogic; /// /// 操作的逻辑条件id /// public int ConditionId; /// /// 是否禁用逻辑条件 ///当LinkType=5时存在 ///0 禁用条件(将逻辑条件的IsValid字段置0) ///1 启用条件(将逻辑条件的IsValid字段置1) ///2:使能一次(条件成立一次后将被禁用,IsValid自动置为0)。 ///3:失能一次(条件第一次成立会被忽略,触发不了逻辑,然后IsValid自动置1。以后条件再成立将不会被忽略) /// public int EnableCondition; /// ///延时执行时间。单位(秒)范围:0-65535。 ///逻辑成立后,延迟多久执行设备动作指令。 ///当LinkType=0时存在。该字段可忽略,默认为0,即逻辑成立后立即执行设备动作。 /// public int Time; /// /// 联动任务列表,联动的节点设备执行的动作指令。 ///当LinkType=0时存在。 ///和本章第1小节的添加或修改逻辑命令的TaskList数组格式相同 /// public List TaskList = new List { }; /// ///对安防模式操作 ///当LinkType = 6时存在 ///0:撤防 ///1:永久布防,直到撤防 ///2:布防,但使能一次,触发一次后将撤防。 ///3:布防,但失能一次,第一次被激活不警告不触发动作。 ///触发动作时,如果系统当前没有布防,则撤防失败。已经存在布防模式,将布防失败(需先对当前布防模式进行撤防) /// /// The epoint. public int SecuritySetting; /// ///安防模式id。为0时,则对当前在布防的安防模式进行操作。 /// /// The epoint. public int SecurityModeId; /// ///检查防区设备最近上报的安防信息状态进行布防 ///当LinkType = 6时存在 ///0:不检查 ///1:检查 ///可缺省,默认为0 /// /// The epoint. public int CheckIASStatus; /// ///是否延时启动。布防后延时一段时间正式启动防区,这段时间可以让人员撤离防区区域。 ///当LinkType = 6时存在 ///0:不延时 ///1:延时启动 ///可缺省,默认为0 /// /// The epoint. public int IsDelayStart; } /// ///设置需要修改或新增动作任务的数据 /// public ChangeActionData changeActionData; /// ///设置需要修改或新增动作任务的数据 /// LogicId, /// [System.Serializable] public class ChangeActionData : LogicBase { /// /// 添加的联动设备类型 ///0:联动设备为zigbee节点设备 ///2:联动设备为场景(恢复场景) ///4:使能失能其他逻辑 ///5:禁用或启用逻辑条件 /// 6:安防模式操作 /// public int LinkType; /// /// 联动设备的地址: /// 设备mac地址(字符),LinkType=0。 ///对场景操作,即恢复场景 为场景id(数值),LinkType为2。 ///对其他逻辑操作 为逻辑id(数值),LinkType=4 、LinkType= 5。 /// public string DeviceAddr; /// /// 联动设备的端口号:LinkType=0时存在 ///和mac地址共同标识唯一的zigbee设备 数值范围0-255 ///场景和组设为null,或忽略该字段 /// public int Epoint; /// /// 逻辑使能、失能。LinkType=4时存在 ///0:失能逻辑。 ///1:使能逻辑。 ///2:只使能一次 ///3:只失能一次 /// public int EnableLogic; /// /// 操作的逻辑条件id,LinkType=5时存在 /// public int ConditionId; /// /// 是否禁用逻辑条件,LinkType=5时存在 ///0 禁用条件(将逻辑条件的IsValid字段置0) ///1 启用条件(将逻辑条件的IsValid字段置1) ///2:使能一次(条件成立一次后将被禁用,IsValid自动置为0)。 ///3:失能一次(条件第一次成立会被忽略,触发不了逻辑,然后IsValid自动置1。以后条件再成立将不会被忽略) /// public int EnableCondition; /// ///延时执行时间。LinkType=0时存在 ///当LinkType=0时,该字段也可忽略,默认为0,即逻辑成立后立即执行设备动作。 ///单位(秒)范围:0-65535。 ///逻辑成立后,延迟多久执行设备动作指令。 /// public int Time; /// ///联动任务列表,LinkType=0时存在 ///联动的节点设备执行的动作指令。 ///和本章第1小节的添加或修改逻辑命令的TaskList数组格式相同 /// public List TaskList = new List { }; /// ///对安防模式操作 ///当LinkType = 6时存在 ///0:撤防 ///1:永久布防,直到撤防 ///2:布防,但使能一次,触发一次后将撤防。 ///3:布防,但失能一次,第一次被激活不警告不触发动作。 ///触发动作时,如果系统当前没有布防,则撤防失败。已经存在布防模式,将布防失败(需先对当前布防模式进行撤防) /// /// The epoint. public int SecuritySetting; /// ///安防模式id。为0时,则对当前在布防的安防模式进行操作。 /// /// The epoint. public int SecurityModeId; /// ///检查防区设备最近上报的安防信息状态进行布防 ///当LinkType = 6时存在 ///0:不检查 ///1:检查 ///可缺省,默认为0 /// /// The epoint. public int CheckIASStatus; /// ///是否延时启动。布防后延时一段时间正式启动防区,这段时间可以让人员撤离防区区域。 ///当LinkType = 6时存在 ///0:不延时 ///1:延时启动 ///可缺省,默认为0 /// /// The epoint. public int IsDelayStart; /// ///布防撤防用户密码,如果密码错误将加入失败 ///当LinkType = 6时存在 ///数据回复时,该字段不存在 /// /// The epoint. public int Password; } #endregion #region 删除动作. /// /// 删除动作 /// public static async System.Threading.Tasks.Task DelActionAsync(DelActionData actionData) { return await System.Threading.Tasks.Task.Run(async () => { DelActionResponseAllData allData = null; if (ZbGateway.MainGateWay == null) { allData = new DelActionResponseAllData { errorMessageBase = "当前没有主网关" }; return allData; } Action 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("Time"), DataID = jobject.Value("Data_ID"), CurrentGateWayId = ZbGateway.MainGateWay.getGatewayBaseInfo.gwID }; var temp = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (temp == null) { allData = new DelActionResponseAllData { errorMessageBase = "网关错误回复,且数据是空" }; } else { allData = new DelActionResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "Logic/DelAction_Respon") { var logic = new Logic() { DataID = jobject.Value("DataID"), GateWayId = ZbGateway.MainGateWay.CurrentGateWayId }; var tempData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (tempData == null) { allData = new DelActionResponseAllData { errorMessageBase = "网关返回的数据为空" }; } else { allData = new DelActionResponseAllData { delActionResponseData = tempData }; System.Console.WriteLine($"收到通知后的主题_{ topic}"); } } }; ZbGateway.MainGateWay.Actions += action; System.Console.WriteLine("Logic/DelAction_Actions 启动" + "_" + ZbGateway.MainGateWay.getGatewayBaseInfo.gwID + System.DateTime.Now.ToString()); try { if (actionData != null) { var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 2008 } }; var dataPublish = new Dictionary { }; switch (actionData.Type) { case 0: var dataPublish0 = new Dictionary { ["LogicId"] = actionData.LogicId, ["Type"] = actionData.Type, ["DeviceAddr"] = actionData.DeviceAddr, ["Epoint"] = actionData.Epoint, }; dataPublish = dataPublish0; break; case 2: int sceneID = int.Parse(actionData.DeviceAddr); var dataPublish2 = new Dictionary { ["LogicId"] = actionData.LogicId, ["Type"] = actionData.Type, ["DeviceAddr"] = sceneID, ["Epoint"] = actionData.Epoint, }; dataPublish = dataPublish2; break; case 4: int conID = int.Parse(actionData.DeviceAddr); var dataPublish4 = new Dictionary //{ }; { ["LogicId"] = actionData.LogicId, ["Type"] = actionData.Type, ["DeviceAddr"] = conID, }; dataPublish = dataPublish4; break; case 5: int logID = int.Parse(actionData.DeviceAddr); var dataPublish5 = new Dictionary { ["LogicId"] = actionData.LogicId, ["Type"] = actionData.Type, ["DeviceAddr"] = logID, ["ConditionId"] = actionData.ConditionId, }; dataPublish = dataPublish5; break; case 6: int sID = int.Parse(actionData.DeviceAddr); var dataPublish6 = new Dictionary { ["LogicId"] = actionData.LogicId, ["Type"] = actionData.Type, ["SecurityModeId"] = actionData.SecurityModeId, }; dataPublish = dataPublish6; break; } ZbGateway.MainGateWay?.Send("Logic/ChangeAction", Device.Cluster_ID.Gateway, Command.LogicDelAction, Newtonsoft.Json.Linq.JObject.Parse(Newtonsoft.Json.JsonConvert.SerializeObject(dataPublish))); } } catch { } var dateTime = DateTime.Now; while ((DateTime.Now - dateTime).TotalMilliseconds < 2000) { await System.Threading.Tasks.Task.Delay(10); if (allData != null) { break; } } if ((DateTime.Now - dateTime).TotalMilliseconds > 2000) { allData = new DelActionResponseAllData { errorMessageBase = " 回复超时,请重新操作" }; } ZbGateway.MainGateWay.Actions -= action; System.Console.WriteLine("Logic/DelAction_Actions 退出" + "_" + ZbGateway.MainGateWay.getGatewayBaseInfo.gwID + System.DateTime.Now.ToString()); return allData; }); } /// ///删除动作的所有数据,网关反馈信息 /// public DelActionResponseAllData delActionResponseAllData; /// /// 删除动作回复的所有数据 /// [System.Serializable] public class DelActionResponseAllData { /// /// 错误信息 /// public string errorMessageBase; /// /// 网关信息错误反馈 /// 当网关接收到客户端信息后,出现以下异常情况将反馈错误。 /// public ErrorResponData errorResponData; /// /// 删除动作回复的数据 /// public DelActionResponseData delActionResponseData; } /// ///删除动作的数据 /// public DelActionResponseData delActionResponseData; /// ///删除动作的数据 /// [System.Serializable] public class DelActionResponseData : LogicBase { /// /// 0:成功 ///1:失败,逻辑或动作设备不存在 /// public int Result; /// /// 删除的联动设备的类型: ///0:联动设备为zigbee节点设备 ///2:联动设备为场景(恢复场景) ///4:使能失能其他逻辑 ///5:禁用或启用逻辑条件 ///6:安防模式操作 /// public int Type; /// /// 联动设备的地址: ///对设备操作 为设备mac地址(字符),Type为0 ///对组操作 为组id(数值),Type为2 ///对场景操作 为场景id(数值),Type为2 ///对逻辑操作 为逻辑id(数值),Type为4或5 /// public string DeviceAddr; /// ///联动设备的端口号: ///和mac地址共同标识唯一的zigbee设备 数值范围0-255 ///场景和组、逻辑忽略该字段 /// public int Epoint; /// ///其他逻辑的条件id,当Type为5时存在 /// public int ConditionId; /// ///安防模式id。为0时,则对当前在布防的安防模式进行操作。(当Type = 6时存在) /// public int SecurityModeId; } /// ///删除动作的数据 /// public DelActionData delActionData; /// ///删除动作的数据 /// [System.Serializable] public class DelActionData : LogicBase { /// /// 删除的联动设备的类型: ///0:联动设备为zigbee节点设备 ///2:联动设备为场景(恢复场景) ///4:使能失能其他逻辑 ///5:禁用或启用逻辑条件 ///6:安防模式操作 /// public int Type; /// /// 联动设备的地址: ///对设备操作 为设备mac地址(字符),Type为0 ///对组操作 为组id(数值),Type为1 ///对场景操作 为场景id(数值),Type为2 ///对逻辑操作 为逻辑id(数值),Type为3 /// public string DeviceAddr; /// /// Type为0时才存在,此时必需填写参数 /// 联动设备的端口号 ///和mac地址共同标识唯一的zigbee设备 数值范围0-255 ///场景和组、逻辑忽略该字段 /// public int Epoint; /// /// Type为5时才存在,此时必需填写参数 /// 操作的逻辑条件id,Type为5时存在 /// public int ConditionId; /// /// Type为6时才存在,此时必需填写参数 /// 安防模式id。为0时,则对当前在布防的安防模式进行操作。 /// public int SecurityModeId; } #endregion #region 删除逻辑. /// /// 删除逻辑 /// public static async System.Threading.Tasks.Task DelLogicAsync(int logicId) { return await System.Threading.Tasks.Task.Run(async () => { DelLogicResponseAllData allData = null; if (ZbGateway.MainGateWay == null) { allData = new DelLogicResponseAllData { errorMessageBase = "当前没有主网关" }; return allData; } Action 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("Time"), DataID = jobject.Value("Data_ID"), CurrentGateWayId = ZbGateway.MainGateWay.getGatewayBaseInfo.gwID }; var temp = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (temp == null) { allData = new DelLogicResponseAllData { errorMessageBase = "网关错误回复,且数据是空" }; } else { allData = new DelLogicResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "Logic/DelLogic_Respon") { var logic = new Logic() { DataID = jobject.Value("DataID"), GateWayId = ZbGateway.MainGateWay.CurrentGateWayId }; var tempData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (tempData == null) { allData = new DelLogicResponseAllData { errorMessageBase = "网关返回的数据为空" }; } else { allData = new DelLogicResponseAllData { delLogicResponseData = tempData }; System.Console.WriteLine($"收到通知后的主题_{ topic}"); } } }; ZbGateway.MainGateWay.Actions += action; System.Console.WriteLine("Logic/DelLogic_Actions 启动" + "_" + ZbGateway.MainGateWay.getGatewayBaseInfo.gwID + System.DateTime.Now.ToString()); try { var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 2009 } }; var data = new JObject { { "LogicId",logicId} }; jObject.Add("Data", data); ZbGateway.MainGateWay?.Send(("Logic/DelLogic"), jObject.ToString()); } catch { } var dateTime = DateTime.Now; while ((DateTime.Now - dateTime).TotalMilliseconds < 2000) { await System.Threading.Tasks.Task.Delay(10); if (allData != null) { break; } } if ((DateTime.Now - dateTime).TotalMilliseconds > 2000) { allData = new DelLogicResponseAllData { errorMessageBase = " 回复超时,请重新操作" }; } ZbGateway.MainGateWay.Actions -= action; System.Console.WriteLine("Logic/DelLogic_Actions 退出" + "_" + ZbGateway.MainGateWay.getGatewayBaseInfo.gwID + System.DateTime.Now.ToString()); return allData; }); } /// ///删除逻辑的所有数据,网关反馈信息 /// public DelLogicResponseAllData delLogicResponseAllData; /// /// 删除逻辑的所有数据 /// [System.Serializable] public class DelLogicResponseAllData { /// /// 错误信息 /// public string errorMessageBase; /// /// 网关信息错误反馈 /// 当网关接收到客户端信息后,出现以下异常情况将反馈错误。 /// public ErrorResponData errorResponData; /// /// 删除逻辑回复的数据 /// public DelLogicResponseData delLogicResponseData; } /// ///删除逻辑的数据 /// public DelLogicResponseData delLogicResponseData; /// ///删除逻辑的数据 /// [System.Serializable] public class DelLogicResponseData : LogicBase { /// ///0:成功 ///1:失败,逻辑不存在 /// public int Result; } #endregion #region 时间点条件推迟执行 /// ///获取时间点条件推迟执行的数据 /// public TimingWillArriveData timingWillArriveData; /// ///获取时间点条件推迟执行的数据 /// [System.Serializable] public class TimingWillArriveData : LogicBase { /// /// 条件id /// public int ConditionId; /// ///条件类型 ///0:阳历 1:农历 /// public int Calendar; /// ///时间点类型: ///0:正常时间点(从Datetime这个时间点开始执行) ///1:日出时间(从DateTime之后第一次日出时间开始执行) ///2:日落时间(从DateTime之后第一次日落时间开始执行) ///3:正午时间(从DateTime之后第一次中午时间开始执行) /// public int DateType; /// ///表示触发动作的开始时间 格式为由utc时间转换成的Unix时间戳。如北京时间2018年7月9日 17:50:00,则转换时间戳后为1531129800。该时间点也是每月每年重复的判断依据。 /// public int Datetime; /// /// 当Type为0时,该字段才存在 ///重复类型 ///1:每小时执行(按上面例子,从北京时间2018/7/9 17:50:00开始每小时执行一次) ///2:每天执行(按上面例子,从北京时间2018/7/9 17:50:00开始每天17:50:00执行一次) ///3:每月执行(按上面例子,从北京时间2018/7/9 17:50:00开始每月9日17:50:00执行一次。如果为农历则是每月农历二十六执行) ///4:每年执行(按上面例子,从北京时间2018/7/9 17:50:00开始每年7月9日17:50:00执行一次。如果为农历,则是每年农历五月二十六17:50:00执行) ///5:周重复。(周一到周七可选执行) /// public int Repeat; /// /// 周工作模式(可或运算) ///0x01 周一执行 ///0x02 周二执行 ///0x04 周三执行 ///0x08 周四执行 ///0x10 周五执行 ///0x20 周六执行 ///0x40 周日执行 ///0x7F 每天执行 ///数值可进行或运算,如周一、周三、周五执行,则为WeekDay=(0x01 || 0x04 || 0x10)= 0x15 即十进制 21。 /// /// The week day. public int WeekDay; /// ///提前提醒时间。(单位秒)范围:0-65535 ///定时条件将要触发的前RemindTime秒,网关将通知客户端定时时间将至,可能会执行逻辑动作(如果该逻辑还需要满足其他条件,则到达定时时间时,其他条件没有满足将不会执行逻辑动作)。在这段时间内,客户端可发送指令让定时推迟执行。最终的定时时间将是原来定时时间+推迟的时间。 ///如果为0,则不提醒。到达提前提醒时,将发送第11小节的提醒通知。 /// public int RemindTime; /// ///是否允许推迟 ///0:不允许 ///1:允许 /// public int EnDelay; /// ///推迟时间(单位:秒)范围:0-65535 ///推迟时间如果小于提前提醒时间,则在推迟前的定时时间到达时提醒。 /// public int DelayTime; /// ///本次定时条件触发的utc时间 /// public int TriggerTime; } #endregion //#region 推迟定时条件 ///// ///// 设置推迟定时条件成立的数据 /////如果要推迟定时条件成立,可在提醒后到达触发的时间点前发送以下推迟指令。如果推迟成功,时间条件将在原该触发的时间点上推迟DelayTime触发条件。 ///// //public GetLogicTimeDelayTriggerData getLogicTimeDelayTrigger; ///// ///// 设置推迟定时条件成立的数据 /////如果要推迟定时条件成立,可在提醒后到达触发的时间点前发送以下推迟指令。如果推迟成功,时间条件将在原该触发的时间点上推迟DelayTime触发条件。 ///// //[System.Serializable] //public class GetLogicTimeDelayTriggerData : LogicBase //{ // /// // /// 0:成功 // ///1:失败,逻辑或条件不存在 // ///2:失败,条件不是定时条件。 // ///3:失败,条件不允许推迟 // ///4:失败,没有在提醒后到达触发的时间点前发送。 // /// // public int Result; // /// // ///条件id // /// // public int ConditionId; // /// // ///推迟后定时条件触发的utc时间 // /// // public int TriggerTime; //} ///// ///// 推迟定时条件成立,发布到网关 ///// 如果要推迟定时条件成立,可在提醒后到达触发的时间点前发送以下推迟指令。如果推迟成功,时间条件将在原该触发的时间点上推迟DelayTime触发条件。 ///// logicId 逻辑id,逻辑的唯一标识 ///// conditionId 条件id ///// //public void LogicTimeDelayTriggerPublish(int logicId, int conditionId) //{ // var dataPublish = new Dictionary { ["LogicId"] = logicId, ["ConditionId"] = conditionId }; // ZbGateway.MainGateWay?.Send("Logic/TimingWillArrive", Device.Cluster_ID.Gateway, Command.LogicTimeDelayTrigger, Newtonsoft.Json.Linq.JObject.Parse(Newtonsoft.Json.JsonConvert.SerializeObject(dataPublish))); //} //#endregion #region 逻辑被调用反馈. /// ///逻辑控制 /// public static async System.Threading.Tasks.Task ControlLogicAsync(int logicId) { return await System.Threading.Tasks.Task.Run(async () => { ExecuteRespoAllData allData = null; if (ZbGateway.MainGateWay == null) { allData = new ExecuteRespoAllData { errorMessageBase = "当前没有主网关" }; return allData; } Action 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("Time"), DataID = jobject.Value("Data_ID"), CurrentGateWayId = ZbGateway.MainGateWay.getGatewayBaseInfo.gwID }; var temp = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (temp == null) { allData = new ExecuteRespoAllData { errorMessageBase = "网关错误回复,且数据是空" }; } else { allData = new ExecuteRespoAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "Logic/TestActions_Respon") { var logic = new Logic() { DataID = jobject.Value("DataID"), GateWayId = ZbGateway.MainGateWay.CurrentGateWayId }; var tempData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (tempData == null) { allData = new ExecuteRespoAllData { errorMessageBase = "网关返回的数据为空" }; } else { allData = new ExecuteRespoAllData { logicExecuteRespo = tempData }; System.Console.WriteLine($"收到通知后的主题_{ topic}"); } } }; ZbGateway.MainGateWay.Actions += action; System.Console.WriteLine("Logic/TestActions_Actions 启动" + "_" + ZbGateway.MainGateWay.getGatewayBaseInfo.gwID + System.DateTime.Now.ToString()); try { var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 2012 } }; var data = new JObject { { "LogicId",logicId} }; jObject.Add("Data", data); ZbGateway.MainGateWay?.Send(("Logic/TestActions"), jObject.ToString()); } catch { } var dateTime = DateTime.Now; while ((DateTime.Now - dateTime).TotalMilliseconds < 2000) { await System.Threading.Tasks.Task.Delay(10); if (allData != null) { break; } } if ((DateTime.Now - dateTime).TotalMilliseconds > 2000) { allData = new ExecuteRespoAllData { errorMessageBase = " 回复超时,请重新操作" }; } ZbGateway.MainGateWay.Actions -= action; System.Console.WriteLine("Logic/TestActions_Actions 退出" + "_" + ZbGateway.MainGateWay.getGatewayBaseInfo.gwID + System.DateTime.Now.ToString()); return allData; }); } /// /// 调用场景,网关反馈信息 /// 返回Result 0:调用失败 ///Result 1:调用成功 /// public ExecuteRespoAllData executeRespoAllData; /// /// 调用逻辑,网关反馈信息 /// [System.Serializable] public class ExecuteRespoAllData { /// /// 错误信息 /// public string errorMessageBase; /// /// 网关信息错误反馈 /// 当网关接收到客户端信息后,出现以下异常情况将反馈错误。 /// public ErrorResponData errorResponData; /// /// 调用逻辑 /// public ExecuteResponse logicExecuteRespo; } /// ///调用逻辑 /// public ExecuteResponse logicExecuteRespo; /// ///调用逻辑 /// [System.Serializable] public class ExecuteResponse : LogicBase { /// /// 0:成功 ///1:失败,逻辑不存在 /// public int Result; } #endregion #region 设定网关所在地经纬度. /// /// 设定网关所在地经纬度 /// Longitude:经度。单位:0.01°。 东经为正数,西经为负数。如:西经172.53°W,应填入-17253 /// Latitude:维度。单位:0.01°。北纬度为正数,南纬度为负数。如:南纬度,如南纬90.25°S ,应该填入-9025。 /// public static async System.Threading.Tasks.Task SetSiteAsync(int longitude,int latitude) { return await System.Threading.Tasks.Task.Run(async () => { SetSiteResponseAllData allData = null; if (ZbGateway.MainGateWay == null) { allData = new SetSiteResponseAllData { errorMessageBase = "当前没有主网关" }; return allData; } Action 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("Time"), DataID = jobject.Value("Data_ID"), CurrentGateWayId = ZbGateway.MainGateWay.getGatewayBaseInfo.gwID }; var temp = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (temp == null) { allData = new SetSiteResponseAllData { errorMessageBase = "网关错误回复,且数据是空" }; } else { allData = new SetSiteResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "Logic/SetSite_Respon") { var logic = new Logic() { DataID = jobject.Value("DataID"), GateWayId = ZbGateway.MainGateWay.CurrentGateWayId }; var tempData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (tempData == null) { allData = new SetSiteResponseAllData { errorMessageBase = "网关返回的数据为空" }; } else { allData = new SetSiteResponseAllData { setSiteResponseData = tempData }; System.Console.WriteLine($"收到通知后的主题_{ topic}"); } } }; ZbGateway.MainGateWay.Actions += action; System.Console.WriteLine("Logic/SetSite_Actions 启动" + "_" + ZbGateway.MainGateWay.getGatewayBaseInfo.gwID + System.DateTime.Now.ToString()); try { var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 2013 } }; var data = new JObject { { "Longitude",longitude}, { "Latitude",latitude} }; jObject.Add("Data", data); ZbGateway.MainGateWay?.Send(("Logic/SetSite"), jObject.ToString()); } catch { } var dateTime = DateTime.Now; while ((DateTime.Now - dateTime).TotalMilliseconds < 2000) { await System.Threading.Tasks.Task.Delay(10); if (allData != null) { break; } } if ((DateTime.Now - dateTime).TotalMilliseconds > 2000) { allData = new SetSiteResponseAllData { errorMessageBase = " 回复超时,请重新操作" }; } ZbGateway.MainGateWay.Actions -= action; System.Console.WriteLine("Logic/SetSite_Actions 退出" + "_" + ZbGateway.MainGateWay.getGatewayBaseInfo.gwID + System.DateTime.Now.ToString()); return allData; }); } /// /// 设定网关所在地经纬度,网关反馈信息 /// 返回Result 0:调用失败 ///Result 1:调用成功 /// public SetSiteResponseAllData setSiteResponseAllData; /// /// 设定网关所在地经纬度,网关反馈信息 /// [System.Serializable] public class SetSiteResponseAllData { /// /// 错误信息 /// public string errorMessageBase; /// /// 网关信息错误反馈 /// 当网关接收到客户端信息后,出现以下异常情况将反馈错误。 /// public ErrorResponData errorResponData; /// /// 设定网关所在地经纬度 /// public SetSiteResponseData setSiteResponseData; } /// ///设定网关所在地经纬度 /// public SetSiteResponseData setSiteResponseData; /// ///设定网关所在地经纬度 /// [System.Serializable] public class SetSiteResponseData { /// ///0:成功 /// public int Result; /// ///经度。单位:0.01°。 东经为正数,西经为负数。如:西经172.53°W,应填入-17253 /// public int Longitude; /// ///维度。单位:0.01°。北纬度为正数,南纬度为负数。如:南纬度,如南纬90.25°S ,应该填入-9025。 /// public int Latitude; } #endregion #region 读取网关当前设定的经纬度信息. /// ///读取网关当前设定的经纬度信息 /// /// public static async System.Threading.Tasks.Task ReadSiteAsync() { return await System.Threading.Tasks.Task.Run(async () => { ReadSiteResponseAllData allData = null; if (ZbGateway.MainGateWay == null) { allData = new ReadSiteResponseAllData { errorMessageBase = "当前没有主网关" }; return allData; } Action 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("Time"), DataID = jobject.Value("Data_ID"), CurrentGateWayId = ZbGateway.MainGateWay.getGatewayBaseInfo.gwID }; var temp = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (temp == null) { allData = new ReadSiteResponseAllData { errorMessageBase = "网关错误回复,且数据是空" }; } else { allData = new ReadSiteResponseAllData { errorResponData = temp, errorMessageBase = ErrorMess(temp.Error) }; } } if (topic == gatewayID + "/" + "Logic/ReadSite_Respon") { var logic = new Logic() { DataID = jobject.Value("DataID"), GateWayId = ZbGateway.MainGateWay.CurrentGateWayId }; var tempData = Newtonsoft.Json.JsonConvert.DeserializeObject(jobject["Data"].ToString()); if (tempData == null) { allData = new ReadSiteResponseAllData { errorMessageBase = "网关返回的数据为空" }; } else { allData = new ReadSiteResponseAllData { readSiteResponseData = tempData }; System.Console.WriteLine($"收到通知后的主题_{ topic}"); } } }; ZbGateway.MainGateWay.Actions += action; System.Console.WriteLine("Logic/ReadSite_Actions 启动" + "_" + ZbGateway.MainGateWay.getGatewayBaseInfo.gwID + System.DateTime.Now.ToString()); try { var jObject = new JObject { { "Cluster_ID", 0 }, { "Command", 2014 } }; ZbGateway.MainGateWay?.Send(("Logic/ReadSite"), jObject.ToString()); } catch { } var dateTime = DateTime.Now; while ((DateTime.Now - dateTime).TotalMilliseconds < 2000) { await System.Threading.Tasks.Task.Delay(10); if (allData != null) { break; } } if ((DateTime.Now - dateTime).TotalMilliseconds > 2000) { allData = new ReadSiteResponseAllData { errorMessageBase = " 回复超时,请重新操作" }; } ZbGateway.MainGateWay.Actions -= action; System.Console.WriteLine("Logic/ReadSite_Actions 退出" + "_" + ZbGateway.MainGateWay.getGatewayBaseInfo.gwID + System.DateTime.Now.ToString()); return allData; }); } /// /// 读取网关当前设定的经纬度信息,网关反馈信息 /// 返回Result 0:调用失败 ///Result 1:调用成功 /// public ReadSiteResponseAllData readSiteResponseAllData; /// /// 读取网关当前设定的经纬度信息,网关反馈信息 /// [System.Serializable] public class ReadSiteResponseAllData { /// /// 错误信息 /// public string errorMessageBase; /// /// 网关信息错误反馈 /// 当网关接收到客户端信息后,出现以下异常情况将反馈错误。 /// public ErrorResponData errorResponData; /// /// 读取网关当前设定的经纬度信息 /// public ReadSiteResponseData readSiteResponseData; } /// ///读取网关当前设定的经纬度信息 /// public ReadSiteResponseData readSiteResponseData; /// ///读取网关当前设定的经纬度信息 /// [System.Serializable] public class ReadSiteResponseData { /// ///经度。单位:0.01°。 东经为正数,西经为负数。如:西经172.53°W,应填入-17253 /// public int Longitude; /// ///维度。单位:0.01°。北纬度为正数,南纬度为负数。如:南纬度,如南纬90.25°S ,应该填入-9025。 /// public int Latitude; } #endregion #region 条件数据对象 /// /// 其他逻辑条件数据 /// [System.Serializable] public class LogicConditionsInfo : ConditionBase { /// ///作条件的其他逻辑id。 /// public int Condition_LogicId; } /// /// 计数器条件数据 /// [System.Serializable] public class CounterConditionsInfo : ConditionBase { /// /// 设备mac地址 /// public string MacAddr; /// /// 当Type为1时,该字段才存在 ///设备端口号,该端口填入的是用于上报Cluster_ID和AttriButeId属性值的端口号。 ///特殊设备: ///如果为hdl功能按键则填入按键号(按键对应的端口号) /// public int Epoint; /// ///当Type为1 时,该字段才存在 ///触发联动的属性状态所在Cluster 如开关Cluster 6 ///特殊设备: ///1、如果为hdl功能按键则填64528。 ///2、如果为IAS安防设备则填入1280。 ///3、如果为门锁操作事件,则填入64529。 /// public int Cluster_ID; /// ///当Type为1 时,该字段才存在 /// 触发联动的属性 如Cluster = 6时 AttriButeId = 0为开关属性 ///特殊设备: ///如果为hdl功能按键则为按键触发时上报触发信息的按键号类型。 ///如果为IAS安防设备则填入1281。 ///如果为门锁操作事件则填入门锁操作事件的OperationEventSoure列表值 /// public int AttriButeId; /// /// 属性状态临界值1 ///特殊设备: ///如果为hdl功能按键,则为下列按键模式:1:点击 2:前点击 4:后单击 8:仅双击 16:前双击 32:后双击 64:仅长按 128:前长按 256:后长按 512:长按释放。 ///如果为IAS安防设备则为IAS安防设备信息上报数据中的ZoneStatus。 ///如果为门锁操作事件则填入门锁操作事件的Operation Event Code值 /// public int AttriButeData1; /// /// 属性状态临界值2 (参考AttriButeData1说明) /// public int AttriButeData2; /// /// 0 : 大于AttriButeData1时计数一次 ///1 :等于AttriButeData1时计数一次 ///2:小于AttriButeData1时计数一次 ///3:大于AttriButeData1且小于AttriButeData2计数一次 ///4:小于AttriButeData1或大于AttriButeData2计数一次 ///5:与AttriButeData1进行与运算结果不为0时计数一次。 ///6:和上一次上报的AttriButeData值不同时计数一次 /// public int Range; /// ///到达多少次触发逻辑 /// public int Number; /// ///时间范围。单位:秒 ///多少秒内到达多少次触发。 ///如果时间到达后,还不达到次数则将次数清零。重新开始倒计时及计数。 /// public int Time; /// ///可缺省,默认为 0。 ///是否循环执行。对一次规定时间内是否达到触发次数的结果处理。 ///0:循环执行。当超时或规定时间内达到次数后,清零次数,重新计时,继续下一次计数。 ///1:某次超时退出。如果达到次数则清零计数重新计时,继续下一次计数。如果超时则退出计数。并将IsVail设置为0。 ///2:计数一次退出。到达规定时间后,无论是否达到次数,都将退出。并将IsVail置0。 /// public int Cycle; } /// /// 倒计时条件数据 /// [System.Serializable] public class CountdownConditionsInfo : ConditionBase { /// ///倒计时多少秒触发。单位 秒。 ///倒计时只生效一次,每次倒计时完成后自动将IsValid置0。客户端可通过第6小节命令使能该倒计时条件,将IsValid置1,即可再次使用该倒计时。 /// public int Time; } /// /// 时间段条件条件数据 /// [System.Serializable] public class TimeBucketConditionsInfo : ConditionBase { /// ///触发动作开始时间,小时。 /// public int StartHour; /// ///触发动作开始时间,分钟 /// public int StartMin; /// ///触发动作结束时间,小时 /// public int StopHour; /// ///触发时间结束时间,分钟 /// public int StopMin; } /// /// 安防条件数据 /// [System.Serializable] public class SecurityConditionsInfo : ConditionBase { /// ///0:布防成功瞬间触发条件成立。 ///1:撤防成功瞬间触发条件成立。 /// public int EnOrWithdrawMode; /// ///安防模式id。如果为0,则为任意安防模式布防或撤防成功后触发条件 /// public int ModeId; } /// /// 执行动作数据 /// [System.Serializable] public class ActionsInfo { /// /// 添加的联动设备类型 ///0:联动设备为zigbee节点设备 ///2:联动设备为场景(恢复场景) ///4:使能失能其他逻辑 ///5:禁用或启用逻辑条件 ///6:对安防模式进行布撤防 /// /// The type of the link. public int LinkType; /// /// 联动设备的地址: ///设备mac地址(字符),LinkType=0。 ///对场景操作,即恢复场景 为场景id(数值),LinkType为2。 ///对其他逻辑操作 为逻辑id(数值),LinkType为4 、LinkType为 5。 /// /// The device address. public string DeviceAddr; /// /// 联动设备的端口号: ///和mac地址共同标识唯一的zigbee设备 数值范围0-255 ///当LinkType=0时存在 /// /// The epoint. public int Epoint; /// /// 逻辑使能、失能。 ///当LinkType = 4时存在 ///0:失能逻辑。 ///1:使能逻辑。 ///2:只使能一次 ///3:只失能一次 /// /// The epoint. public int EnableLogic; /// /// 操作的逻辑条件id。 ///当LinkType=5时存在 /// /// The epoint. public int ConditionId; /// /// 是否禁用逻辑条件 ///当LinkType=5时存在 ///0 禁用条件(将逻辑条件的IsValid字段置0) ///1 启用条件(将逻辑条件的IsValid字段置1) ///2:使能一次(条件成立一次后将被禁用,IsValid自动置为0)。 ///3:失能一次(条件第一次成立会被忽略,触发不了逻辑,然后IsValid自动置1。以后条件再成立将不会被忽略) /// /// The epoint. public int EnableCondition; /// /// 延时执行时间。单位(秒)范围:0-65535。 ///逻辑成立后,延迟多久执行设备动作指令。 ///当LinkType=0时存在。该字段可忽略,默认为0,即逻辑成立后立即执行设备动作。 /// /// The epoint. public int Time; /// /// 设备列表 /// 当LinkType=0时存在 /// public List TaskList = new List(); /// ///对安防模式操作 ///当LinkType = 6时存在 ///0:撤防 ///1:永久布防,直到撤防 ///2:布防,但使能一次,触发一次后将撤防。 ///3:布防,但失能一次,第一次被激活不警告不触发动作。 ///触发动作时,如果系统当前没有布防,则撤防失败。已经存在布防模式,将布防失败(需先对当前布防模式进行撤防) /// /// The epoint. public int SecuritySetting; /// ///安防模式id。为0时,则对当前在布防的安防模式进行操作。 /// /// The epoint. public int SecurityModeId; /// ///检查防区设备最近上报的安防信息状态进行布防 ///当LinkType = 6时存在 ///0:不检查 ///1:检查 ///可缺省,默认为0 /// /// The epoint. public int CheckIASStatus; /// ///是否延时启动。布防后延时一段时间正式启动防区,这段时间可以让人员撤离防区区域。 ///当LinkType = 6时存在 ///0:不延时 ///1:延时启动 ///可缺省,默认为0 /// /// The epoint. public int IsDelayStart; /// ///布防撤防用户密码,如果密码错误将加入失败 ///当LinkType = 6时存在 ///数据回复时,该字段不存在 /// /// The epoint. public int Password; } /// /// 时间条件数据 /// [System.Serializable] public class TimeConditionsInfo : ConditionBase { /// ///时间点类型: ///0:正常时间点(由StartHour和StartMin设定) ///1:日出时间 ///2:日落时间 ///3:正午时间 /// public int DateType; /// ///触发动作时间,(0-23)小时。 ///当DateType = 0时,该参数才有效。 /// public int StartHour; /// ///触发动作时间,(0-59)分钟。 ///当DateType = 0 时,该参数才有效。 /// public int StartMin; /// ///提前或推后多少分钟执行。(单位:分钟) ///范围:-127到127。正数为推后,负值为提前。 ///如日落前30分钟执行,则将该值设定为-30。 ///当DateType不为0时,该参数才有效。 /// public int AdjustTime; /// ///提前提醒时间。(单位秒)范围:0-65535 ///定时条件将要触发的前RemindTime秒,网关将通知客户端定时时间将至,可能会执行逻辑动作(如果该逻辑还需要满足其他条件,则到达定时时间时,其他条件没有满足将不会执行逻辑动作)。在这段时间内,客户端可发送指令让定时推迟执行。最终的定时时间将是原来定时时间+推迟的时间。 ///如果为0,则不提醒。到达提前提醒时,将发送第11小节的提醒通知。 /// public int RemindTime; /// ///是否允许推迟 ///0:不允许 ///1:允许 /// public int EnDelay; /// ///推迟时间(单位:秒)范围:0-65535 ///推迟时间如果小于提前提醒时间,则在推迟前的定时时间到达时提醒。可缺省 ,默认为0。 /// public int DelayTime; } /// /// 设备条件数据 /// [System.Serializable] public class DeviceConditionsInfo : ConditionBase { /// ///设备mac地址(当Type为1时,该字段才存在) /// public string MacAddr; /// /// 设备端口号,(当Type为1时,该字段才存在) /// 该端口填入的是用于上报Cluster_ID和AttriButeId属性值的端口号。) /// 特殊设备: /// 如果为hdl功能按键则填入按键号(按键对应的端口号) /// public int Epoint; /// /// 触发联动的属性状态所在Cluster 如开关Cluster 6.(当Type为1时,该字段才存在) ///特殊设备: ///1、如果为hdl功能按键则填64528。 ///2、如果为IAS安防设备则填入1280。 ///3、如果为门锁操作事件,则填入64529. /// 4、如果为随心贴按键On/Off命令反馈,则填入1282 /// public int Cluster_ID; /// ///触发联动的属性 如Cluster=6时 AttriButeId=0为开关属性.(当Type为1时,该字段才存在) ///特殊设备: ///1.如果为hdl功能按键则为按键触发时上报触发信息的按键号类型。 ///2.如果为IAS安防设备则填入1281。 ///3.如果为门锁操作事件则填入门锁操作事件的OperationEventSoure列表值,参考第八章节3门锁操作事件通知 ///4.如果为随心贴On/Off命令反馈,则填入1283。 /// public int AttriButeId; /// ///属性状态临界值1 (当Type为1 时,该字段才存在) /// 特殊设备: ///如果为hdl功能按键,则为下列按键模式: ///1:点击 2:前点击 4:后单击 8:仅双击 ///16:前双击 32:后双击 64:仅长按 ///128:前长按 256:后长按 512:长按释放。 ///2.如果为IAS安防设备则为IAS安防设备信息上报数据中的ZoneStatus。 ///3.如果为门锁操作事件则填入门锁操作事件的Operation Event Code值,参考第八章节3门锁操作事件通知 ///4、如果为随心贴On/Off则填入 0。当接收到随心贴设备On/Off命令反馈将触发逻辑 /// public int AttriButeData1; /// ///属性状态临界值2 。(当Type为1 时,该字段才存在) ///特殊设备:(见AttriButeData1说明) /// public int AttriButeData2; /// ///当Type为1 时,该字段才存在 ///上报的设备属性状态值AttriButeData(参考设备状态查询章节)与设定的临界值比较。 ///0 : 上报的设备属性状态值大于AttriButeData1时触发动作 ///1:上报的设备属性状态值等于AttriButeData1时触发动作 ///2:上报的设备属性状态值小于AttriButeData1时触发动作 ///3:上报的设备属性状态值大于AttriButeData1且小于AttriButeData2时触发动作 ///4:上报的设备属性状态值小于AttriButeData1或大于AttriButeData2时触发动作 ///5:上报的设备属性状态值和AttriButeData1进行与运算结果不为0时触发动作。(方便用于安防设备信息上报) ///特殊设备:如果为随心贴On/Off则填入 0。当接收到随心贴设备On/Off命令反馈将触发逻辑。 /// public int Range; } /// /// 任务数据 /// [System.Serializable] public class TaskListInfo { /// /// 任务类型。 ///1:开关 (设备具有开关功能时可用) ///3:亮度调整(设备具有亮度调节功能时可用) ///4:颜色调整 (设备具有颜色调节功能时可用) ///5:恒温器(设备具有恒温器功能时可用) ///6: 窗帘设备(设备具有窗帘功能时可用) ///7:设备identify识别。 ///8:开关报警模式 ///9:squawk command /// public int TaskType; /// /// Data1取值 /// 开关 :Data1(数值): 0关/1开 ///亮度调整 Data1(数值):亮度值 ///颜色调整 Data1(数值):色调 /// 恒温器 Data1(数值): 0加热/1制冷/2自动调节/3 设置工作模式/4 设置加热度数 5/设置制冷度数 6/设置风扇模式 /// 窗帘设备 Data1(数值): 0 打开/ 1关闭/ 2 停止转动/ 4 调整到指定高度/ 5 调整到指定的百分比处位置 / 7 调整到指定倾斜角/ 8 调整到指定的百分比倾斜度 /// 设备identify识别。Data1为identify闪烁闪烁时间(0-65535秒)。 /// 开关报警模式 Data1(数值,4字节整型)第1字节(bit0-bit7)表示报警模式,字节值0:停止蜂鸣器1:盗窃报警 2:火灾报警 3:紧急情况报警 4:警车发出的报警 5:消防车发出的报警 6:备用的报警。第2字节(bit8-bit15)表示是否启用报警灯,字节值 0:不启用 1:启用。第3字节(bit16-bit23)表示报警音量,字节值0:Low,1:Medium,2:high,3:very high。 /// squawk command Data1(数值,4字节整型)第1字节(bit0-bit7)表示报警模式,字节值0:安防系统“布防”音效” ,1:安防系统“撤防”音效。第2字节(bit8-bit15)表示是否启动报警灯,字节值0:不启动,1:启动。第3字节(bit16-bit23)表示报警音量,字节值0:Low ,1:Medium ,2:high ,3: very high。 /// public int Data1; /// /// Data2取值 /// 开关 Data2(数值): 0 /// 亮度调整 Data2(数值): 0 /// 颜色调整 Data2(数值):饱和度 /// 恒温器Data2数值如下: /// 【当Data1=0|1|2时,Data2为要变化的度数,单位:0.1℃ 。】 ///【若Data1=3,Data2为要设定的空调模式(0-9),0:off,1:auto,3:cool, 4:heat ,5:emergency heating, 6:precooling,7:fan only ,8:dry,9:sleep。】 ///【若Data1=4|5,Data2为加热或制冷度数,单位0.01摄氏度。】 ///【若Data1=6,Data2为要设定的风扇模式(0-6),0:off,1:low,2:medium,3:high,4:on,5:auto,6:smart】 ///窗帘设备,Data2数值如下 ///【当Data1=4或7,Data2为调整的高度或倾斜角度 倾斜角度单位为0.1°】。 ///【当Data1=5 或 8,Data2为百分比,0-100表示0%-100%】 ///设备identify识别。Data2(数值): 0 ///开关报警模式 Data2(数值,4字节整型)第1、2字节(bit0-bit15)表示报警时长,字节值 0-65535,单位:秒。第3字节(bit16-bit23)表示闪烁占空比,字节值0-100。第4字节(bit16-bit23)表示报警灯亮度,字节值0:Low ,1:Medium ,2:high ,3: very high。 ///squawk command:Data2(数值): 0 /// /// The type of the task. public int Data2; } /// ///条件类型 ///0:时间点条件,在某个时间发生 ///1:设备状态变化条件 ///2:其他逻辑条件 ///3:计数器条件 ///4:倒计时 ///5:时间段条件 /// public enum ConditionType { /// ///时间点条件,在某个时间发生 /// Time = 0, /// ///设备状态变化条件 /// Device = 1, /// ///其他逻辑条件 /// Logic = 2, /// ///计数器条件 /// Counter = 3, /// ///倒计时 /// CountDown = 4, /// ///条件类型 ///时间段条件 /// TimeBucket = 5, } #endregion //public static string LogistFile = "LogistFile"; //public void SaveLogicObj(string logicFilePath) //{ // Shared.IO.FileUtils.WriteFileByBytes(logicFilePath, Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(this))); //} ///// ///// 根据逻辑路径恢复逻辑对象 ///// logicFilePath命名:"Logic" + LogicId; ///// //public static Logic GetLogicByFilePath(string logicFilePath) //{ // try // { // return Newtonsoft.Json.JsonConvert.DeserializeObject(System.Text.Encoding.UTF8.GetString(Shared.IO.FileUtils.ReadFile(logicFilePath))); // } // catch // { // return new Logic(); // } //} } }