using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Net.NetworkInformation;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml.Linq;
using DH.Commons.Base;
using DH.Commons.Enums;
using DH.Commons.Models;
using HslCommunication;
using HslCommunication.Enthernet;
using HslCommunication.Profinet.XINJE;
using OpenCvSharp;

namespace DH.Devices.PLC
{
    public class XinJEPLCTcpNet : PLCBase
    {
        private static XinJEPLCTcpNet _instance;
        public static XinJEPLCTcpNet Instance
        {
            get
            {
                if (_instance == null)
                    _instance = new XinJEPLCTcpNet();
                return _instance;
            }
        }
    
        private XinJETcpNet TcpNet = new XinJETcpNet();

        public override bool PLCConnect()
        {
            try
            {
                TcpNet.IpAddress = IP;
                TcpNet.Port = Port;
                TcpNet.ConnectTimeOut = 5000;
                TcpNet.ReceiveTimeOut = 10000;
                TcpNet.SleepTime = 0;
                TcpNet.AddressStartWithZero = true;
                TcpNet.IsStringReverse = false;
                TcpNet.Station = 1;
                switch (PLCType)
                {
                    case EnumPLCType.信捷XD网口:
                        TcpNet.Series = XinJESeries.XD;
                        TcpNet.DataFormat = HslCommunication.Core.DataFormat.CDAB;
                        break;
                    case EnumPLCType.信捷XC网口:
                        TcpNet.Series = XinJESeries.XC;
                        TcpNet.DataFormat = HslCommunication.Core.DataFormat.CDAB;
                        break;
                }
                OperateResult ret = TcpNet.ConnectServer();
                if (ret.IsSuccess)
                {
                    Connected = true;
                    //初始化流程
                    InitProcess();
                    return true;
                }
                else
                {
                    Connected = false;
                    throw new Exception($"{IP}:{Port}PLC连接失败!");
                }


            }
            catch(Exception ex)
            {
                Connected = false;
                throw new Exception($"{IP}:{Port}PLC连接失败!失败原因:{ex.ToString()}");
            }

        }

        public override Int16 ReadInt16(string address)
        {
            try
            {
                if (Connected)
                {
                    // 读取Int变量
                    var result = TcpNet.ReadInt16(address);
                    if (result.IsSuccess)
                    {
                        return result.Content;
                    }
                    else
                    {

                        throw new Exception($"PLC操作读取int16失败,地址{address}");

                    }
                }
                else
                {
                    throw new Exception($"PLC未连接,地址{address}");
                }
            }
            catch (Exception ex)
            {
                throw new Exception($"PLC操作读取int16失败,地址{address},失败原因:{ex.ToString()}");
            }
        }

        public override Int32 ReadInt32(string address)
        {
            try
            {
                if (Connected)
                {
                    // 读取Int变量
                    var result = TcpNet.ReadInt32(address);
                    if (result.IsSuccess)
                    {
                        return result.Content;
                    }
                    else
                    {

                        throw new Exception($"PLC操作读取int32失败,地址{address}");
                    }
                }
                else
                {
                    throw new Exception($"PLC未连接,地址{address}");
                }
            }
            catch (Exception ex)
            {
                throw new Exception($"PLC操作读取int32失败,地址{address},失败原因:{ex.ToString()}");
            }
        }


        public override UInt16 ReadUInt16(string address)
        {
            try
            {
                if (Connected)
                {
                    // 读取Int变量
                    var result = TcpNet.ReadUInt16(address);
                    if (result.IsSuccess)
                    {
                        return result.Content;
                    }
                    else
                    {

                        throw new Exception($"PLC操作读取uint16失败,地址{address}");

                    }
                }
                else
                {
                    throw new Exception($"PLC未连接,地址{address}");
                }
               
            }
            catch (Exception ex)
            {
                throw new Exception($"PLC操作读取uint16失败,地址{address},失败原因:{ex.ToString()}");
            }
        }

        public override UInt32 ReadUInt32(string address)
        {
            try
            {
                if (Connected)
                {
                    // 读取Int变量
                    var result = TcpNet.ReadUInt32(address);
                    if (result.IsSuccess)
                    {
                        return result.Content;
                    }
                    else
                    {

                        throw new Exception($"PLC操作uint32失败,地址{address}");
                    }
                }
                else
                {
                    throw new Exception($"PLC未连接,地址{address}");
                }
            }
            catch (Exception ex)
            {
                throw new Exception($"PLC操作读取uint32失败,地址{address},失败原因:{ex.ToString()}");
            }
        }


