package com.bonait.bnframework.business;

import android.app.Activity;
import android.content.Context;
import android.content.ContextWrapper;
import android.media.MediaPlayer;
import android.net.wifi.rtt.WifiRttManager;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import androidx.annotation.NonNull;

import com.bonait.bnframework.HBL.Unity;
import com.bonait.bnframework.R;
import com.bonait.bnframework.common.constant.ConfigName;
import com.bonait.bnframework.common.constant.DataBus;
import com.bonait.bnframework.common.db.QueryDB;
import com.bonait.bnframework.common.db.mode.BPA_GOODSRECIPE;
import com.bonait.bnframework.common.db.mode.BPA_MATERIAL;
import com.bonait.bnframework.common.db.mode.BPA_PLCADDRESS;
import com.bonait.bnframework.common.db.mode.BPA_SILOS;
import com.bonait.bnframework.common.db.mode.BPA_SILOS_CALIBRATE;
import com.bonait.bnframework.common.db.res.AlertLogEnum;
import com.bonait.bnframework.common.db.res.ResGoodsMake;
import com.bonait.bnframework.common.db.res.ResGoodsRecipe;
import com.bonait.bnframework.common.db.res.SilosLsjyMode;
import com.bonait.bnframework.common.db.res.UserLogEnum;
import com.bonait.bnframework.common.helper.ByteHelper;
import com.bonait.bnframework.common.helper.DataFormat;
import com.bonait.bnframework.common.helper.I.IReadCallBack;
import com.bonait.bnframework.common.helper.I.IRun;
import com.bonait.bnframework.common.helper.I.IRunT;
import com.bonait.bnframework.common.helper.I.IThread;
import com.bonait.bnframework.common.helper.I.IWriteCallBack;
import com.bonait.bnframework.common.helper.MediaPlayerHelper;
import com.bonait.bnframework.common.helper.MessageLog;
import com.bonait.bnframework.common.helper.RTrig;
import com.bonait.bnframework.common.helper.ThreadManager;
import com.bonait.bnframework.common.modbus.ModbusTcpServer;
import com.bonait.bnframework.common.utils.AlertDialogUtils;
import com.bonait.bnframework.common.utils.ToastUtils;
import com.http.utils.LogUtils;
import com.qmuiteam.qmui.widget.dialog.QMUIDialog;
import com.qmuiteam.qmui.widget.dialog.QMUIDialogAction;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import kotlin.UShort;

/**
 * 执行配方
 */
public class ExecuteTheRecipe {

    //region 变量
    /**
     * 等待超时时间
     */
    public static int whileTime = 30;

    /**
     * 监听变量值
     */
    public static HashMap<String, Object> ListeningValue = new HashMap<String, Object>();

    /**
     * 实时状态
     */
    public static ConcurrentHashMap<Integer, Boolean> IoStatus = new ConcurrentHashMap<Integer, Boolean>();

    /**
     * 商品是否制作
     */
    public static boolean IsMakeGood = false;

    /**
     * 扫码信息
     */
    public static String Code = "";

    /**
     * 出杯总量
     */
    public static int MakeGoodCount = 0;

    /**
     * 接收到扫码信息,返回
     */
    public static IRunT<String> OnScanTheCodeInformationT;
    /**
     * 配料完成通知
     */
    public static IRun OnChargeMixtureCompleteNotify;
    /**
     * 通道配料完成通知
     */
    public static IRun OnChargeMixtureComNotPar;
    /**
     * 按钮按下通知
     */
    public static IRun OnIngredientButtonPressedNotify;

    /**
     * 清洗完成
     */
    public static IRun CleaningComplete;

    /**
     * 自动排水完成
     */
    public static IRun AutoPaiShui;

    /**
     * 当前制作商品
     */
    public static ResGoodsMake GoodMake=null;

    /**
     * 出料口重量
     */
    public static int OutletWeigh=0;

    /**
     * 杯子检测
     */
    public static boolean IsCup=false;

    /**
     * 水池温度
     */
    public static int WaterTemp=0;

    /**
     * 果糖左温度
     */
    public static int SugarTempLeft=0;
    /**
     * 果糖右温度
     */
    public static int SugarTempRight=0;

    /**
     * 果糖左温度
     */
    public static int SugarTempLeft_SZ=0;
    /**
     * 果糖右温度
     */
    public static int SugarTempRight_SZ=0;
    /**
     * 重量刷新提示
     */
    public static IRun WeighComplete;
    /**
     * 温度刷新提示
     */
    public static IRun TempComplete;
    //endregion

