gxc
2019-11-07 a4924de3136289d10cabbf2f61a228387d44ded7
ZigbeeApp/Shared/Phone/UserCenter/Device/Curtain/RollerShadeDirectionLimitSettingForm.cs
New file
@@ -0,0 +1,1020 @@
using System;
using System.Collections.Generic;
using Shared.Common;
using Shared.Phone.UserView;
using ZigBee.Device;
namespace Shared.Phone.UserCenter.DeviceCurtain
{
    /// <summary>
    /// 卷帘设置反向与限位
    /// </summary>
    public class RollerShadeDirectionLimitSettingForm: EditorCommonForm,ZigBee.Common.IStatus
    {
        #region ◆ 设备接口__________________________
        /// <summary>
        /// Changed the specified common.
        /// </summary>
        /// <param name="common">Common.</param>
        public void Changed(CommonDevice common)
        {
            //throw new NotImplementedException();
        }
        /// <summary>
        /// 设备状态更新接口
        /// <para>type:如果为 DeviceInComingRespon:设备新上报</para>
        /// <para>type:如果为 IASInfoReport:RemoveDeviceRespon</para>
        /// <para>type:如果为 DeviceStatusReport:设备上报</para>
        /// <para>type:如果为 IASInfoReport:IAS安防信息上报</para>
        /// <para>type:如果为 OnlineStatusChange: 设备在线状态更新</para>
        /// </summary>
        /// <param name="common">Common.</param>
        /// <param name="typeTag">Type tag.</param>
        public void DeviceInfoChange(CommonDevice common, string typeTag)
        {
            if (typeTag == "DeviceStatusReport")
            {
                Application.RunOnMainThread(() =>
                {
                    try
                    {
                        var device = listRollershade[0];
                        //是否为当前设备
                        if (device.DeviceEpoint != common.DeviceEpoint || device.DeviceAddr != common.DeviceAddr)
                        {
                            return;
                        }
                        if ((common as Rollershade).DeviceStatusReport == null || (common as Rollershade).DeviceStatusReport.CluterID != 258)
                        {
                            return;
                        }
                        var attriButeList = (common as Rollershade).DeviceStatusReport.AttriBute;
                        if(attriButeList==null ||  attriButeList.Count==0)
                        {
                            return;
                        }
                        switch (attriButeList[0].AttributeId)
                        {
                            case 0:
                                //类型
                                rollershade.DeviceStatusReport = (common as Rollershade).DeviceStatusReport;
                                rollershade.WcdType = attriButeList[0].AttriButeData;
                                rollershade.LastDateTime = DateTime.Now;
                                break;
                            case 1:
                                //总长
                                rollershade.DeviceStatusReport = (common as Rollershade).DeviceStatusReport;
                                rollershade.WcdCurrentLength = attriButeList[0].AttriButeData;
                                windowCurrentLength = rollershade.WcdCurrentLength;
                                rollershade.LastDateTime = DateTime.Now;
                                break;
                            case 23:
                                //方向
                                rollershade.DeviceStatusReport = (common as Rollershade).DeviceStatusReport;
                                if (0 < (attriButeList[0].AttriButeData & 0x01))
                                {
                                    //电机反向
                                    rollershade.WcdCurrentDirection = true;
                                    directionBtn.TextID = R.MyInternationalizationString.ReverseDirection;
                                }
                                else
                                {
                                    //电机正向
                                    rollershade.WcdCurrentDirection = false;
                                    directionBtn.TextID = R.MyInternationalizationString.ForwardDirection;
                                }
                                rollershade.LastDateTime = DateTime.Now;
                                break;
                            case 16:
                                //上限位
                                rollershade.DeviceStatusReport = (common as Rollershade).DeviceStatusReport;
                                if (windowCurrentLength != 0)
                                {
                                    rollershade.WcdCurrentWcdInstalOpenLimit = attriButeList[0].AttriButeData;
                                    startSeekBar.Progress = (int)(rollershade.WcdCurrentWcdInstalOpenLimit / (windowCurrentLength * 1.0) * 100);
                                    startBtn.Text = $"{Language.StringByID(R.MyInternationalizationString.SetStartLimit)} : {startSeekBar.Progress}%";
                                    rollershade.LastDateTime = DateTime.Now;
                                }
                                break;
                            case 17:
                                //下限位
                                rollershade.DeviceStatusReport = (common as Rollershade).DeviceStatusReport;
                                if (windowCurrentLength != 0)
                                {
                                    rollershade.WcdCurrentInstalCloseLimit = attriButeList[0].AttriButeData;
                                    endSeekBar.Progress = (int)(rollershade.WcdCurrentInstalCloseLimit / (windowCurrentLength * 1.0) * 100);
                                    endBtn.Text = $"{Language.StringByID(R.MyInternationalizationString.SetEndLimit)} : {endSeekBar.Progress}%";
                                    rollershade.LastDateTime = DateTime.Now;
                                }
                                break;
                            case 8:
                                //窗帘百分比
                                //发送设置上限位
                                //发送设置下限位
                                rollershade.DeviceStatusReport = (common as Rollershade).DeviceStatusReport;
                                rollershade.LastDateTime = DateTime.Now;
                                rollershade.WcdCurrentPositionLiftPercentage= attriButeList[0].AttriButeData;
                                System.Console.WriteLine($"收到了回复:{rollershade.WcdCurrentPositionLiftPercentage}  {startSeekBar.Progress} {endSeekBar.Progress}");
                                if (canSetStartLimit && System.Math.Abs(rollershade.WcdCurrentPositionLiftPercentage - startSeekBar.Progress) < 5)
                                {
                                    hadReceivedStartEndLimitCode = true;
                                    CommonPage.Loading.Hide();
                                    var alert = new Alert(Language.StringByID(R.MyInternationalizationString.TIP), Language.StringByID(R.MyInternationalizationString.SettingStartLimit), Language.StringByID(R.MyInternationalizationString.Cancel), Language.StringByID(R.MyInternationalizationString.Confrim));
                                    alert.Show();
                                    alert.ResultEventHandler += async (sender2, e2) =>
                                    {
                                        if (e2)
                                        {
                                            try
                                            {
                                                CommonPage.Loading.Start();
                                                var status = await SetLimitAsync(Rollershade.CurtainPrivateInstalledLimi.UpLimit, rollershade);
                                                if (status == 0)
                                                {
                                                    System.Console.WriteLine("上行程设置成功");
                                                    this.ShowMassage(ShowMsgType.Tip, Language.StringByID(R.MyInternationalizationString.Success));
                                                }
                                                else if (status == -1)
                                                {
                                                    CommonPage.Instance.ShowErrorInfoAlert(R.MyInternationalizationString.ConnectGWFail);
                                                }
                                                else
                                                {
                                                    CommonPage.Instance.ShowErrorInfoAlert(R.MyInternationalizationString.FAIL);
                                                }
                                            }
                                            catch (Exception ex)
                                            {
                                                System.Console.WriteLine($"设置上限位失败{ex.Message}");
                                            }
                                            finally
                                            {
                                                CommonPage.Loading.Hide();
                                            }
                                        }
                                    };
                                }
                                if (canSetEndLimit && System.Math.Abs(rollershade.WcdCurrentPositionLiftPercentage - endSeekBar.Progress) < 5)
                                {
                                    hadReceivedStartEndLimitCode = true;
                                    CommonPage.Loading.Hide();
                                    var alert = new Alert(Language.StringByID(R.MyInternationalizationString.TIP), Language.StringByID(R.MyInternationalizationString.SettingEndLimit), Language.StringByID(R.MyInternationalizationString.Cancel), Language.StringByID(R.MyInternationalizationString.Confrim));
                                    alert.Show();
                                    alert.ResultEventHandler += async (sender2, e2) =>
                                    {
                                        if (e2)
                                        {
                                            try
                                            {
                                                CommonPage.Loading.Start();
                                                var status = await SetLimitAsync(Rollershade.CurtainPrivateInstalledLimi.DownLimit, rollershade);
                                                if (status == 0)
                                                {
                                                    System.Console.WriteLine("下行程设置成功");
                                                    this.ShowMassage(ShowMsgType.Tip, Language.StringByID(R.MyInternationalizationString.Success));
                                                }
                                                else if (status == -1)
                                                {
                                                    CommonPage.Instance.ShowErrorInfoAlert(R.MyInternationalizationString.ConnectGWFail);
                                                }
                                                else
                                                {
                                                    CommonPage.Instance.ShowErrorInfoAlert(R.MyInternationalizationString.FAIL);
                                                }
                                            }
                                            catch (Exception ex)
                                            {
                                                System.Console.WriteLine($"设置下限位失败{ex.Message}");
                                            }
                                            finally
                                            {
                                                CommonPage.Loading.Hide();
                                            }
                                        }
                                    };
                                }
                                break;
                        }
                    }
                    catch (Exception ex)
                    {
                        System.Console.WriteLine($"Error:{ex.Message}");
                    }
                });
            }
        }
        /// <summary>
        /// Changeds the IL ogic status.
        /// </summary>
        /// <param name="logic">Logic.</param>
        public void ChangedILogicStatus(ZigBee.Device.Logic logic)
        {
            //throw new NotImplementedException();
        }
        /// <summary>
        /// Changeds the IS cene status.
        /// </summary>
        /// <param name="scene">Scene.</param>
        public void ChangedISceneStatus(Scene scene)
        {
            //throw new NotImplementedException();
        }
        #endregion
        #region ◆ 变量_____________________________
        /// <summary>
        /// 设置方向与限位的设备--窗帘
        /// </summary>
        private List<CommonDevice> listRollershade = null;
        /// <summary>
        /// The rollershade.
        /// </summary>
        private Rollershade rollershade = null;
        /// <summary>
        /// 起始方向btn
        /// </summary>
        private NormalViewControl directionBtn = null;
        /// <summary>
        /// 设置开始的限位的滑条
        /// </summary>
        private HorizontalSeekBar startSeekBar = null;
        /// <summary>
        /// 设置限位的开始百分比按钮
        /// </summary>
        private Button startBtn = null;
        /// <summary>
        /// 设置结束限位的滑条
        /// </summary>
        private HorizontalSeekBar endSeekBar = null;
        /// <summary>
        /// 设置限位的结束百分比按钮
        /// </summary>
        private Button endBtn = null;
        //延时 300毫秒
        private readonly double sleepSpan = 0.3;
        /// <summary>
        /// 是否可以发送设置上限位命令了
        /// </summary>
        private bool canSetStartLimit = false;
        /// <summary>
        /// 接口中是否收到了设置开始\结束限位的导轨移动的百分比
        /// </summary>
        private bool hadReceivedStartEndLimitCode = false;
        /// <summary>
        /// 是否可以发送设置结束限位命令了
        /// </summary>
        ///
        private bool canSetEndLimit = false;
        /// <summary>
        /// 窗帘总长
        /// </summary>
        private int windowCurrentLength = 0;
        /// <summary>
        /// 设置限位的线程列表
        /// </summary>
        static List<System.Threading.Thread> threads = new List<System.Threading.Thread> { };
        #endregion
        #region ◆ 构造方法__________________________
        /// <summary>
        /// 构造方法
        /// </summary>
        public RollerShadeDirectionLimitSettingForm()
        {
            UserView.HomePage.Instance.ScrollEnabled = false;
            ZigBee.Device.ZbGateway.StatusList.Add(this);
        }
        #endregion
        #region ◆ 关闭界面__________________________
        /// <summary>
        /// 画面关闭
        /// </summary>
        public override void CloseForm()
        {
            UserView.HomePage.Instance.ScrollEnabled = true;
            ZigBee.Device.ZbGateway.StatusList.Remove(this);
            base.CloseForm();
        }
        #endregion
        #region ◆ 显示界面__________________________
        /// <summary>
        /// 画面显示(底层会固定调用此方法,借以完成画面创建)
        /// </summary>
        /// <param name="i_listdevice">设备</param>
        public void ShowForm(List<CommonDevice> i_listdevice)
        {
            if(i_listdevice==null || i_listdevice.Count==0)
            {
                return;
            }
            this.listRollershade = i_listdevice;
            this.rollershade = listRollershade[0] as Rollershade;
            //设置标题信息
            base.SetTitleText(Language.StringByID(R.MyInternationalizationString.DirectionLimit));
            //初始化中部控件
            this.InitMiddleFrame();
        }
        #endregion
        #region ◆ 初始化中部控件_____________________
        /// <summary>
        /// 初始化中部控件
        /// </summary>
        private void InitMiddleFrame()
        {
            bodyFrameLayout.RemoveAll();
            var listview = new VerticalScrolViewLayout();
            listview.ScrollEnabled = false;
            bodyFrameLayout.AddChidren(listview);
            //读取状态
            InitReadStatu();
            //起始方向
            AddinitialDirectionRow(listview);
            //限位
            AddDirectionLimitRow(listview);
            //恢复行程设置
            AddRestoreTravelSettingsRow(listview);
        }
        #endregion
        #region ◆ 读取状态__________________________
        /// <summary>
        /// 读取状态
        /// </summary>
        private void InitReadStatu()
        {
            //不上非远程
            if (rollershade.Gateway == null)
            {
                return;
            }
            UserHomeView.ReadStatus(rollershade, () =>
            {
                rollershade.ReadWcdType();
                rollershade.ReadWcdLength();
                rollershade.ReadCurtainDirectionAndMode();
                rollershade.ReadWcdInstalOpenLimit();
                rollershade.ReadWcdInstalCloseLimit();
            }, 1);
        }
        #endregion
        #region ◆ 添加 【起始方向】行_________________
        /// <summary>
        /// 添加 【起始方向】行
        /// </summary>
        /// <param name="listview">Lisrview.</param>
        private void AddinitialDirectionRow(VerticalScrolViewLayout listview)
        {
            var initialDirectionRow = new RowLayoutControl();
            listview.AddChidren(initialDirectionRow);
            var initialDirectionBtn = initialDirectionRow.frameTable.AddLeftCaption("", 900);
            initialDirectionBtn.TextID = R.MyInternationalizationString.InitialDirection;
            initialDirectionRow.frameTable.AddRightArrow();
            directionBtn = initialDirectionRow.frameTable.AddMostRightView("", 300);
            directionBtn.TextID = rollershade.WcdCurrentDirection == false ? R.MyInternationalizationString.ForwardDirection : R.MyInternationalizationString.ReverseDirection;
            directionBtn.TextColor = UserCenterColor.Current.TextGrayColor;
            initialDirectionRow.frameTable.ButtonClickEvent +=  (sender, e) =>
            {
                try
                {
                    CommonPage.Loading.Start();
                    System.Console.WriteLine("方向");
                    var list = new List<string> { };
                    list.Add(Language.StringByID(R.MyInternationalizationString.ForwardDirection));
                    list.Add(Language.StringByID(R.MyInternationalizationString.ReverseDirection));
                    PickerView.Show(list, async (obj) =>
                    {
                        directionBtn.Text = list[obj];
                        bool direction = directionBtn.Text.Trim() == Language.StringByID(R.MyInternationalizationString.ReverseDirection);
                        var setWritableValueResponAllData = await rollershade.SetCurtainDirectionAsync(direction);
                        if (setWritableValueResponAllData == null || setWritableValueResponAllData.setWritableValueResponData == null)
                        {
                            CommonPage.Loading.Hide();
                            Shared.Common.CommonPage.Instance.ShowErrorInfoAlert(R.MyInternationalizationString.ConnectGWFail);
                            return;
                        }
                        var status = setWritableValueResponAllData.setWritableValueResponData.Status;
                        //以后补充提示
                        //0:配置成功(若配置成功,下面的AttributeId字段不存在)
                        //34:不支持该属性
                        //135:无效的属性值
                        //141:无效的数据类型
                        if (status == 0)
                        {
                            System.Console.WriteLine("设置方向成功");
                            rollershade.WcdCurrentDirection = direction;
                        }
                        else
                        {
                            CommonPage.Loading.Hide();
                            Shared.Common.CommonPage.Instance.ShowErrorInfoAlert(R.MyInternationalizationString.FAIL);
                        }
                    }, 0, "", Language.StringByID(R.MyInternationalizationString.Confrim));
                }
                catch(Exception ex)
                {
                    System.Console.WriteLine($"设置方向行错误:{ex.Message}");
                }
                finally
                {
                    CommonPage.Loading.Hide();
                }
            };
        }
        #endregion
        #region ◆ 添加 【限位】行____________________
        /// <summary>
        /// 添加 【限位】行
        /// </summary>
        /// <param name="listview">Lisrview.</param>
        private void AddDirectionLimitRow(VerticalScrolViewLayout listview)
        {
            if(rollershade.WcdType==0)
            {
                AddDirectionLimitRowJL(listview);
            }
            else if(rollershade.WcdType==4)
            {
                AddDirectionLimitRowKHL(listview);
            }
        }
        /// <summary>
        /// 添加 卷帘【限位】行
        /// </summary>
        /// <param name="listview">Lisrview.</param>
        private void AddDirectionLimitRowJL(VerticalScrolViewLayout listview)
        {
            var directionLimitRow = new RowLayoutControl();
            directionLimitRow.Height = ControlCommonResourse.ListViewRowHeight;
            directionLimitRow.LineColor = ZigbeeColor.Current.GXCLineColor;
            listview.AddChidren(directionLimitRow);
            var directionLimitBtn = directionLimitRow.frameTable.AddLeftCaption("", 900);
            directionLimitBtn.TextID = R.MyInternationalizationString.Limit;
            directionLimitRow.AddChidren(directionLimitBtn);
            //方向与限位设置向右的图标
            //向右的图标
            var btnDirectionRight = new Button()
            {
                X = directionLimitRow.Width - Application.GetRealWidth(150),
                Height = Application.GetMinRealAverage(110),
                Width = Application.GetMinRealAverage(110),
                UnSelectedImagePath = "Item/Next.png",
                SelectedImagePath = "Item/DownSelected.png",
                Gravity = Gravity.CenterVertical
            };
            //btnDirectionRight.UnSelectedImagePath = "Item/Next.png";
            //btnDirectionRight.SelectedImagePath = "Item/Down.png";
            directionLimitRow.AddChidren(btnDirectionRight);
            var startLimitRowView = new FrameLayout()
            {
                Y = ControlCommonResourse.ListViewRowHeight,
                Height = ControlCommonResourse.ListViewRowHeight * 2,
                BackgroundColor = ZigbeeColor.Current.GXCBackgroundColor,
                Tag = "startEndLimitRowView"
            };
            directionLimitRow.AddChidren(startLimitRowView);
            var startLine = new Button()
            {
                Height = 1,
                BackgroundColor = ZigbeeColor.Current.GXCLineColor
            };
            startLimitRowView.AddChidren(startLine);
            startBtn = new Button()
            {
                Height = Application.GetRealHeight(80),
                X = Application.GetRealWidth(CommonPage.XLeft),
                Width = Application.GetRealWidth(500),
                TextColor = ZigbeeColor.Current.GXCTextBlueColor,
                TextAlignment = TextAlignment.CenterLeft,
                TextID = R.MyInternationalizationString.SetStartLimit,
                Gravity=Gravity.CenterVertical
            };
            startLimitRowView.AddChidren(startBtn);
            startBtn.MouseUpEventHandler += (sender, e) =>
            {
                rollershade.WcdGoToLiftValue(0);
            };
            var setStart = new Button()
            {
                Height = Application.GetRealHeight(80),
                X = Application.GetRealWidth(CommonPage.AppRealWidth-200-100),
                Width = Application.GetRealWidth(200),
                TextColor = ZigbeeColor.Current.GXCTextBlueColor,
                TextAlignment = TextAlignment.CenterRight,
                TextID = R.MyInternationalizationString.Confrim,
                Gravity = Gravity.CenterVertical
            };
            startLimitRowView.AddChidren(setStart);
            setStart.MouseUpEventHandler += async (sender, e) =>
            {
                var status = await SetLimitAsync(Rollershade.CurtainPrivateInstalledLimi.UpLimit, rollershade);
                if (status == 0)
                {
                    System.Console.WriteLine("下行程设置成功");
                    this.ShowMassage(ShowMsgType.Tip, Language.StringByID(R.MyInternationalizationString.Success));
                }
                else if (status == -1)
                {
                    CommonPage.Instance.ShowErrorInfoAlert(R.MyInternationalizationString.ConnectGWFail);
                }
                else
                {
                    CommonPage.Instance.ShowErrorInfoAlert(R.MyInternationalizationString.FAIL);
                }
            };
            var endLimitRowView = new FrameLayout()
            {
                Y = startLimitRowView.Bottom,
                Height = ControlCommonResourse.ListViewRowHeight * 2,
                BackgroundColor = ZigbeeColor.Current.GXCBackgroundColor,
                Tag = "startEndLimitRowView"
            };
            directionLimitRow.AddChidren(endLimitRowView);
            var endLine = new Button()
            {
                Height = 1,
                BackgroundColor = ZigbeeColor.Current.GXCLineColor
            };
            endLimitRowView.AddChidren(endLine);
            endBtn = new Button()
            {
                Height = Application.GetRealHeight(80),
                X = Application.GetRealWidth(CommonPage.XLeft),
                Width = Application.GetRealWidth(500),
                TextColor = ZigbeeColor.Current.GXCTextBlueColor,
                TextAlignment = TextAlignment.CenterLeft,
                TextID = R.MyInternationalizationString.SetEndLimit,
                Gravity = Gravity.CenterVertical
            };
            endLimitRowView.AddChidren(endBtn);
            endBtn.MouseUpEventHandler+=(sender, e) =>
            {
                rollershade.WcdGoToLiftValue(100);
            };
            var setEnd = new Button()
            {
                Height = Application.GetRealHeight(80),
                X = Application.GetRealWidth(CommonPage.AppRealWidth - 200 - 100),
                Width = Application.GetRealWidth(200),
                TextColor = ZigbeeColor.Current.GXCTextBlueColor,
                TextAlignment = TextAlignment.CenterRight,
                TextID = R.MyInternationalizationString.Confrim,
                Gravity = Gravity.CenterVertical
            };
            endLimitRowView.AddChidren(setEnd);
            setEnd.MouseUpEventHandler += async (sender, e) =>
            {
                var status = await SetLimitAsync(Rollershade.CurtainPrivateInstalledLimi.DownLimit, rollershade);
                if (status == 0)
                {
                    System.Console.WriteLine("下行程设置成功");
                    this.ShowMassage(ShowMsgType.Tip, Language.StringByID(R.MyInternationalizationString.Success));
                }
                else if (status == -1)
                {
                    CommonPage.Instance.ShowErrorInfoAlert(R.MyInternationalizationString.ConnectGWFail);
                }
                else
                {
                    CommonPage.Instance.ShowErrorInfoAlert(R.MyInternationalizationString.FAIL);
                }
            };
            void limit_MouseUpEvnet(object sender, MouseEventArgs mouseEventArgs)
            {
                btnDirectionRight.IsSelected = !btnDirectionRight.IsSelected;
                if (btnDirectionRight.IsSelected)
                {
                    directionLimitRow.Height = ControlCommonResourse.ListViewRowHeight * 5;
                }
                else
                {
                    directionLimitRow.Height = ControlCommonResourse.ListViewRowHeight;
                }
            }
            btnDirectionRight.MouseUpEventHandler += limit_MouseUpEvnet;
            directionLimitBtn.MouseUpEventHandler += limit_MouseUpEvnet;
            directionLimitRow.MouseUpEventHandler += limit_MouseUpEvnet;
        }
        /// <summary>
        /// 添加 开合帘【限位】行
        /// </summary>
        /// <param name="listview">Lisrview.</param>
        private void AddDirectionLimitRowKHL(VerticalScrolViewLayout listview)
        {
            var directionLimitRow = new RowLayoutControl();
            directionLimitRow.Height = ControlCommonResourse.ListViewRowHeight;
            directionLimitRow.LineColor = ZigbeeColor.Current.GXCLineColor;
            listview.AddChidren(directionLimitRow);
            var directionLimitBtn = directionLimitRow.frameTable.AddLeftCaption("", 900);
            directionLimitBtn.TextID = R.MyInternationalizationString.Limit;
            directionLimitRow.AddChidren(directionLimitBtn);
            //方向与限位设置向右的图标
            //向右的图标
            var btnDirectionRight = new Button()
            {
                X = directionLimitRow.Width - Application.GetRealWidth(150),
                Height = Application.GetMinRealAverage(110),
                Width = Application.GetMinRealAverage(110),
                UnSelectedImagePath = "Item/Next.png",
                SelectedImagePath = "Item/DownSelected.png",
                Gravity = Gravity.CenterVertical
            };
            //btnDirectionRight.UnSelectedImagePath = "Item/Next.png";
            //btnDirectionRight.SelectedImagePath = "Item/Down.png";
            directionLimitRow.AddChidren(btnDirectionRight);
            var startLimitRowView = new FrameLayout()
            {
                Y = ControlCommonResourse.ListViewRowHeight,
                Height = ControlCommonResourse.ListViewRowHeight * 2,
                BackgroundColor = ZigbeeColor.Current.GXCBackgroundColor,
                Tag = "startEndLimitRowView"
            };
            directionLimitRow.AddChidren(startLimitRowView);
            var startLine = new Button()
            {
                Height = 1,
                BackgroundColor = ZigbeeColor.Current.GXCLineColor
            };
            startLimitRowView.AddChidren(startLine);
            startSeekBar = new HorizontalSeekBar()
            {
                Height = Application.GetRealHeight(80),
                Width = Application.GetRealWidth(750),
                Gravity = Gravity.Center,
                ThumbColor = ZigbeeColor.Current.GXCButtonBlueColor,
                BackgroundColor = ZigbeeColor.Current.GXCSliderUnSelectedColor,
                ProgressColor = ZigbeeColor.Current.GXCButtonBlueColor,
                Max = 100,
                Progress = 0
            };
            startLimitRowView.AddChidren(startSeekBar);
            startBtn = new Button()
            {
                Y = Application.GetRealHeight(30),
                Height = Application.GetRealHeight(80),
                X = Application.GetRealWidth(CommonPage.XLeft),
                Width = Application.GetRealWidth(500),
                TextColor = ZigbeeColor.Current.GXCTextBlackColor,
                TextAlignment = TextAlignment.CenterLeft,
                Text = $"{Language.StringByID(R.MyInternationalizationString.SetStartLimit)} : {startSeekBar.Progress}%"
            };
            startLimitRowView.AddChidren(startBtn);
            var endLimitRowView = new FrameLayout()
            {
                Y = startLimitRowView.Bottom,
                Height = ControlCommonResourse.ListViewRowHeight * 2,
                BackgroundColor = ZigbeeColor.Current.GXCBackgroundColor,
                Tag = "startEndLimitRowView"
            };
            directionLimitRow.AddChidren(endLimitRowView);
            var endLine = new Button()
            {
                Height = 1,
                BackgroundColor = ZigbeeColor.Current.GXCLineColor
            };
            endLimitRowView.AddChidren(endLine);
            endSeekBar = new HorizontalSeekBar()
            {
                Y = endLine.Bottom,
                Height = Application.GetRealHeight(80),
                BackgroundColor = ZigbeeColor.Current.GXCSliderUnSelectedColor,
                Width = Application.GetRealWidth(750),
                Gravity = Gravity.Center,
                ThumbColor = ZigbeeColor.Current.GXCButtonBlueColor,
                ProgressColor = ZigbeeColor.Current.GXCButtonBlueColor,
                Max = 100,
                Progress = 100
            };
            endLimitRowView.AddChidren(endSeekBar);
            endBtn = new Button()
            {
                Y = Application.GetRealHeight(30),
                Height = Application.GetRealHeight(80),
                X = Application.GetRealWidth(CommonPage.XLeft),
                Width = Application.GetRealWidth(500),
                TextColor = ZigbeeColor.Current.GXCTextBlackColor,
                TextAlignment = TextAlignment.CenterLeft,
                Text = $"{Language.StringByID(R.MyInternationalizationString.SetEndLimit)} : {endSeekBar.Progress}%"
            };
            endLimitRowView.AddChidren(endBtn);
            bool isStartSendDelayFrist = false;
            bool isEndSendDelayFrist = false;
            DateTime lastStartSendDelayTime = DateTime.Now;
            DateTime lastEndSendDelayTime = DateTime.Now;
            startSeekBar.ProgressChanged += async (sender1, e1) =>
            {
                canSetStartLimit = false;
                startBtn.Text = $"{Language.StringByID(R.MyInternationalizationString.SetStartLimit)} : {startSeekBar.Progress}%";
                if (isStartSendDelayFrist == false)
                {
                    isStartSendDelayFrist = true;
                    //先发送删除限位点命令
                    var t = await DeleteUpLimitAsync(rollershade);
                    endBtn.Text = $"{Language.StringByID(R.MyInternationalizationString.SetEndLimit)} : {endSeekBar.Progress}%";
                    rollershade.WcdGoToTiltValue(startSeekBar.Progress);
                    lastStartSendDelayTime = DateTime.Now;
                }
                else
                {
                    if ((DateTime.Now - lastStartSendDelayTime).TotalSeconds > sleepSpan)
                    {
                        rollershade.WcdGoToTiltValue(startSeekBar.Progress);
                        lastStartSendDelayTime = DateTime.Now;
                    }
                }
            };
            startSeekBar.MouseUpEventHandler += (sender1, e1) =>
            {
                isStartSendDelayFrist = false;
                canSetStartLimit = true;
                hadReceivedStartEndLimitCode = false;
                rollershade.WcdGoToTiltValue(startSeekBar.Progress);
                lastStartSendDelayTime = DateTime.Now;
                CommonPage.Loading.Start(Language.StringByID(R.MyInternationalizationString.PleaseWaitWhileTheGuidewayIsMoving));
                DeviceDelayAction(rollershade, (hadReceived) =>
                {
                    Application.RunOnMainThread(() =>
                    {
                        if (hadReceived == false)
                        {
                            this.ShowMassage(ShowMsgType.Tip, Language.StringByID(R.MyInternationalizationString.FailedPleaseTryAgain));
                        }
                        else
                        {
                            //var tip = new TipViewControl(Language.StringByID(R.MyInternationalizationString.Success));
                            //tip.ShowView();
                        }
                        CommonPage.Loading.Hide();
                    });
                }, 5);
            };
            endSeekBar.ProgressChanged += async (sender1, e1) =>
            {
                canSetEndLimit = false;
                endBtn.Text = $"{Language.StringByID(R.MyInternationalizationString.SetEndLimit)} : {endSeekBar.Progress}%";
                if (isEndSendDelayFrist == false)
                {
                    isEndSendDelayFrist = true;
                    //先发送删除限位点命令
                    await DeleteDownLimintAsync(rollershade);
                    rollershade.WcdGoToTiltValue(endSeekBar.Progress);
                    lastEndSendDelayTime = DateTime.Now;
                }
                else
                {
                    if ((DateTime.Now - lastEndSendDelayTime).TotalSeconds > sleepSpan)
                    {
                        rollershade.WcdGoToTiltValue(endSeekBar.Progress);
                        lastEndSendDelayTime = DateTime.Now;
                    }
                }
            };
            endSeekBar.MouseUpEventHandler += (sender1, e1) =>
            {
                isEndSendDelayFrist = false;
                hadReceivedStartEndLimitCode = false;
                canSetEndLimit = true;
                rollershade.WcdGoToTiltValue(endSeekBar.Progress);
                lastEndSendDelayTime = DateTime.Now;
                CommonPage.Loading.Start(Language.StringByID(R.MyInternationalizationString.PleaseWaitWhileTheGuidewayIsMoving));
                DeviceDelayAction(rollershade, (hadReceived) =>
                {
                    Application.RunOnMainThread(() =>
                    {
                        if (hadReceived == false)
                        {
                            this.ShowMassage(ShowMsgType.Tip, Language.StringByID(R.MyInternationalizationString.FailedPleaseTryAgain));
                        }
                        else
                        {
                            //var tip = new TipViewControl(Language.StringByID(R.MyInternationalizationString.Success));
                            //tip.ShowView();
                        }
                        CommonPage.Loading.Hide();
                    });
                }, 5);
            };
            void limit_MouseUpEvnet(object sender, MouseEventArgs mouseEventArgs)
            {
                btnDirectionRight.IsSelected = !btnDirectionRight.IsSelected;
                if (btnDirectionRight.IsSelected)
                {
                    directionLimitRow.Height = ControlCommonResourse.ListViewRowHeight * 5;
                }
                else
                {
                    directionLimitRow.Height = ControlCommonResourse.ListViewRowHeight;
                }
            }
            btnDirectionRight.MouseUpEventHandler += limit_MouseUpEvnet;
            directionLimitBtn.MouseUpEventHandler += limit_MouseUpEvnet;
            directionLimitRow.MouseUpEventHandler += limit_MouseUpEvnet;
        }
        #endregion
        #region ◆ 添加 【恢复行程设置】行______________
        /// <summary>
        /// 添加 【恢复行程设置】行
        /// </summary>
        /// <param name="listview">Lisrview.</param>
        private void AddRestoreTravelSettingsRow(VerticalScrolViewLayout listview)
        {
            var RestoreTravelSettingsRow = new RowLayoutControl();
            listview.AddChidren(RestoreTravelSettingsRow);
            var RestoreTravelSettingsRowBtn = RestoreTravelSettingsRow.frameTable.AddLeftCaption("", 900);
            RestoreTravelSettingsRowBtn.TextID = R.MyInternationalizationString.RestoreTravelSettings;
            RestoreTravelSettingsRow.AddChidren(RestoreTravelSettingsRowBtn);
            RestoreTravelSettingsRow.frameTable.ButtonClickEvent += (sender, e) =>
            {
                try
                {
                    CommonPage.Loading.Start();
                    System.Console.WriteLine("恢复限位");
                    var alert = new Alert(Language.StringByID(R.MyInternationalizationString.TIP), Language.StringByID(R.MyInternationalizationString.IsCancelRestoreTravelSettings), Language.StringByID(R.MyInternationalizationString.Cancel), Language.StringByID(R.MyInternationalizationString.Confrim));
                    alert.Show();
                    alert.ResultEventHandler += async (alertSender, alertE) =>
                    {
                        if (alertE)
                        {
                            var setWritableValueResponAllData = await rollershade.RestoreCurtainLimitAsync();
                            if(setWritableValueResponAllData==null || setWritableValueResponAllData.setWritableValueResponData==null)
                            {
                                CommonPage.Loading.Hide();
                                CommonPage.Instance.ShowErrorInfoAlert(R.MyInternationalizationString.FAIL);
                                return;
                            }
                            var status = setWritableValueResponAllData.setWritableValueResponData.Status;
                            //以后补充提示
                            //0:配置成功(若配置成功,下面的AttributeId字段不存在)
                            //34:不支持该属性
                            //135:无效的属性值
                            //141:无效的数据类型
                            if (status == 0)
                            {
                                //恢复行程成功后手动去读取状态
                                InitReadStatu();
                                System.Console.WriteLine("恢复行程设置成功");
                                this.ShowMassage(ShowMsgType.Tip, Language.StringByID(R.MyInternationalizationString.Success));
                            }
                            else
                            {
                                CommonPage.Loading.Hide();
                                CommonPage.Instance.ShowErrorInfoAlert(R.MyInternationalizationString.FAIL);
                            }
                        }
                    };
                }
                catch(Exception ex)
                {
                    System.Console.WriteLine($"恢复行程设置失败{ex.Message}");
                }
                finally
                {
                    CommonPage.Loading.Hide();
                }
            };
        }
        #endregion
        #region ◆ 设备延时回调_______________________
        /// <summary>
        /// 设备延时回调
        /// </summary>
        /// <param name="commonDevice">Common device.</param>
        /// <param name="action">Action.</param>
        /// <param name="delayTime">延时执行时间,默认10秒</param>
        public void DeviceDelayAction(CommonDevice commonDevice,Action<bool> action,int delayTime=10)
        {
            var threadName = commonDevice.GetHashCode().ToString();
            var tt = threads.Find((obj) => obj.Name == threadName);
            if (threads.Find((obj) => obj.Name==threadName)==null)
            {
                var thread = new System.Threading.Thread(() =>
                  {
                      var dateTime = DateTime.Now;
                      while ((DateTime.Now - dateTime).TotalSeconds < delayTime)
                      {
                          System.Threading.Thread.Sleep(100);
                      }
                      lock (threads)
                      {
                          threads.RemoveAll((obj) => obj.Name == threadName);
                      }
                      action?.Invoke(hadReceivedStartEndLimitCode);
                  })
                { IsBackground = true, Name = threadName };
                lock (threads)
                {
                    threads.Add(thread);
                }
                thread.Start();
            }
            else
            {
                System.Console.WriteLine("dddd");
            }
        }
        #endregion
        #region ◆ 设置上、下限位______________________
        /// <summary>
        /// 设置上、下限位
        /// <para>0 :成功</para>
        /// <para>-1 :失败(网关不在线)</para>
        /// <para>34:不支持该属性</para>
        /// <para>135:无效的属性值</para>
        /// <para>141:无效的数据类型</para>
        /// </summary>
        /// <returns>The limit async.</returns>
        /// <param name="upOrDownLimit">上或者下限位</param>
        /// <param name="r">窗帘.</param>
        private async System.Threading.Tasks.Task<int> SetLimitAsync(Rollershade.CurtainPrivateInstalledLimi upOrDownLimit, Rollershade r)
        {
            var setWritableValueResponAllData = await r.SetCurtainInstalledLimitAsync(upOrDownLimit);
            if (setWritableValueResponAllData == null || setWritableValueResponAllData.setWritableValueResponData == null)
            {
                return -1;
            }
            return setWritableValueResponAllData.setWritableValueResponData.Status;
        }
        #endregion
        #region ◆ 删除限位点_________________________
        /// <summary>
        /// 删除上限位点
        /// </summary>
        /// <returns>The up limits async.</returns>
        /// <param name="r">The red component.</param>
        private async System.Threading.Tasks.Task<CommonDevice.SetWritableValueResponAllData> DeleteUpLimitAsync(Rollershade r)
        {
            return await r.DeleteCurtainLimitsAsync(Rollershade.LimiType.UpLimit);
        }
        /// <summary>
        /// 删除下限位点
        /// </summary>
        /// <returns>The down limint async.</returns>
        /// <param name="r">The red component.</param>
        private async System.Threading.Tasks.Task<CommonDevice.SetWritableValueResponAllData> DeleteDownLimintAsync(Rollershade r)
        {
            return await r.DeleteCurtainLimitsAsync(Rollershade.LimiType.DownLimit);
        }
        #endregion
    }
}