        public override float ReadFloat(string address)
        {
            try
            {
                if (Connected)
                {
                    // 读取Float变量
                    var result = TcpNet.ReadFloat(address);
                    if (result.IsSuccess)
                    {
                        return result.Content;
                    }
                    else
                    {
                        throw new Exception($"PLC操作读取float失败,地址{address}");
                    }
                }
                else
                {
                    throw new Exception($"PLC未连接,地址{address}");
                }
            }
            catch (Exception ex)
            {
                throw new Exception($"PLC操作读取float失败,地址{address},失败原因:{ex.ToString()}");
            }
        }

        public override bool ReadBool(string address)
        {
            try
            {   if (Connected)
                {
                    // 读取Bool变量
                    var result = TcpNet.ReadBool(address);
                    if (result.IsSuccess)
                    {
                        return result.Content;
                    }
                    else
                    {
                        throw new Exception($"PLC操作读取bool失败,地址{address}");
                    }
                }
                else
                {
                    throw new Exception($"PLC未连接,地址{address}");
                }
            }
            catch (Exception ex)
            {
                throw new Exception($"PLC操作读取bool失败,地址{address},失败原因:{ex.ToString()}");
            }
        }


        /// <summary>
        /// 写单独地址 uint32 值
        /// </summary>
        /// <param name="address">地址</param>
        /// <param name="writeValue">要写入的 int 值</param>
        /// <param name="waitForReply">是否等待回复</param>
        public override bool WriteUInt32(string address, UInt32 writeValue, bool waitForReply = true)
        {
            if (Connected)
            {

                if (string.IsNullOrEmpty(address))
                {
                    return false;
                }

                int repeatTime = 3;

                do
                {
                    try
                    {
                        var result = TcpNet.Write(address, writeValue);
                        if (result.IsSuccess)
                        {
                            return true;
                        }
                    }
                    catch (Exception ex)
                    {
                        repeatTime--;
                        if (repeatTime <= 0)
                        {
                            throw new Exception($"PLC操作写入uint32失败,地址{address},失败原因:{ex.ToString()}");
                        }
                    }
                } while (repeatTime > 0);
            }
            else
            {
                throw new Exception($"PLC未连接,地址{address}");
            }
            return false;
        }

        /// <summary>
        /// 写单独地址 uint16 值
        /// </summary>
        /// <param name="address">地址</param>
        /// <param name="writeValue">要写入的 int 值</param>
        /// <param name="waitForReply">是否等待回复</param>

        public override bool WriteUInt16(string address, UInt16 writeValue, bool waitForReply = true)
        {
            if (Connected) 
            {
                if (string.IsNullOrEmpty(address))
                {
                    return false;
                }

                int repeatTime = 3;

                do
                {
                    try
                    {
                        var result = TcpNet.Write(address, writeValue);
                        if (result.IsSuccess)
                        {
                            return true;
                        }
                    }
                    catch (Exception ex)
                    {
                        repeatTime--;
                        if (repeatTime <= 0)
                        {
                            throw new Exception($"PLC操作写入uint16失败,地址{address},失败原因:{ex.ToString()}");
                        }
                    }
                } while (repeatTime > 0);
            }
            else
            {
                throw new Exception($"PLC未连接,地址{address}");
            }
            return false;
        }




        /// <summary>
        /// 写单独地址 int32 值
        /// </summary>
        /// <param name="address">地址</param>
        /// <param name="writeValue">要写入的 int 值</param>
        /// <param name="waitForReply">是否等待回复</param>
        public override bool WriteInt32(string address, Int32 writeValue, bool waitForReply = true)
        {
            if (Connected)
            {
                if (string.IsNullOrEmpty(address))
                {
                    return false;
                }

                int repeatTime = 3;

                do
                {
                    try
                    {
                        var result = TcpNet.Write(address, writeValue);
                        if (result.IsSuccess)
                        {
                            return true;
                        }
                    }
                    catch (Exception ex)
                    {
                        repeatTime--;
                        if (repeatTime <= 0)
                        {
                            throw new Exception($"PLC操作写入int32失败,地址{address},失败原因:{ex.ToString()}");
                        }
                    }
                } while (repeatTime > 0);
            }
            else
            {
                throw new Exception($"PLC未连接,地址{address}");
            }
            return false;
        }