    //region 执行配方
    /**
     * 执行配方
     *
     * @param
     * @return
     */
    public static void Execute(ResGoodsMake makegood) {
        try {
            GoodMake=makegood;
            IsMakeGood=true;
        } catch (Exception ex) {
            ToastUtils.error("异常信息:" + ex.getMessage());
        } finally {
        }
    }
    //endregion

    //region 写PLC工序

    /**
     * 按下
     * @param name m名称
     * @param time 时间 毫秒
     */
//    public static void BottomClick(String name,long time)
//    {
//        try
//        {
//            WritePLC(name,true,null);
//            new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
//                @Override
//                public void run() {
//                    ExecuteTheRecipe.WritePLC(name, false, null);
//                }
//            }, time);
//        }catch (Exception ex)
//        {
//
//        }
//    }
    //endregion

    //region PLC监听线程
    static List<String> names=new ArrayList<>();
    /**
     * 心跳标志
     */
    static boolean HeartbeatMarkers=false;
    static long StartTime=0;
    static  void Heart(){
        if(!HeartbeatMarkers&&(System.currentTimeMillis()-StartTime)>=3000) {
            Write("心跳",true,null);
            HeartbeatMarkers=true;
            StartTime=System.currentTimeMillis();
        }

        if(HeartbeatMarkers&&(System.currentTimeMillis()-StartTime)>=3000){
            Write("心跳",false,null);
            HeartbeatMarkers=false;
            StartTime=System.currentTimeMillis();
        }

        Write("掉线标志",false,null);
    }


