HDL Home App 第二版本 旧平台金堂用 正在使用
hxb
2022-08-30 25429f085093d89d543a0b90e30d0d62d1b7dac9
ZigbeeApp/Shared/Phone/UserCenter/CommonBase/Logic/HdlDeviceCurtainLogic.cs
New file
@@ -0,0 +1,477 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Shared.Phone.TemplateData;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using ZigBee.Device;
namespace Shared.Phone.UserCenter
{
    /// <summary>
    /// 窗帘的逻辑
    /// </summary>
    public class HdlDeviceCurtainLogic
    {
        #region ■ 变量声明___________________________
        /// <summary>
        /// 窗帘的逻辑
        /// </summary>
        private static HdlDeviceCurtainLogic m_Current = null;
        /// <summary>
        /// 窗帘的逻辑
        /// </summary>
        public static HdlDeviceCurtainLogic Current
        {
            get
            {
                if (m_Current == null)
                {
                    m_Current = new HdlDeviceCurtainLogic();
                }
                return m_Current;
            }
        }
        #endregion
        #region ■ 手拉控制___________________________
        /// <summary>
        /// 设置手拉控制状态值 ☆☆☆☆☆
        /// </summary>
        /// <param name="device">窗帘对象</param>
        /// <param name="bolStatu">手拉控制状态值</param>
        /// <returns></returns>
        public bool SetHandPullControl(CommonDevice device, bool bolStatu)
        {
            //如果是虚拟住宅
            if (Common.Config.Instance.Home.IsVirtually == true)
            {
                //添加缓存
                TemplateDeviceDataLogic.Current.SetCurtainHandPullControl(device, bolStatu, null);
                return true;
            }
            //获取发送的命令字符
            var sendData = this.GetHandPullControlText(device.DeviceAddr, device.DeviceEpoint, bolStatu);
            //发送给网关
            var result = HdlDeviceCommonLogic.Current.SendJobjectDataToGateway(device, "SetWritableValue", sendData, "SetWritableValue_Respon");
            if (result.ErrorMsg != null)
            {
                this.ShowTipMsg(result.ErrorMsg);
                return false;
            }
            if (result.ErrorMsgDiv == 0)
            {
                //切换手拉控制失败
                string msg = Language.StringByID(R.MyInternationalizationString.uChangeHandPullControlFail);
                //拼接上【网关回复超时】的Msg
                msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, result);
                this.ShowTipMsg(msg);
                return false;
            }
            var data = JsonConvert.DeserializeObject<CommonDevice.SetWritableValueResponData>(result.ReceiptData);
            if (data.Status != 0)
            {
                //切换手拉控制失败
                string msg = Language.StringByID(R.MyInternationalizationString.uChangeHandPullControlFail);
                this.ShowTipMsg(msg);
                return false;
            }
            //添加缓存
            TemplateDeviceDataLogic.Current.SetCurtainHandPullControl(device, bolStatu, result.JsonData[0]);
            return true;
        }
        /// <summary>
        /// 获取更改手拉控制状态的字符串命令 ☆☆☆☆☆
        /// </summary>
        /// <param name="DeviceAddr">DeviceAddr</param>
        /// <param name="DeviceEpoint">DeviceEpoint</param>
        /// <param name="bolStatu">手拉控制状态值</param>
        /// <returns></returns>
        public string GetHandPullControlText(string DeviceAddr, int DeviceEpoint, bool bolStatu)
        {
            int bit2 = bolStatu == true ? 1 : 0;
            int attributeData = bit2 * 4;
            var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", DeviceEpoint }, { "Cluster_ID", 258 }, { "Command", 120 } };
            var data = new JObject { { "Undivided", 0 }, { "AttributeId", 23 }, { "AttributeDataType", 24 }, { "AttributeData", attributeData } };
            jObject.Add("Data", data);
            return jObject.ToString();
        }
        #endregion
        #region ■ 窗帘方向配置_______________________
        /// <summary>
        /// 配置窗帘的方向
        /// </summary>
        /// <param name="rollershade">窗帘对象</param>
        /// <param name="bolStatu">false:电机方向正向;true:电机方向反向</param>
        /// <returns></returns>
        public bool SetCurtainDirection(CommonDevice rollershade, bool bolStatu)
        {
            var result = this.SetCurtainDirectionAsync(rollershade, bolStatu);
            //检测网关返回的共通错误状态码
            string error = HdlCheckLogic.Current.CheckCommonErrorCode(result);
            if (error != null)
            {
                this.ShowTipMsg(error);
                return false;
            }
            if (result == null || result.setWritableValueResponData == null)
            {
                //窗帘方向设置失败
                string msg = Language.StringByID(R.MyInternationalizationString.uSetCurtainDirectionFail);
                //拼接上【网关回复超时】的Msg
                msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, result);
                this.ShowTipMsg(msg);
                return false;
            }
            if (result.setWritableValueResponData.Status != 0)
            {
                //窗帘方向设置失败
                string msg = Language.StringByID(R.MyInternationalizationString.uSetCurtainDirectionFail);
                this.ShowTipMsg(msg);
                return false;
            }
            return true;
        }
        /// <summary>
        /// 设置开合帘电机方向
        /// <para>isDirectionReversed (false:电机方向正向;true:电机方向反向;)</para> .
        /// </summary>
        private CommonDevice.SetWritableValueResponAllData SetCurtainDirectionAsync(CommonDevice device, bool isDirectionReversed)
        {
            //如果当前是虚拟住宅
            if (Common.Config.Instance.Home.IsVirtually == true)
            {
                return TemplateDeviceDataLogic.Current.SetCurtainDirection(device, isDirectionReversed, null);
            }
            //获取编辑窗帘方向的命令字符
            var sendData = this.GetCurtainDirectionCommadText(device.DeviceAddr, device.DeviceEpoint, isDirectionReversed);
            var result = HdlDeviceCommonLogic.Current.SendJobjectDataToGateway(device, "SetWritableValue", sendData, "SetWritableValue_Respon");
            if (result.ErrorMsg != null || result.ErrorMsgDiv == 0)
            {
                return null;
            }
            //添加缓存
            TemplateDeviceDataLogic.Current.SetCurtainDirection(device, isDirectionReversed, result.JsonData[0]);
            var tempData = JsonConvert.DeserializeObject<CommonDevice.SetWritableValueResponData>(result.ReceiptData);
            return new CommonDevice.SetWritableValueResponAllData { setWritableValueResponData = tempData };
        }
        /// <summary>
        /// 获取编辑窗帘方向的命令字符
        /// </summary>
        /// <param name="DeviceAddr"></param>
        /// <param name="DeviceEpoint"></param>
        /// <param name="isDirectionReversed"></param>
        /// <returns></returns>
        public string GetCurtainDirectionCommadText(string DeviceAddr,int DeviceEpoint, bool isDirectionReversed)
        {
            int bit0 = isDirectionReversed == true ? 1 : 0;
            int attributeData = bit0 * 1;
            var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", DeviceEpoint }, { "Cluster_ID", 258 }, { "Command", 120 } };
            var data = new JObject { { "Undivided", 0 }, { "AttributeId", 23 }, { "AttributeDataType", 24 }, { "AttributeData", attributeData } };
            jObject.Add("Data", data);
            return jObject.ToString();
        }
        #endregion
        #region ■ 开合帘限位配置_____________________
        /// <summary>
        /// 设置开合帘限位
        /// </summary>
        /// <param name="rollershade"></param>
        /// <param name="upLimit">开限位</param>
        /// <param name="downLimit">合限位</param>
        /// <param name="curtainLength">导轨长度(这个是给虚拟设备用的)</param>
        /// <returns></returns>
        public bool SetAutoOpenCurtainLimitPoint(CommonDevice rollershade, int upLimit, int downLimit, int curtainLength)
        {
            //如果当前是虚拟住宅
            if (Common.Config.Instance.Home.IsVirtually == true)
            {
                return TemplateData.TemplateDeviceDataLogic.Current.SetCurtainLimitPoint(rollershade, upLimit, downLimit, curtainLength, null);
            }
            //获取编辑开合帘限位的命令字符
            var sendData = this.GetAutoOpenCurtainLimitPointCommandText(rollershade.DeviceAddr, rollershade.DeviceEpoint, upLimit, downLimit);
            var result = HdlDeviceCommonLogic.Current.SendJobjectDataToGateway(rollershade, "SetWritableValue", sendData, "SetWritableValue_Respon");
            if (result.ErrorMsg != null || result.ErrorMsgDiv == 0)
            {
                //设置窗帘限位点失败
                string msg = Language.StringByID(R.MyInternationalizationString.uCommitCurtainLimitFail);
                //拼接上【网关回复超时】的Msg
                msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, result);
                this.ShowTipMsg(msg);
                return false;
            }
            var tempData = Newtonsoft.Json.JsonConvert.DeserializeObject<CommonDevice.SetWritableValueResponData>(result.ReceiptData);
            if (tempData.Status != 0)
            {
                //设置窗帘限位点失败
                string msg = Language.StringByID(R.MyInternationalizationString.uCommitCurtainLimitFail);
                this.ShowTipMsg(msg);
                return false;
            }
            //添加缓存
            TemplateDeviceDataLogic.Current.SetCurtainLimitPoint(rollershade, upLimit, downLimit, curtainLength, result.JsonData[0]);
            return true;
        }
        /// <summary>
        /// 获取编辑开合帘限位的命令字符
        /// </summary>
        /// <param name="DeviceAddr"></param>
        /// <param name="DeviceEpoint"></param>
        /// <param name="upLimit"></param>
        /// <param name="downLimit"></param>
        /// <returns></returns>
        public string GetAutoOpenCurtainLimitPointCommandText(string DeviceAddr, int DeviceEpoint, int upLimit, int downLimit)
        {
            //这个是开合帘 "2,0x00ff,0x00ff"格式 合限位在前,开限位在后
            string convertData = "\"2,0x" + Convert.ToString(downLimit, 16).PadLeft(4, '0');
            convertData += ",0x" + Convert.ToString(upLimit, 16).PadLeft(4, '0') + "\"";
            //然后将它们转为ASK码数值,然后再转为16进制
            //总计长度为17(这里是16进制)
            string sendData = "11";
            foreach (char c in convertData)
            {
                sendData += Convert.ToString((int)c, 16).PadLeft(2, '0');
            }
            var jObject = new JObject { { "DeviceAddr", DeviceAddr }, { "Epoint", DeviceEpoint }, { "Cluster_ID", 258 }, { "Command", 120 } };
            var data = new JObject { { "Undivided", 0 }, { "AttributeId", 24 }, { "AttributeDataType", 65 }, { "AttributeData", sendData } };
            jObject.Add("Data", data);
            return jObject.ToString();
        }
        #endregion
        #region ■ 窗帘限位配置_______________________
        /// <summary>
        /// 执行确认及覆盖窗帘限位点
        /// </summary>
        /// <param name="rollershade">窗帘对象</param>
        /// <param name="limiType">确认及覆盖上限位还是下限位</param>
        /// <param name="upLimit">上限位的值(长度值,不是百分比)</param>
        /// <param name="downLimit">下限位的值(长度值,不是百分比)</param>
        /// <returns></returns>
        public async Task<bool> CommitCurtainLimitPoint(Rollershade rollershade, Rollershade.CurtainPrivateInstalledLimi limiType, int upLimit, int downLimit)
        {
            CommonDevice.SetWritableValueResponAllData result = null;
            if (upLimit == -1 && downLimit == -1)
            {
                //这个是卷帘
                result = await rollershade.SetCurtainInstalledLimitAsync(limiType);
            }
            else
            {
                //这个是开合帘 "2,0x00ff,0x00ff"格式 合限位在前,开限位在后
                string convertData = "\"2,0x" + Convert.ToString(downLimit, 16).PadLeft(4, '0');
                convertData += ",0x" + Convert.ToString(upLimit, 16).PadLeft(4, '0') + "\"";
                //然后将它们转为ASK码数值,然后再转为16进制
                //总计长度为17(这里是16进制)
                string sendData = "11";
                foreach (char c in convertData)
                {
                    sendData += Convert.ToString((int)c, 16).PadLeft(2, '0');
                }
                //result = await HdlDeviceAttributeLogic.Current.WriteDeviceAttribute(rollershade, 258, 24, 65, sendData);
            }
            //检测网关返回的共通错误状态码
            string error = HdlCheckLogic.Current.CheckCommonErrorCode(result);
            if (error != null)
            {
                this.ShowTipMsg(error);
                return false;
            }
            if (result == null || result.setWritableValueResponData == null)
            {
                //设置窗帘限位点失败
                string msg = Language.StringByID(R.MyInternationalizationString.uCommitCurtainLimitFail);
                //拼接上【网关回复超时】的Msg
                msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, result);
                this.ShowTipMsg(msg);
                return false;
            }
            if (result.setWritableValueResponData.Status != 0)
            {
                //设置窗帘限位点失败
                string msg = Language.StringByID(R.MyInternationalizationString.uCommitCurtainLimitFail);
                this.ShowTipMsg(msg);
                return false;
            }
            return true;
        }
        /// <summary>
        /// 删除限位点
        /// </summary>
        /// <param name="rollershade">窗帘对象</param>
        /// <param name="limiType">删除上限位还是删除下限位</param>
        /// <returns></returns>
        public async Task<bool> DeleteCurtainLimitPoint(Rollershade rollershade, Rollershade.LimiType limiType)
        {
            var result = await rollershade.DeleteCurtainLimitsAsync(limiType);
            //检测网关返回的共通错误状态码
            string error = HdlCheckLogic.Current.CheckCommonErrorCode(result);
            if (error != null)
            {
                this.ShowTipMsg(error);
                return false;
            }
            if (result == null || result.setWritableValueResponData == null)
            {
                //重置窗帘限位点失败
                string msg = Language.StringByID(R.MyInternationalizationString.uDeleteCurtainLimitFail);
                //拼接上【网关回复超时】的Msg
                msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, result);
                this.ShowTipMsg(msg);
                return false;
            }
            if (result.setWritableValueResponData.Status != 0)
            {
                //重置窗帘限位点失败
                string msg = Language.StringByID(R.MyInternationalizationString.uDeleteCurtainLimitFail);
                this.ShowTipMsg(msg);
                return false;
            }
            return true;
        }
        #endregion
        #region ■ 获取窗帘限位配置___________________
        /// <summary>
        /// 发送获取窗帘限位配置的命令
        /// </summary>
        /// <param name="rollershade">窗帘对象</param>
        public void SetGetCurtainLimitSettionComand(Rollershade rollershade)
        {
            var jObject = new Newtonsoft.Json.Linq.JObject
            {
                { "DeviceAddr",rollershade.DeviceAddr },
                { "Epoint", rollershade.DeviceEpoint },
                { "Cluster_ID", (int)Cluster_ID.WindowCovering },
                { "Command", 108 }
            };
            var attriBute = new Newtonsoft.Json.Linq.JArray
            {
               new Newtonsoft.Json.Linq.JObject
               {
                 //开合帘方向
                 { "AttriButeId", (int)AttriButeId.WindowCoveringMode}
               },
               new Newtonsoft.Json.Linq.JObject
               {
                 //开合帘总长
                 { "AttriButeId", (int)AttriButeId.WindowCoveringLength}
               },
               new Newtonsoft.Json.Linq.JObject
               {
                 //开限位
                 { "AttriButeId", (int)AttriButeId.InstalledOpenLimitLift}
               },
               new Newtonsoft.Json.Linq.JObject
               {
                 //合限位
                 { "AttriButeId", (int)AttriButeId.InstalledClosedLimitLift}
               }
            };
            var data = new Newtonsoft.Json.Linq.JObject { { "AttriBute", attriBute } };
            jObject.Add("Data", data);
            rollershade.Gateway?.Send(("GetDeviceStatus"), jObject.ToString());
        }
        #endregion
        #region ■ 重置窗帘___________________________
        /// <summary>
        /// 重置窗帘
        /// </summary>
        /// <param name="rollershade">窗帘对象</param>
        /// <returns></returns>
        public async Task<bool> RestoreCurtain(Rollershade rollershade)
        {
            var result = await rollershade.RestoreCurtainLimitAsync();
            //检测网关返回的共通错误状态码
            string error = HdlCheckLogic.Current.CheckCommonErrorCode(result);
            if (error != null)
            {
                this.ShowTipMsg(error);
                return false;
            }
            if (result == null || result.setWritableValueResponData == null)
            {
                //重置窗帘失败
                string msg = Language.StringByID(R.MyInternationalizationString.uRestoreCurtainFail);
                //拼接上【网关回复超时】的Msg
                msg = UserCenterLogic.CombineGatewayTimeOutMsg(msg, result);
                this.ShowTipMsg(msg);
                return false;
            }
            if (result.setWritableValueResponData.Status != 0)
            {
                //重置窗帘失败
                string msg = Language.StringByID(R.MyInternationalizationString.uRestoreCurtainFail);
                this.ShowTipMsg(msg);
                return false;
            }
            return true;
        }
        #endregion
        #region ■ 一般方法___________________________
        /// <summary>
        /// 显示错误信息窗口
        /// </summary>
        /// <param name="msg"></param>
        private void ShowErrorMsg(string msg)
        {
            Application.RunOnMainThread(() =>
            {
                var contr = new ShowMsgControl(ShowMsgType.Error, msg);
                contr.Show();
            });
        }
        /// <summary>
        /// 显示Tip信息窗口
        /// </summary>
        /// <param name="msg"></param>
        private void ShowTipMsg(string msg)
        {
            Application.RunOnMainThread(() =>
            {
                var contr = new ShowMsgControl(ShowMsgType.Tip, msg);
                contr.Show();
            });
        }
        #endregion
    }
}