        /// <summary>
        /// 写单独地址 int16 值
        /// </summary>
        /// <param name="address">地址</param>
        /// <param name="writeValue">要写入的 int 值</param>
        /// <param name="waitForReply">是否等待回复</param>

        public override bool WriteInt16(string address, Int16 writeValue, bool waitForReply = true)
        {
            if (Connected)
            {
                if (string.IsNullOrEmpty(address))
                {
                    return false;
                }

                int repeatTime = 3;

                do
                {
                    try
                    {
                        var result = TcpNet.Write(address, writeValue);
                        if (result.IsSuccess)
                        {
                            return true;
                        }
                    }
                    catch (Exception ex)
                    {
                        repeatTime--;
                        if (repeatTime <= 0)
                        {
                            throw new Exception($"PLC操作写入int16失败,地址{address},失败原因:{ex.ToString()}");
                        }
                    }
                } while (repeatTime > 0);
            }
            else
            {
                throw new Exception($"PLC未连接,地址{address}");
            }
        
            return false;
        }



  
        /// <summary>
        /// 写单独地址 float 值
        /// </summary>
        /// <param name="address">地址</param>
        /// <param name="writeValue">要写入的 float 值</param>
        /// <param name="waitForReply">是否等待回复</param>
        public override bool WriteFloat(string address, float writeValue, bool waitForReply = true)
        {
            if (Connected)
            {
                if (string.IsNullOrEmpty(address))
                {
                    return false;
                }

                int repeatTime = 3;

                do
                {
                    try
                    {
                        var result = TcpNet.Write(address, writeValue);
                        if (result.IsSuccess)
                        {
                            return true;
                        }
                    }
                    catch (Exception ex)
                    {
                        repeatTime--;
                        if (repeatTime <= 0)
                        {
                            throw new Exception($"PLC操作写入float失败,地址{address},失败原因:{ex.ToString()}");
                        }
                    }
                } while (repeatTime > 0);
            }
            else
            {
                throw new Exception($"PLC未连接,地址{address}");
            }
            return false;
        }

        /// <summary>
        /// 写单独地址 bool 值
        /// </summary>
        /// <param name="address">地址</param>
        /// <param name="writeValue">要写入的 bool 值</param>
        /// <param name="waitForReply">是否等待回复</param>
        public override bool WriteBool(string address, bool writeValue, bool waitForReply = true)
        {
            if(Connected)
            {
                if (string.IsNullOrEmpty(address))
                {
                    return false;
                }

                int repeatTime = 3;
                do
                {
                    try
                    {
                        var result = TcpNet.Write(address, writeValue);
                        if (result.IsSuccess)
                        {
                            return true;
                        }
                    }
                    catch (Exception ex)
                    {
                        repeatTime--;
                        if (repeatTime <= 0)
                        {
                            throw new Exception($"PLC操作写入bool失败,地址{address},失败原因:{ex.ToString()}");
                        }
                    }
                } while (repeatTime > 0);

                Thread.Sleep(30);
            }
            else
            {
                throw new Exception($"PLC未连接,地址{address}");
            }
          
            return false;
        }


        public override bool PLCDisConnect()
        {
            if (Connected)
            {
            
                var res = TcpNet.ConnectClose();
                if (res.IsSuccess)
                {
                    Connected = false;
                    return true;
                }
                return false;
            }
            return false;
        }




        private void MonitorPieces()
        {
        
            ThreadStart ts = new ThreadStart(MonitorPiecesImpl);
            Thread th = new Thread(ts);
            th.Priority = ThreadPriority.AboveNormal;
            th.IsBackground = false;
            th.Start();

        }


        public TaskFactory _taskFactory = new TaskFactory(TaskCreationOptions.LongRunning, TaskContinuationOptions.LongRunning);

        private Dictionary<ushort, uint> piecesCountDic = new Dictionary<ushort, uint>();
        private uint piecesCount = 0;