    public static void Listening() {

        ConfigName.getInstance().PLC_Address.clear();
        ArrayList<BPA_PLCADDRESS> address = QueryDB.GetPlcaddressALL();
        for (BPA_PLCADDRESS item : address) {
            if (!item.address.isEmpty() && !item.address.equals("-------------")) {
                ConfigName.getInstance().PLC_Address.put(item.name, item);
            }
        }

//        names.clear();
//        if (ConfigName.getInstance().versionSelectionEnum.equals("配料吧台")) {
//            names.add("水池温度");
//        }else  if (ConfigName.getInstance().versionSelectionEnum.equals("奶茶机"))
//        {
//            names.add("水池温度");
//            names.add("果糖左温度");
//            names.add("果糖右温度");
//        }

//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                //1.自动模式
//                ExecuteTheRecipe.WritePLC("手自切换",true,null);
//                //1.清除开关
//                for (int i=1;i<=20;i++)
//                {
//                    ExecuteTheRecipe.WritePLC("通道"+i+"校准开关",false,null);
//                }
//
//                for (int i=1;i<=20;i++)
//                {
//                    ExecuteTheRecipe.WritePLC("手动控制"+i,false,null);
//                }
//            }
//        }).start();

        ThreadManager.Get().StartLong("PLC设备数据监听", true, new IThread() {
            @Override
            public void Run() throws InterruptedException {
                try {

                    //状态读取
                    for (String item : ConfigName.getInstance().PLC_Address.keySet()) {
                        String key = item;
                        BPA_PLCADDRESS plcaddress = ConfigName.getInstance().PLC_Address.get(item);
                        if (plcaddress.isread == 1) {
                            Object val = ReadPLC(key);
                            ListeningValue.put(key, val);
                        }
                    }

                    Heart();//心跳处理

                    if(!IsMakeGood)
                    {
                        //1.读取扫码数据
                        ReadCode();
                        //2.读取实时状态
                        ReadPLCStatus();
                    }
                } catch (Exception ex) {
                    ToastUtils.error("PLC设备数据监听异常:" + ex.getMessage());
                }
                Thread.sleep(50);
            }

            @Override
            public void RunComplete() throws InterruptedException {

            }
        });

//        ThreadManager.Get().StartLong("PLC设备-温度重量", true, new IThread() {
//            @Override
//            public void Run() throws InterruptedException {
//                try {
//                    if(!IsMakeGood)
//                    {
//                        Object zl= ExecuteTheRecipe.ReadPLC("称当前重量");
//                        OutletWeigh=zl==null?0:(int)zl;
//                        Object bz= ExecuteTheRecipe.ReadPLC("出料口检测");
//                        IsCup=bz==null?false:(boolean) bz;
//                        Object obj1= ExecuteTheRecipe.ReadPLC("水池温度");
//                        WaterTemp=obj1==null?0:(int)obj1;
//
//                        if (ConfigName.getInstance().versionSelectionEnum.equals("奶茶机"))
//                        {
//                            Object obj2= ExecuteTheRecipe.ReadPLC("果糖左温度");
//                            Object obj3= ExecuteTheRecipe.ReadPLC("果糖右温度");
//                            SugarTempLeft=obj2==null?0:(int)obj2;
//                            SugarTempRight=obj3==null?0:(int)obj3;
//
//                            Object obj21= ExecuteTheRecipe.ReadPLC("果糖左温度设置");
//                            Object obj31= ExecuteTheRecipe.ReadPLC("果糖右温度设置");
//                            SugarTempLeft_SZ=obj21==null?0:(int)obj21;
//                            SugarTempRight_SZ=obj31==null?0:(int)obj31;
//                        }
//
//                        if (WeighComplete!=null)
//                        {
//                            WeighComplete.Run();
//                        }
//                        if (TempComplete!=null)
//                        {
//                            TempComplete.Run();
//                        }
//                    }
//                } catch (Exception ex) {
//                    ToastUtils.error("异常信息:" + ex.getMessage());
//                }
//                Thread.sleep(200);
//            }
//            @Override
//            public void RunComplete() throws InterruptedException {
//
//            }
//        });

//        ThreadManager.Get().StartLong("PLC设备-自动加热补水", true, new IThread() {
//            @Override
//            public void Run() throws InterruptedException {
//                try {
//                    if(!IsMakeGood)
//                    {
//                        AutoJR();
//                    }
//                } catch (Exception ex) {
//                    ToastUtils.error("异常信息:" + ex.getMessage());
//                }
//                Thread.sleep(5000);
//            }
//
//            @Override
//            public void RunComplete() throws InterruptedException {
//
//            }
//        });

        ThreadManager.Get().StartLong("PLC设备数据监听-信号检测", true, new IThread() {
            @Override
            public void Run() throws InterruptedException {
                try {
                    ChargeSignal();
                } catch (Exception ex) {
                    ToastUtils.error("异常信息:" + ex.getMessage());
                }
                Thread.sleep(100);
            }
            @Override
            public void RunComplete() throws InterruptedException {

            }
        });

        ThreadManager.Get().StartLong("商品制作线程", true, new IThread() {
            @Override
            public void Run() throws InterruptedException {
                try {
                    if(IsMakeGood && GoodMake!=null)
                    {

                        ArrayList<ResGoodsRecipe> recipes= GoodMake.recipes;

                        //region 根据物料配方排序Sort步骤分组
                        LinkedHashMap<Integer, List<ResGoodsRecipe>> rgrs = new LinkedHashMap<>();
                        for (int i = 0; i < recipes.size(); i++) {
                            if (!rgrs.containsKey(recipes.get(i).sort))
                                rgrs.put(recipes.get(i).sort, new ArrayList<>());
                            rgrs.get(recipes.get(i).sort).add(recipes.get(i));
                        }
                        //endregion

                        int count = 0;
                        for (LinkedHashMap.Entry<Integer, List<ResGoodsRecipe>> entry : rgrs.entrySet()) {
                            WritePLC("配料完成", false,null);

                            final Integer key = entry.getKey();

                            List<ResGoodsRecipe> goodsRecipes = entry.getValue();

                            //region 当前一次性下发物料集合
                            String RecipesNames = "";
                            for (ResGoodsRecipe item : goodsRecipes) {
                                RecipesNames += item.materialName + ",";
                            }
                            count=2;
                            DataBus.getInstance().UpdateGoodsMake(GoodMake.subOrder.id, "步骤【" + key + "】准备下发物料:" + RecipesNames, count, key, false);

                            for (int m = 0; m < goodsRecipes.size(); m++) {
                                ResGoodsRecipe recipe = goodsRecipes.get(m);
                                final String message = "[" + GoodMake.good.name + "]步骤【" + key + "】下发【" + recipe.materialName + "】";

                                //获取物料关联的料仓信息
                                BPA_SILOS silos = null;
                                List<BPA_SILOS> siloslist = QueryDB.GetSolisByMaterialID(recipe.materialID);
                                for (BPA_SILOS item : siloslist) {
                                    if(silos==null)
                                        silos = item;
                                }
                                if (silos == null) {
                                    MessageLog.ShowUserMessage(UserLogEnum.订单处理日志, message + "下发失败！物料没有管理料仓！");
                                } else {
                                    //MessageLog.ShowUserMessage(UserLogEnum.订单处理日志, message + "准备下发【" + silos.num + "】号料仓PLC控制命令,需求量:=" + recipe.value);
//                                    int _val = (int)Math.round((Double.parseDouble(recipe.value) * 10));
                                    float _val = Float.parseFloat(recipe.value);

                                    BPA_SILOS_CALIBRATE res = QueryDB.GetSilosCalibrateByNum(silos.num);
                                    if(res!=null){
                                        String name = silos.name+silos.num+"出料时间";
                                        float outValue = Unity.Scale(_val,res.inputWightMax,res.inputWightMin,res.outputTimeMax,res.outputTimeMin);
                                        MessageLog.ShowUserMessage(UserLogEnum.订单处理日志, "写入地址："+name+"地址值："+outValue*100);
                                        WritePLC(name, (short) (outValue*100), null);
                                    }else{ MessageLog.ShowUserMessage(UserLogEnum.订单处理日志, message + "下发失败！物料没有对应的校准值！");}

                                    //減去料仓数量
                                    int otherG=silos.silosmargin-(int)(_val/10);
                                    QueryDB.UpdateYL(silos.id,otherG>=0?otherG:0);
                                }
                            }
                            MessageLog.ShowInfo(RecipesNames + "下发成功！");
                            //endregion

                            //等待配料完成，一直等待
                            final boolean[] IsComplete = {false};
                            OnChargeMixtureCompleteNotify = new IRun() {
                                @Override
                                public void Run() {
                                    IsComplete[0] = true;
                                    MessageLog.ShowUserMessage(UserLogEnum.订单处理日志, "[" + GoodMake.good.name + "]步骤【" + key + "】配料完成!");
                                }
                            };

                            //启动配料
                            WritePLC("配料启动",true,new IWriteCallBack() {
                                @Override
                                public void onSuccess() {
                                    MessageLog.ShowInfo("[" + GoodMake.good.name + "]步骤【" + key + "】启动配料成功！");
                                }

                                @Override
                                public void onFailure(String ErrorMsg) {
                                    MessageLog.ShowInfo("[" + GoodMake.good.name + "]步骤【" + key + "】启动配料失败！");
                                    MessageLog.ShowAlertMessage(AlertLogEnum.异常订单未制作日志, "[" + GoodMake.good.name + "]步骤【" + key + "】启动配料失败！");
                                }
                            });

                            long a = System.currentTimeMillis();
                            while (!IsComplete[0]) {
                                if ((System.currentTimeMillis() - a) > 1000 * 60) {
                                    break;
                                }
                                Thread.sleep(100);//10 *6
                            }
                            //更新缓存商品制作列表状态
                            count += goodsRecipes.size();
                            DataBus.getInstance().UpdateGoodsMake(GoodMake.subOrder.id, "步骤【" + key + "】:" + RecipesNames + "-配料完成!", count, key, true);
                            MessageLog.ShowUserMessage(UserLogEnum.订单处理日志, "[" + GoodMake.good.name + "]步骤【" + key + "】下发" + RecipesNames + "执行完成!");
                        }

                        DataBus.getInstance().DeleteGoodsMake(GoodMake.subOrder.id);
                        MessageLog.ShowUserMessage(UserLogEnum.订单处理日志, "[" + GoodMake.good.name + "]-订单执行完成,请取餐!");

                        GoodMake=null;
                        IsMakeGood=false;
                    }
                } catch (Exception ex) {
                    ToastUtils.error("异常信息:" + ex.getMessage());
                    IsMakeGood=false;
                }
                Thread.sleep(500);
            }
            @Override
            public void RunComplete() throws InterruptedException {

            }
        });
    }