        /// <summary>
        /// int,int  轴号  捕获位置
        /// </summary>
        public event Action<int, uint> OnNewPieces;

        public void NewPieces(int axisIndex, uint pieceNumber)
        {
            _taskFactory.StartNew(() =>
            {
                Thread.CurrentThread.Priority = ThreadPriority.Highest;

                OnNewPieces?.Invoke(axisIndex, pieceNumber);
            });
        }
        public async Task HeartbeatAsync1()
        {
            PLCItem? pLCItem = PLCItemList.FirstOrDefault(u => u.Name == "心跳地址");
            while (Connected)
            {
            
                if (pLCItem == null)
                    return;
                WriteBool(pLCItem.Name, true);
                await Task.Delay(900); // 非阻塞,等待1秒
            }
        }
        /// <summary>
        /// 入料监听
        /// </summary>
        /// <param name="axisIndex"></param>
        private void MonitorPiecesImpl()
        {

            PLCItem pLCItem= PLCItemList.FirstOrDefault(u => u.Name == "产品计数");
            if (pLCItem == null)
                return;
            string Count = pLCItem.Address;
            DateTime startTime = DateTime.Now;
            DateTime endTime = startTime;
            TimeSpan timeSpan = endTime - startTime;
            Thread.CurrentThread.Priority = ThreadPriority.AboveNormal;
            //while (CurrentState != DeviceState.DSClose && CurrentState != DeviceState.DSExcept && CurrentState != DeviceState.DSUninit)
            while (Connected)
            {
                Stopwatch sw = new Stopwatch();
                uint tmpPieceNumber = 0;
                sw.Start();
                
               // var ret = TcpNet.ReadUInt16("D1016");
                var ret = TcpNet.ReadUInt32(Count);

                sw.Stop();
                if (ret.IsSuccess)
                {
                    tmpPieceNumber = ret.Content;
                }

                if (ret.IsSuccess && ret.Content > piecesCount)
                {
                    sw.Start();
                    // Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")} 板卡{station}产品入列触发{tmpPieceNumber}");
                    //LogAsync(DateTime.Now, LogLevel.Information, $"转盘{0}产品入列 {piecesCountDic[0]} size:{sum}");
                    if (tmpPieceNumber != piecesCount + 1)
                    {
                        //LogAsync(DateTime.Now, LogLevel.Information, $"入列触发丢失\t{tmpPieceNumber}");
                        // Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")}\t板卡{station}产品入列触发丢失,{piecesCountDic[station]}\t{tmpPieceNumber}");

                    }
                    piecesCount = tmpPieceNumber;
                    //NewPieces(ai, piecesCountDic[station]);
                     NewPieces(1, piecesCount);
                    sw.Stop();
                    startTime = DateTime.Now;
                    //if (idalarm)
                    //{
                    //    idalarm = false;
                    //    AlarmVibration(false);
                    //}

                }

                Thread.Sleep(1);
            }
        }

        public void InitProcess()
        {
            //启用心跳
            OpenHeartbeat(true);
            //状态复位
            StatusReset();
            //关闭定位
            VisionPos(false);

            //写入流程加载点位配置
            InitProcessAction();

            //计数清零
            CountToZero();
            //停止转盘
            TurnStart(false);
            //转盘使能
            TurnEnable(true);
            //开启入料监听
            MonitorPieces();

        }

        public void StartProcess()
        { 
            //状态复位
            StatusReset();
            //关闭定位
            VisionPos(false);
            //写入流程启动点位配置
            StartProcessAction();
            //计数清零
            CountToZero();
            //转盘启动
            TurnStart(true);
        }


        public void InitProcessAction() =>
            ProcessAction(ConfigModel.GlobalList?.FirstOrDefault()?.InitProcessList?.ToList() ?? new List<PLCItem>());

        public void StartProcessAction() =>
            ProcessAction(ConfigModel.GlobalList?.FirstOrDefault()?.StartProcessList?.ToList() ?? new List<PLCItem>());

        public void StopProcessAction() =>
            ProcessAction(ConfigModel.GlobalList?.FirstOrDefault()?.StopProcessList?.ToList() ?? new List<PLCItem>());

        public void StartResetAction() =>
            ProcessAction(ConfigModel.GlobalList?.FirstOrDefault()?.StartResetList?.ToList() ?? new List<PLCItem>());