    public static void releaseListening(){
        ThreadManager.Get().Stop("PLC设备数据监听");
        ThreadManager.Get().Stop("PLC设备数据监听-信号检测");
        ThreadManager.Get().Stop("商品制作线程");
    }
    //endregion

    //region PLC基础控制类

    /**
     * 写PLC数据
     *
     * @param name
     * @param value
     */
    public static void WritePLC(String name, Object value, IWriteCallBack callback) {
        MessageLog.ShowInfo("WritePLC  name="+name +";value="+value.toString());
        try {
            if (ConfigName.getInstance().PLC_Address.containsKey(name)) {
                BPA_PLCADDRESS plcaddress = ConfigName.getInstance().PLC_Address.get(name);
                MessageLog.ShowInfo("WritePLC  name="+name + ";plcaddress.address="+plcaddress.address.toString()+";value="+value.toString());

                if (!plcaddress.address.isEmpty() && ConfigName.getInstance().PlcIsConnect) {
                    if (plcaddress.address.toUpperCase().startsWith("VD"))//int
                    {
                        ModbusTcpServer.get().WriteInt(plcaddress.address, (int) value, callback);
                    } else if (plcaddress.address.toUpperCase().startsWith("M"))//bool
                    {
                        ModbusTcpServer.get().WriteBool(plcaddress.address, (boolean) value, callback);
                    } else if (plcaddress.address.toUpperCase().startsWith("VW"))//short
                    {
                        if(plcaddress.address.contains("."))
                        {
                            String[] res = plcaddress.address.split("[.]");
                            String firstAdd = res[0]; //VW100
                            int endAdd = Integer.parseInt(res[1]); //1  //第几位
                            ModbusTcpServer.get().ReadShort(firstAdd, 1, new IReadCallBack<short[]>() {
                                @Override
                                public void onSuccess(short[] shorts) {
                                    Short val=shorts[0];
                                    Short valk= ByteHelper.setBit(val,endAdd,(boolean) value);
                                    ModbusTcpServer.get().WriteShort(firstAdd, valk, null);
                                }
                            });
                        }else
                        {
                            ModbusTcpServer.get().WriteShort(plcaddress.address, Short.parseShort(value.toString()), callback);
                        }
                    }else if (plcaddress.address.toUpperCase().startsWith("VR"))//float
                    {
                        ModbusTcpServer.get().WriteFloat(plcaddress.address, Float.parseFloat(value.toString()), callback);
                    }
                }
            }
        } catch (Exception ex) {
            ToastUtils.error("异常信息:" + ex.getMessage());
        } finally {

        }
    }

    public static void Write(Object plcName,Object value,IWriteCallBack callBack){
        MessageLog.ShowInfo("WritePLC  plcName=" +plcName.toString() +";value="+value.toString());
        WritePLC(plcName.toString(),value,callBack);
    }

    /**
     * 读PLC数据
     *
     * @param name
     * @return
     */
    public static Object ReadPLC(String name) {

        final Object[] ReturnsVariable = {null};
        try {
            if (ConfigName.getInstance().PLC_Address.containsKey(name)) {
                BPA_PLCADDRESS plcaddress = ConfigName.getInstance().PLC_Address.get(name);
                MessageLog.ShowInfo("ReadPLC  name=" +name +"  plcaddress="+plcaddress.address.toString());
                if (!plcaddress.address.isEmpty() && ConfigName.getInstance().PlcIsConnect) {
                    if (plcaddress.address.toUpperCase().startsWith("VD"))//int
                    {
                        ModbusTcpServer.get().ReadInt(plcaddress.address, 1, ints -> {
                            ReturnsVariable[0] = ints[0];
                        });
                    } else if (plcaddress.address.toUpperCase().startsWith("M"))//bool
                    {
                        ModbusTcpServer.get().ReadBool(plcaddress.address, 1, val -> {
                            ReturnsVariable[0] = val[0];
                        });
                    } else if (plcaddress.address.toUpperCase().startsWith("VW"))//short
                    {
                        if(plcaddress.address.contains("."))
                        {
                            String[] res = plcaddress.address.split("[.]");
                            String firstAdd = res[0].replace("V","VW"); //VW194
                            int endAdd = Integer.parseInt(res[1]); //1  //第几位
                            ModbusTcpServer.get().ReadbcStatus(firstAdd, 1, data -> {
                                byte status=data[0];//0x92
                                ReturnsVariable[0] = ByteHelper.getBit(status,endAdd)==1;
                            });
                        }else
                        {
                            ModbusTcpServer.get().ReadShort(plcaddress.address, 1, val -> {
                                ReturnsVariable[0] = val[0];
                            });
                        }
                    } else if (plcaddress.address.toUpperCase().startsWith("VR"))//float
                    {
                        ModbusTcpServer.get().ReadFloat(plcaddress.address, 1, val -> {
                            ReturnsVariable[0] = val[0];
                        });
                    }
                    if ((plcaddress.address.toUpperCase().equals("VW82"))){
                        MessageLog.ShowInfo("ReadPLC  称当前重量  name=" +name+" ReturnsVariable[0]="+ReturnsVariable[0] );
                        OutletWeigh = (short)ReturnsVariable[0];

                    }
                }
            }
        } catch (Exception ex) {
            ToastUtils.error("异常信息:" + ex.getMessage());
        } finally {
            MessageLog.ShowInfo("ReadPLC  name=" +name+" ReturnsVariable[0]="+ReturnsVariable[0] );
            return ReturnsVariable[0];
        }
    }