        public void StopResetAction() =>
            ProcessAction(ConfigModel.GlobalList?.FirstOrDefault()?.StopResetList?.ToList() ?? new List<PLCItem>());

        // 处理方法:无需再检查 null
        private void ProcessAction(List<PLCItem> items)
        {
            if (items.Count == 0) return;

            foreach (var item in items.OrderBy(x => x.StartIndex))
            {
                switch (item.Type)
                {
                    case EnumPLCDataType.单字整型:
                        WriteUInt16(item.Address, ushort.Parse(item.Value));
                        break;
                    case EnumPLCDataType.双字整型:
                        WriteUInt32(item.Address, uint.Parse(item.Value));
                        break;
                    case EnumPLCDataType.浮点型:
                        WriteFloat(item.Address, float.Parse(item.Value));
                        break;
                    case EnumPLCDataType.布尔型:
                        WriteBool(item.Address, item.Value.Equals("true", StringComparison.OrdinalIgnoreCase));
                        break;
                }
            }
        }
        /// <summary>
        /// 状态复位
        /// </summary>
        public void StatusReset()
        {
            PLCItem? pLCItem = PLCItemList.FirstOrDefault(u => u.Name == "状态复位");
            if (pLCItem == null)
                return;
            WriteBool(pLCItem.Address, false);
        }

        /// <summary>
        /// 开启关闭视觉定位
        /// </summary>
        public void VisionPos(bool b)
        {
            PLCItem? pLCItem = PLCItemList.FirstOrDefault(u => u.Name == "启用定位");
            if (pLCItem == null)
                return;
            WriteBool(pLCItem.Address, b);
        }

        /// <summary>
        /// 转盘启停
        /// </summary>
        public void TurnStart(bool b)
        {
            PLCItem? DiskRunItem = PLCItemList.FirstOrDefault(u => u.Name == "转盘启动");
            if (DiskRunItem == null)
                return;
            WriteBool(DiskRunItem.Address, b);
            Thread.Sleep(30);
            piecesCount = 0;
        }

        /// <summary>
        /// 转盘使能
        /// </summary>
        /// <param name="b"></param>
        public void TurnEnable(bool b)
        {
            PLCItem? DiskOpenItem = PLCItemList.FirstOrDefault(u => u.Name == "转盘使能");
            if (DiskOpenItem == null)
                return;
            WriteBool(DiskOpenItem.Address, b);
            Thread.Sleep(30);
        }

        /// <summary>
        /// 计数清零
        /// </summary>
        public void CountToZero()
        {
            PLCItem? pLCItem = PLCItemList.FirstOrDefault(u => u.Name == "计数清零");
            if (pLCItem == null)
                return;
            WriteBool(pLCItem.Address, true);
            Thread.Sleep(30);
        }

        public void RedLight(bool b)
        {
            PLCItem? pLCItem = PLCItemList.FirstOrDefault(u => u.Name == "指示灯红");
            if (pLCItem == null)
                return;
            WriteBool(pLCItem.Address, b);
            Thread.Sleep(30);
        }

        public void GreenLight(bool b)
        {
            PLCItem? pLCItem = PLCItemList.FirstOrDefault(u => u.Name == "指示灯绿");
            if (pLCItem == null)
                return;
            WriteBool(pLCItem.Address, b);
            Thread.Sleep(30);

        }

        public void YellowLight(bool b)
        {
            PLCItem? pLCItem = PLCItemList.FirstOrDefault(u => u.Name == "指示灯黄");
            if (pLCItem == null)
                return;
            WriteBool(pLCItem.Address, b);
            Thread.Sleep(30);
        }

        public void Buzzer(bool b)
        {
            PLCItem? pLCItem = PLCItemList.FirstOrDefault(u => u.Name == "蜂鸣器");
            if (pLCItem == null)
                return;
            WriteBool(pLCItem.Address, b);
            Thread.Sleep(30);
        }