    public static boolean ReadBool(Object plcName){
        MessageLog.ShowInfo("ReadBool  plcName=" +plcName.toString() );
        try{
            if(ListeningValue.containsKey(plcName)){
                return Boolean.parseBoolean(ListeningValue.get(plcName).toString());
            }else{
                return Boolean.parseBoolean(ReadPLC(plcName.toString()).toString());
            }
        }catch(Exception e){
            return false;
        }
    }

    public static short ReadShort(Object plcName){
        MessageLog.ShowInfo("ReadShort "+plcName.toString());
        try{
            if(ListeningValue.containsKey(plcName)){
                short result = Short.parseShort(ListeningValue.get(plcName).toString());
                MessageLog.ShowInfo(plcName.toString()+"   result="+result);
                return result;
            }else{
                short result = Short.parseShort(ReadPLC(plcName.toString()).toString());
                MessageLog.ShowInfo(plcName.toString()+"   result="+result);
                return result;
            }
        }catch(Exception e){
            return 0;
        }
    }

    public static int ReadInt(Object plcName){
        try{
            if(ListeningValue.containsKey(plcName)){
                return Integer.parseInt(ListeningValue.get(plcName).toString());
            }else{
                return Integer.parseInt(ReadPLC(plcName.toString()).toString());
            }

        }catch(Exception e){
            return 0;
        }
    }

    /**
     * 读PLC数据
     *
     * @param name
     * @return
     */
    public static Object[] ReadPLC(String name,int length) {
        final Object[] ReturnsVariable = new Object[length];
        try {
            if (ConfigName.getInstance().PLC_Address.containsKey(name)) {
                BPA_PLCADDRESS plcaddress = ConfigName.getInstance().PLC_Address.get(name);
                if (!plcaddress.address.isEmpty() && ConfigName.getInstance().PlcIsConnect) {
                    if (plcaddress.address.toUpperCase().startsWith("VD"))//int
                    {
                        ModbusTcpServer.get().ReadInt(plcaddress.address, length, val -> {
                            for (int i = 0; i < length; i++) {
                                ReturnsVariable[i] = val[i];
                            }
                        });
                    } else if (plcaddress.address.toUpperCase().startsWith("M"))//bool
                    {
                        ModbusTcpServer.get().ReadBool(plcaddress.address, length, val -> {
                            for (int i = 0; i < length; i++) {
                                ReturnsVariable[i] = val[i];
                            }
                        });
                    } else if (plcaddress.address.toUpperCase().startsWith("VW"))//short
                    {
                        ModbusTcpServer.get().ReadShort(plcaddress.address, length, val -> {
                            for (int i = 0; i < length; i++) {
                                ReturnsVariable[i] = val[i];
                            }
                        });
                    } else if (plcaddress.address.toUpperCase().startsWith("VR"))//float
                    {
                        ModbusTcpServer.get().ReadFloat(plcaddress.address, length, val -> {
                            for (int i = 0; i < length; i++) {
                                ReturnsVariable[i] = val[i];
                            }
                        });
                    }
                }
            }
        } catch (Exception ex) {
            ToastUtils.error("异常信息:" + ex.getMessage());
        } finally {
            return ReturnsVariable;
        }
    }

    /**
     * 根据地址写 PLC数据 bool
     *
     * @return
     */
    public static void WritePLCSD(String address ,boolean value, IWriteCallBack callback) {
        try {
            if (ConfigName.getInstance().PlcIsConnect) {
                ModbusTcpServer.get().WriteBool(address, (boolean) value, callback);
            }
        } catch (Exception ex) {
            ToastUtils.error("异常信息:" + ex.getMessage());
        } finally {
        }
    }

    /**
     * 获取实时状态
     *
     * @param ch
     * @return
     */
    public static boolean getConcurrentHash(int ch) {
        if (!IoStatus.containsKey(ch)) {
            return false;
        }
        return IoStatus.get(ch);
    }

    /**
     * 获取监听变量
     *
     * @param
     * @return
     */
    public static Object getListingValue(String name) {
        if (!ListeningValue.containsKey(name)) {
            return null;
        }
        return ListeningValue.get(name);
    }

    /**
     * 读取状态
     */
    public static void ReadPLCStatus() {
        try {
            if (ConfigName.getInstance().PLC_Address.containsKey("实时状态")) {
                BPA_PLCADDRESS plcaddress = ConfigName.getInstance().PLC_Address.get("实时状态");
                if (!plcaddress.address.isEmpty() && ConfigName.getInstance().PlcIsConnect) {
                    ModbusTcpServer.get().ReadStatus(plcaddress.address, 4, (data) -> {
                        for (int i = 0; i < data.length; i++) {
                            byte status=data[i];//0x92
                            IoStatus.put(i*8+0, ByteHelper.getBit(status,0)==1);
                            IoStatus.put(i*8+1, ByteHelper.getBit(status,1)==1);
                            IoStatus.put(i*8+2, ByteHelper.getBit(status,2)==1);
                            IoStatus.put(i*8+3, ByteHelper.getBit(status,3)==1);
                            IoStatus.put(i*8+4, ByteHelper.getBit(status,4)==1);
                            IoStatus.put(i*8+5, ByteHelper.getBit(status,5)==1);
                            IoStatus.put(i*8+6, ByteHelper.getBit(status,6)==1);
                            IoStatus.put(i*8+7, ByteHelper.getBit(status,7)==1);
                        }
                    });
                }
            }
        } catch (Exception ex) {
            ToastUtils.error("异常信息:" + ex.getMessage());
        } finally {
        }
    }

    /**
     * 读取扫码信息
     */
    public static void ReadCode() {
        try {
            if (ConfigName.getInstance().PLC_Address.containsKey("扫码数据")) {
                BPA_PLCADDRESS plcaddress = ConfigName.getInstance().PLC_Address.get("扫码数据");
                if (!plcaddress.address.isEmpty() && ConfigName.getInstance().PlcIsConnect) {
                    ModbusTcpServer.get().ReadString(plcaddress.address, 39, (data) -> {

                        if(!data.isEmpty() && !Code.equals(data) && OnScanTheCodeInformationT != null)
                        {
                            Log.d("信息", "扫码数据: "+data);
                            OnScanTheCodeInformationT.Run(data);
                            ModbusTcpServer.get().WriteString(plcaddress.address, 39, null);
                        }

                        //记录上一次读取PLC 扫码数据
                        Code = data;
                    });
                }
            }

//            if (ConfigName.getInstance().PLC_Address.containsKey("配料次数")) {
//                BPA_PLCADDRESS plcaddress = ConfigName.getInstance().PLC_Address.get("配料次数");
//                if (!plcaddress.address.isEmpty() && ConfigName.getInstance().PlcIsConnect) {
//                    ModbusTcpServer.get().ReadInt(plcaddress.address, 1, (data) -> {
//                        MakeGoodCount=data[0] ;
//                    });
//                }
//            }
        } catch (Exception ex) {
            ToastUtils.error("异常信息:" + ex.getMessage());
        } finally {
        }
    }

    /**
     * 信号检测
     */
    public static void ChargeSignal() {
        try {

            //配料完成 M0.3
            CompleteListen("配料完成", OnChargeMixtureCompleteNotify);

            //按钮状态 M0.5
            CompleteListen( "按钮启动", OnIngredientButtonPressedNotify);

            //校准校正完成信号 M0.7
            CompleteListen( "校准完成", OnChargeMixtureComNotPar);

            //清洗完成标志
            CompleteListen( "自动清洗完成", CleaningComplete);

            //管道自动排水完成
            CompleteListen( "管道自动排水完成", AutoPaiShui);

        } catch (Exception ex) {
            ToastUtils.error("异常信息:" + ex.getMessage());
        } finally {
        }
    }