        /// <summary>
        /// 挡料电机操作 
        /// true: 顺时针
        /// False: 逆时针
        /// </summary>
        /// <param name="u"></param>
        public void FeedingMotor( bool direction)
        {


           // 设置最大等待时间,假设为 3 秒
            int timeout = 3000;
            int elapsedTime = 0;
            int checkInterval = 100; // 每次检查等待 100ms

            PLCItem pLCItem = PLCItemList.FirstOrDefault(u => u.Name == "挡料电机回原点");
            if (pLCItem == null)
                return;
            PLCItem zerospeeditem = PLCItemList.FirstOrDefault(u => u.Name == "挡料电机回原点速度");
            if (zerospeeditem == null)
                return;

            PLCItem CunSpeed = PLCItemList.FirstOrDefault(u => u.Name == "挡料电机速度");
            if (CunSpeed == null)
                return;

            PLCItem CunClockwiseItem = PLCItemList.FirstOrDefault(u => u.Name == "挡料电机顺时针");
            if (CunClockwiseItem == null)
                return;

            PLCItem CunCounterclockwiseItem = PLCItemList.FirstOrDefault(u => u.Name == "挡料电机逆时针");
            if (CunCounterclockwiseItem == null)
                return;

            PLCItem CunPosItem = PLCItemList.FirstOrDefault(u => u.Name == "挡料电机位置");
            if (CunPosItem == null)
                return;

            string CunToZero = pLCItem.Type + pLCItem.Address;
            string CunToZeroSpeed = zerospeeditem.Type + zerospeeditem.Address;
            string CunSpeedadress = CunSpeed.Type + CunSpeed.Address;
            string CunClockwise = CunClockwiseItem.Type + CunClockwiseItem.Address;
            string CunCounterclockwise = CunCounterclockwiseItem.Type + CunCounterclockwiseItem.Address;
            string CunPos = CunPosItem.Type + CunPosItem.Address;
            UInt16 zerospeed = UInt16.Parse(zerospeeditem.Value);
            UInt16 cunSpeed = UInt16.Parse(CunSpeed.Value);
            UInt16 u = UInt16.Parse(CunPosItem.Value);
           // WriteBool(CountToZero, true);

            // 检查是否不在原点,如果不在,则回原点
            if (!ReadBool(CunToZero))
            {
                WriteUInt16(CunToZeroSpeed, zerospeed); // 速度
                Thread.Sleep(30);
                // 发送回原点指令
                WriteBool(CunToZero, true);
                Thread.Sleep(1000); // 给设备一些时间响应

                // 等待回到原点
                while (!ReadBool(CunToZero))
                {
                    if (elapsedTime >= timeout)
                    {
                       break;
                    }

                    Thread.Sleep(checkInterval);
                    elapsedTime += checkInterval;
                }
            }

            // 无论是刚回到原点还是已经在原点,执行目标位置、速度和方向设置



            WriteUInt16(CunSpeedadress,cunSpeed);
            Thread.Sleep(2000);
            string dir = string.Empty;
            if (direction)
            {
                WriteBool(CunClockwise, true); // 顺时针转动
                dir = "顺时针";
            }
            else
            {
                WriteBool(CunCounterclockwise, true); // 逆时针转动
                dir = "逆时针";
            }
            Thread.Sleep(30);
            WriteUInt16(CunPos, u);   // 目标位置
            Thread.Sleep(2000);



        }

        /// <summary>
        /// 转盘清料
        /// </summary>
        /// <param name="b"></param>
        public void TurnClear(bool b)
        {
            PLCItem? pLCItem = PLCItemList.FirstOrDefault(u => u.Name == "转盘清料");
            if (pLCItem == null)
                return;
            WriteBool(pLCItem.Address, b);
            Thread.Sleep(30);
        }

        /// <summary>
        /// 开启心跳
        /// </summary>
        /// <param name="v"></param>
        public void OpenHeartbeat(bool b)
        {
            PLCItem? pLCItem = PLCItemList.FirstOrDefault(u => u.Name == "启用心跳");
            if (pLCItem == null)
                return;
            WriteBool(pLCItem.Address, b);
            Thread.Sleep(30);
            if (b)
            {
                //开启心跳
                Task.Run(async () => await HeartbeatAsync1());
            }
        }

        int currentRegister = 0;
        public void Blowing(uint productNumber, UInt16 value)
        {
            int Register = (int)((productNumber - 1) % 30);
            currentRegister = 411 + Register;
            WriteUInt16($"D{currentRegister}", value);
          
        }
    }
}