    /**
     * 自动加热
     */
//    public static void AutoJR() {
//        try {
//
//            if(ConfigName.getInstance().PlcIsConnect)
//            {
//
//                for (String item:names)
//                {
//                    boolean isopen=false;
//                    if(item.equals("水池温度"))
//                    {
//                        isopen=ConfigName.getInstance().AutomaticHeating;
//                    }else if(item.equals("果糖左温度"))
//                    {
//                        isopen=ConfigName.getInstance().GT1_AutomaticHeating;
//                    }else if(item.equals("果糖右温度"))
//                    {
//                        isopen=ConfigName.getInstance().GT2_AutomaticHeating;
//                    }
//
//                    if(isopen)
//                    {
//                        Object sc= ReadPLC(item);
//                        Object scsz= ReadPLC(item+"设置");
//
//                        int sx_temp=sc==null?0:(int)sc;//水箱温度
//                        int sx_temp_sz=scsz==null?0:(int)scsz;//水箱温度设置值
//                        if(sx_temp_sz>0)
//                        {
//                            if(sx_temp>=sx_temp_sz)
//                            {
//                                WritePLC(item+"加热",false,null);
//                            }else
//                            {
//                                WritePLC(item+"加热",true,null);
//                            }
//                        }
//                    }
//                }
//
//                //自动补水
//                if(ConfigName.getInstance().AutomaticWaterRefill)
//                {
//                    Object yw= ReadPLC("水池液位检测");
//                    boolean isopen=yw==null?false:(boolean) yw;
//                    if(!isopen)
//                    {
//                        WritePLC("水池进水阀",true,null);
//                    }else
//                    {
//                        if(yw!=null )
//                        {
//                            Object jsf= ReadPLC("水池进水阀");
//                            if(jsf!=null && (boolean)jsf)
//                            {
//                                new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
//                                    @Override
//                                    public void run() {
//                                        WritePLC("水池进水阀",false,null);
//                                    }
//                                }, (int)Math.round((Double.parseDouble(ConfigName.getInstance().AutomaticWaterRefillTime) * 1000)));
//                            }
//                        }
//                    }
//                }
//            }
//        } catch (Exception ex) {
//            ToastUtils.error("异常信息:" + ex.getMessage());
//        } finally {
//        }
//    }

    /**
     * 完成信号监听
     *
     * @param name     监听 KEY
     * @param callback 执行委托
     */
    private static void CompleteListen(String name, IRun callback) {
//        if (ConfigName.getInstance().PLC_Address.containsKey(name)) {
//            BPA_PLCADDRESS plcaddress = ConfigName.getInstance().PLC_Address.get(name);
//            if (!plcaddress.address.isEmpty() && ConfigName.getInstance().PlcIsConnect) {
//                ModbusTcpServer.get().ReadBool(plcaddress.address, 1, booleans -> {
//                    RTrig.get(name).Start(booleans[0], () -> {
//                        if (callback != null)
//                            callback.Run();
//                    });
//                });
//            }
//        }

        if(ListeningValue.containsKey(name)){
            boolean res = Boolean.parseBoolean(ListeningValue.get(name).toString());
            RTrig.get(name).Start(res,()->{if(callback!=null)callback.Run();});
        }

    }
    //endregion

    //region 电子称校验

    /**
     * 启动校验模式
     */
    public static boolean StartJiaoYanMode()
    {
        final boolean[] issucess1 = {false};
        final boolean[] issucess2 = {false};
        final boolean[] issucess3 = {false};

        //写校准模式
        WritePLC("校准模式", true, new IWriteCallBack() {
            @Override
            public void onSuccess() {
                issucess1[0] =true;
            }

            @Override
            public void onFailure(String ErrorMsg) {

            }
        });
        WritePLC("关闭写保护", true, new IWriteCallBack() {
            @Override
            public void onSuccess() {
                issucess2[0] =true;
            }
            @Override
            public void onFailure(String ErrorMsg) {

            }
        });

        WritePLC("零点校准", true, new IWriteCallBack() {
            @Override
            public void onSuccess() {
                issucess3[0] =true;
            }
            @Override
            public void onFailure(String ErrorMsg) {

            }
        });
        return issucess1[0] && issucess2[0]&& issucess3[0];
    }

    /**
     * 停止校验模式
     */
    public static boolean StopJiaoYanMode()
    {
        final boolean[] issucess1 = {false};
        final boolean[] issucess2 = {false};

        //写校准模式
        WritePLC("校准模式", false, new IWriteCallBack() {
            @Override
            public void onSuccess() {
                issucess1[0] =true;
            }

            @Override
            public void onFailure(String ErrorMsg) {

            }
        });
        WritePLC("打开写保护", true, new IWriteCallBack() {
            @Override
            public void onSuccess() {
                issucess2[0] =true;
            }
            @Override
            public void onFailure(String ErrorMsg) {

            }
        });
        return issucess1[0] && issucess2[0];
    }
    //endregion
}
