package com.device.comm.mylibrary;

import android.content.Context;
import android.content.SharedPreferences;
import android.os.Build;
import android.provider.Settings;
import android.util.Log;


import com.android.pj11.PJ11UartJni;
import com.device.comm.mylibrary.NativeDevice.ByteUtil;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.WritableMap;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Random;

//import android_serialport_api.SerialPort;

/**
 * Created by lvwang2002 on 2019/3/26.
 */

public class RNYASEEGlucoseModule extends ReactContextBaseJavaModule {
    private Context mContext;
    final private static String TAG = "RN_YASEE_GLUCOSE_MODULE";
    public KOJNativeEventManager mEventManager;
    private BleDeviceManager deviceManager = null;
    private String connectDeviceMac = "";
    public static RNYASEEGlucoseModule yaseeGlucoseModuel = null;
    private static final String GLUCOSE_DEVICE = "glucose";
    private static final String LIPID_DEVICE = "lipid";
    private String deviceType = "";
    public static final int KEYCODE_PLUG_IN_UART = 292;//外设插入
    public static final int KEYCODE_PLUG_OUT_UART = 293;//外设拔出

    private static final SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");

    private static final String MODEL = "PDA-M10";
//    SerialPort mserialport;
    private boolean isStop = false;
    String path = "/dev/ttyS1";
    //    String path = "/dev/ttyS3";
    int baudrate = 9600;
    private OutputStream mOutputStream;
    private InputStream mInputStream;
    private ReadThread mReadThread;
    private CheckDeviceThread checkDeviceThread;
    public static int uartState = -1;
    public boolean findDevice = false;
    private static final int DATA_MAX_LENGTH = 1024;
    private Integer resultType = 0;

    private RNM10GKUCommandHandler GKUCommandHandler;
    private RNM10LMCommandHandler LMCommandHandler;

    private static final String PREFS_NAME = "M10_MAC_APP";
    private static final String PREFS_KEY = "RandomMAC";

    @Override
    public String getName() {
        return "RNYASEEGlucoseModule";
    }

    public RNYASEEGlucoseModule(ReactApplicationContext reactContext) {
        super(reactContext);
        mContext = reactContext;
        mEventManager = new KOJNativeEventManager(reactContext);
        deviceManager = BleDeviceManager.get(mContext);
        yaseeGlucoseModuel = this;
        GKUCommandHandler = new RNM10GKUCommandHandler(reactContext);
        LMCommandHandler = new RNM10LMCommandHandler(reactContext);
        ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE_MAC = getRandomMAC(reactContext);
        init();
    }


    private void init() {
        try {
            Log.d(TAG,"init");
            String model= android.os.Build.MODEL;
            RNLog.d(TAG,"model:"+model);

            cleanReciveBytes();

            mReadThread = new ReadThread();
            isStop = false;
            mReadThread.start();
//            RNLog.d(TAG,"open successful "+ uartState);
//            checkDeviceThread = new  CheckDeviceThread();
//            checkDeviceThread.start();

        } catch (Exception e) {
            e.printStackTrace();
            RNLog.d(TAG,"init error !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!  " + e.toString());
        }

    }

    public static String getRandomMAC(Context context) {
        SharedPreferences sharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);

        // 如果已经存在保存的字符串，读取它。否则，生成一个新的随机字符串
        String randomMAC = sharedPreferences.getString(PREFS_KEY, null);
        if (randomMAC == null) {
            randomMAC = generateRandomMAC();
            sharedPreferences.edit().putString(PREFS_KEY, randomMAC).apply();
        }

        return randomMAC;
    }

    private static String generateRandomMAC() {
        Random random = new Random();
        byte[] macAddr = new byte[6];
        random.nextBytes(macAddr);

        StringBuilder sb = new StringBuilder(18);
        for(byte b : macAddr){
            if(sb.length() > 0)
                sb.append(":");
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }

    public void deviceStatusChanged(int status){
        switch (deviceType) {
            case GLUCOSE_DEVICE:
                GKUCommandHandler.deviceStatusChanged(status);
                break;
            case LIPID_DEVICE:
                LMCommandHandler.deviceStatusChanged(status);
                break;
            default:
                RNLog.d(TAG,"Invalid value: "+deviceType);
                break;
        }



        if(status == KEYCODE_PLUG_OUT_UART){

            findDevice = false;
            BleDevice device = BleDeviceManager.get(mContext).getSerialPortDevice(ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE_MAC);
            if(device==null){
                return;
            }
            BleDeviceManager.get(mContext).removeDevice(device);
        }else if(status == KEYCODE_PLUG_IN_UART){
            BleDevice device = BleDeviceManager.get(mContext).addSerialPortDevice(ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE_MAC,ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE);
            long currentTime = System.currentTimeMillis()+(long)30*24*3600*1000;
            device.setDeviceDate(currentTime);
            findDevice = false;
        }
    }

    @ReactMethod
    public void getM10Status(Callback callback) {
        callback.invoke(findDevice);
    }

    private synchronized void postDelay(Runnable runnable,long delayMillis){
        final UpdateLoop updateLoop = BleDeviceManager.get(mContext).getMainUpdateLoop();
        updateLoop.postDelay(runnable,delayMillis);
    }




    private static int current_size;
    private static byte[] recive_btyes;

    private class ReadThread extends Thread {
        @Override
        public void run() {
//            Log.d("ReadThread", "run: my thread");
            while (!isStop) {
                if (Thread.currentThread().isInterrupted()) {
                    break;
                }
                if (uartState != 0) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    continue;
                }
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                try {
                    byte[] buffer = new byte[DATA_MAX_LENGTH];
//                    int size = mInputStream.read(buffer);
                    int size = PJ11UartJni.readPJ11Uart(buffer);
                    RNLog.d(TAG,"size:"+size);
                    if (size > 0) {
                        StringBuffer sb = new StringBuffer();
                        sb.append("进数据-----------------");
                        for(int i =0;i<size;i++){
                            sb.append(filterByte(HexUtils.int2HexIntString(buffer[i])));
                            sb.append(" ");
                        }
                        RNLog.d(TAG,sb.toString());
//                        commandHandler(buffer);
                        onFragmentDataIn(buffer, size);
                    }
//                    mInputStream.close();
                } catch (Exception e) {
                    e.printStackTrace();
                    RNLog.d(TAG,"serial error --- " + e.toString());
                }


            }
        }

    }

    private class CheckDeviceThread extends Thread {
        @Override
        public void run() {
            while (true) {

                if(findDevice){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    continue;
                }
            try {
                String status = readDeviceStatus();
//                RNLog.d(TAG,"device status:"+status);
                if(status.startsWith("0")){
                    Thread.sleep(1000);
                    continue;
                }

            } catch (Exception e) {
                e.printStackTrace();
            }


                if(uartState!=0){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    continue;

                }
                sendHeartbeat();
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void sendHand(){
        byte[] data = {(byte)0xAA,(byte)0x55,(byte)0x04,(byte)0x81,(byte)0xFF,(byte)0x01,(byte)0x80};
        int result = PJ11UartJni.sendPJ11Uart(data,7);
        Log.d(TAG,"send result: "+result);
    }

    public void sendHeartbeat(){
        byte[] data = {(byte)0xAA,(byte)0x55,(byte)0x04,(byte)0x8c,(byte)0x01,(byte)0x00,(byte)0x8d};
        int result = PJ11UartJni.sendPJ11Uart(data,7);
        Log.d(TAG,"send result: "+result);
    }
    public void sendSleep(){
        byte[] data = {(byte)0xAA,(byte)0x55,(byte)0x04,(byte)0x82,(byte)0x01,(byte)0x00,(byte)0x83};
        int result = PJ11UartJni.sendPJ11Uart(data,7);
        Log.d(TAG,"send result: "+result);
    }

    //把新进的数据拷贝进入累加数据
    private byte[] addBytes(byte[] oldBytes, int old_length, byte[] newBytes, int copy_length) {
        System.arraycopy(newBytes, 0, oldBytes, old_length, copy_length);
        return oldBytes;
    }

    //清空累加数据
    private void cleanReciveBytes() {
        current_size = 0;
        recive_btyes = new byte[DATA_MAX_LENGTH];
    }

    //删掉一段数据
    private byte[] delBytes(byte[] oldBytes, int indexStart, int length) {
        byte[] newBytes = new byte[DATA_MAX_LENGTH];
        int copy_index = 0;
        for (int i = 0; i < oldBytes.length; i++) {
            if (i >= indexStart && i <= length-1) {
                continue;
            }
            newBytes[copy_index] = oldBytes[i];
            copy_index++;
        }
        return newBytes;
    }

    //有数据片段进来
    private void onFragmentDataIn(byte[] newBytes, int size) {
        if(size == 4){
            if(((newBytes[0]&0xff)== 0xaa) && ((newBytes[1]&0xff)== 0x55) && ((newBytes[2]&0xff)== 0xaa) && ((newBytes[3]&0xff)== 0x55) ){
                commandHandler(newBytes,size);
                return;
            }
        }

        if(current_size<0){
            Log.d(TAG,"the value is not correct");
            cleanReciveBytes();
            return;
        }

        if((size+current_size)>DATA_MAX_LENGTH){
            Log.d(TAG,"out of max data");
            cleanReciveBytes();
            return;
        }


        //把新数据累加
        if (newBytes != null && size != 0) {
            recive_btyes = addBytes(recive_btyes, current_size, newBytes, size);
            current_size += size;
        }

        //判断累加后的数据，是否包含一条完整语句
        byte[] resultData = isHaveResultData(recive_btyes, current_size);
        //包含一条完整语句
        if (resultData != null) {
            RNLog.d(TAG,"command is:"+Bytes2HexString(resultData,0,resultData.length));
//            commandHandler(resultData,resultData.length);
            commandHandler(resultData);
            if (needDeleteFrontOfResultData > 0) {
                //需要删除冗余数据，则删除
                recive_btyes = delBytes(recive_btyes, 0, needDeleteFrontOfResultData);
                current_size -= needDeleteFrontOfResultData;
            }

            //把这条完整的语句从累加数据中删除
            recive_btyes = delBytes(recive_btyes, 0,resultData.length);
            current_size -= resultData.length;

            //删除后再次判断，后面是否含有完整语句
            onFragmentDataIn(null, 0);
        }
        //不包含一条完整语句
        else {
            RNLog.d(TAG,"not a command");
        }
    }




    //byte数组中包含一条完整语句，且语句前的needDeleteFrontOfResultData个数据是冗余数据
    private int needDeleteFrontOfResultData;

    //判断byte[]是否包含一条完整语句，有则返回一个ResultData对象
    private byte[] isHaveResultData(byte[] checkBytes, int checkSize) {
        needDeleteFrontOfResultData = 0;
        RNLog.d(TAG,"check is Have Result Data "+checkSize);
//        printData(checkBytes,checkSize);
        int checkIndex = 0;
        for (int a = 0; a < checkSize-1; a++) {
            if (HexUtils.getUnsignedByte(checkBytes[a]) != 0xAA && HexUtils.getUnsignedByte(checkBytes[a+1]) != 0x55) {
                //不是帧头continue
                RNLog.d(TAG,"not a start");
                continue;
            }
            //找到帧头
            checkIndex = a;
            int surplus_size = checkSize - checkIndex;//从checkIndex到checkSize剩余多少个长度

            //该条数据的长度，是否可能包含了完整的语句 1 surplus_size>=5 2 帧长<=surplus_size-1（帧头）-1（帧长）-1（校验和）
            boolean maybeCompleteData = surplus_size >= 4 && HexUtils.getUnsignedByte(checkBytes[2 + checkIndex]) <= surplus_size - 2 - 1;
            RNLog.d(TAG,"first check "+maybeCompleteData);
            if (maybeCompleteData) {
                //有可能包含一条完整语句
                int frame_length = HexUtils.getUnsignedByte(checkBytes[2 + checkIndex]);//帧长
                int funtion_id = HexUtils.getUnsignedByte(checkBytes[3 + checkIndex]);//功能字
                int device_id = HexUtils.getUnsignedByte(checkBytes[4 + checkIndex]);//设备ID
                int index_sum = 1 + frame_length + checkIndex;//校验和所在的index
                if (index_sum > checkSize) {
                    RNLog.d(TAG,"check index out");
                    return null;
                }

                int data_length = frame_length - 4;
                if (data_length < 0) {
                    continue;
                }

                int result_length = 2 + 1 + 1 + 1 + data_length + 2;
                byte[] resultBytes = new byte[result_length];
                System.arraycopy(checkBytes, checkIndex, resultBytes, 0, result_length);

                needDeleteFrontOfResultData = checkIndex;

                return resultBytes;
//                }

            }

        }
        return null;
    }


    private boolean checkCommand(byte[] checkBytes){
        if(checkBytes.length<5){
            return false;
        }


        if (HexUtils.getUnsignedByte(checkBytes[0]) != 0xAA && HexUtils.getUnsignedByte(checkBytes[1]) != 0x55) {
            //不是帧头continue
            RNLog.d(TAG,"not a start");
            return false;
        }

        return true;
    }

    public void sendAck(byte command){
        byte[] list = {command,(byte)0x01,(byte)0x00};
        int verifyValue = countVerify(list);

        byte[] sendCmd = {(byte)0xaa,(byte)0x55,(byte)0x05,command,(byte)0x01,(byte)0x00,(byte)(verifyValue>>8),(byte)(verifyValue%256)};
        int result = PJ11UartJni.sendPJ11Uart(sendCmd,8);
        RNLog.d(TAG,"send ack "+(command&0xff));
    }

    private int countVerify(byte[] dataList){
        int verifyData = 0;
        for(byte data:dataList){
            verifyData = verifyData + (data&0xff);
        }
        return verifyData;

    }

    //过滤ffffff
    private static String filterByte(String str) {
        if (str.length() ==8 && str.substring(0, 6).equals("ffffff")) {
            str = str.substring(6, 8);
        }
        return str;
    }



    private void commandHandler(byte[] data){
        RNLog.d(TAG,"command handler "+deviceType);
        if (data.length > 4) { // Ensure we have at least 5 elements in the array
//            int command = data[4]&0xff;
            switch (deviceType) {
                case GLUCOSE_DEVICE:
                    GKUCommandHandler.commandHandler(data,data.length);
                    break;
                case LIPID_DEVICE:
                    LMCommandHandler.commandHandler(data,data.length);
                    break;
                default:
                    RNLog.d(TAG,"Invalid value: "+deviceType);
                    break;
            }
        }
    }


    private  void commandHandler(byte[] data,int length){
        Log.d(TAG,"data length "+data.length);
        if(length == 4){
            Log.d(TAG,"awake "+(data[0]&0xff));
            if(((data[0]&0xff)== 0xaa) && ((data[1]&0xff)== 0x55) && ((data[2]&0xff)== 0xaa) && ((data[3]&0xff)== 0x55) ){
                findDevice = false;
                sendStatus("请插入试纸",0x01,0);
                BleDevice device = BleDeviceManager.get(mContext).addSerialPortDevice(ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE_MAC,ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE);
                long currentTime = System.currentTimeMillis()+(long)30*24*3600*1000;
                device.setDeviceDate(currentTime);
            }

            return;
        }

        if(!checkCommand(data)){
            return;
        }

         int command = data[3]&0xff;
         switch (command){
             case 0x80:{
                 findDevice = false;
                 sendStatus("请插入试纸",command,0);
                 BleDevice device = BleDeviceManager.get(mContext).addSerialPortDevice(ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE_MAC,ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE);
                 long currentTime = System.currentTimeMillis()+(long)30*24*3600*1000;
                 device.setDeviceDate(currentTime);

                 postDelay(new Runnable() {
                     @Override
                     public void run() {
                         sendAck((byte)0x80);
                     }
                 },100);
             }
             break;
             case 0x81:{
                 Log.d(TAG,"command is "+(data[3]&0xff));
                 findDevice = true;
                 sendStatus("请插入试纸",command,0);
                 BleDevice device = BleDeviceManager.get(mContext).addSerialPortDevice(ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE_MAC,ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE);
                 long currentTime = System.currentTimeMillis()+(long)30*24*3600*1000;
                 device.setDeviceDate(currentTime);
                 //             sendStatus(data[i+4]&0xff);

             }
             break;
             case 0x82:{
                 //休眠
                 Log.d(TAG,"sleep command is "+(data[3]&0xff));

                 postDelay(new Runnable() {
                     @Override
                     public void run() {
                         sendStatus("设备休眠，请重新插入试纸",0x82,0);
                     }
                 },300);
                 findDevice = true;
                 postDelay(new Runnable() {
                     @Override
                     public void run() {
                         sendAck((byte)0x82);
                     }
                 },100);
             }
             break;
             case 0x83:{
                 //插入试纸
                 Log.d(TAG,"command is "+(data[3]&0xff));
                 resultType = data[8]&0xff;
                 if((data[7]&0xff) == 0x00){
                    //血糖试纸插入
                     sendStatus("请采集血样",command,0);

                 }else{
                    sendStatus("无效试纸插入",command,0);
                 }


                 postDelay(new Runnable() {
                     @Override
                     public void run() {
                         sendAck((byte)0x83);
                     }
                 },100);
             }
             break;
             case 0x86:{
                 //吸血
                 Log.d(TAG,"command is "+(data[3]&0xff));
                 sendStatus("检测到血样",command,0);
                 postDelay(new Runnable() {
                     @Override
                     public void run() {
                         sendAck((byte)0x86);
                     }
                 },100);
             }
             break;
             case 0x87:{
                 //倒计时
                 Log.d(TAG,"command is "+(data[3]&0xff));
                 sendStatus("检测倒计时："+(data[5]&0xff),command,(data[5]&0xff));
                 postDelay(new Runnable() {
                     @Override
                     public void run() {
                         sendAck((byte)0x87);
                     }
                 },100);
             }
             break;
             case 0x88:{
                 //血糖结果
                 Log.d(TAG,"command is "+(data[3]&0xff));
                 int value = (data[8]&0xff)*256+(data[7]&0xff);
                 sendStatus("",command,0);
                 sendValue(value);
                 postDelay(new Runnable() {
                     @Override
                     public void run() {
                         sendAck((byte)0x88);
                     }
                 },100);
             }
             break;
             case 0x8b:{
                 //进入错误模式
                 Log.d(TAG,"command is "+(data[3]&0xff));
                 sendErrorValue(data[7]&0xff);
                 postDelay(new Runnable() {
                     @Override
                     public void run() {
                         sendAck((byte)0x8b);
                     }
                 },100);
                 postDelay(new Runnable() {
                     @Override
                     public void run() {
                         sendSleep();
                     }
                 },10*1000);
             }
             break;
             case 0x8c:{
                 Log.d(TAG,"command is "+(data[3]&0xff));
                 findDevice = true;
                 sendStatus("请插入试纸",command,0);
                 BleDevice device = BleDeviceManager.get(mContext).addSerialPortDevice(ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE_MAC,ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE);
                 long currentTime = System.currentTimeMillis()+(long)30*24*3600*1000;
                 device.setDeviceDate(currentTime);
                 //             sendStatus(data[i+4]&0xff);

                 postDelay(new Runnable() {
                     @Override
                     public void run() {
                         sendHand();
                     }
                 },300);
             }
             break;
         }
    }

    public void sendStatus(String status,Integer command,Integer extraParameter){
//        SimpleDateFormat formatter =new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
        Date curDate = new Date(System.currentTimeMillis());//获取当前时间
        String curDateString = dateFormatter.format(curDate);
        String type = "";
        String eventName = "";
        if(resultType == 0x10){
            type = "glucose";
            eventName = "STATUS_GLUCOSE_DEVICE";
        }else if(resultType == 0x40){
            type = "acid";
            eventName = "STATUS_ACID_DEVICE";
        }else{
            type = "ketone";
            eventName = "STATUS_KETONE_DEVICE";
        }

        // 如果command是0x00或0x01，强制将type设置为"M10"
        if (command == 0x00 || command == 0x01 || command == 0x82) {
            type = "M10";
            eventName = "STATUS_M10_DEVICE";
        }

        WritableMap map = Arguments.createMap();
        map.putString("deviceName", "one");
        map.putString("deviceMac", "no");
        map.putString("deviceStatusDescription", "测量成功");
        map.putString("deviceStatus", "result");
        map.putString("time", curDateString);
        map.putString("deviceTime", curDateString);
        map.putString("status", status);
        map.putString("resultType", type);
        map.putInt("command",command);
        map.putInt("extraParameter", extraParameter);
        RNLog.d(TAG,"send map:"+map);
        mEventManager.sendCustomEvent(eventName, map);
    }


    public void sendValue(int value){
//        SimpleDateFormat formatter =new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
        Date curDate = new Date(System.currentTimeMillis());//获取当前时间
        String curDateString = dateFormatter.format(curDate);
        String displayValue = "";
        String type = "";
        String eventName = "";
        if(resultType == 0x10){
            displayValue =  new BigDecimal(value*0.055).setScale(1, RoundingMode.HALF_UP).toString();
            type = "glucose";
            eventName = "RESULT_BT_DEVICE";
        }else if(resultType == 0x40){
            displayValue =new BigDecimal((float)(value/168.1)).setScale(3,BigDecimal.ROUND_DOWN).multiply(new BigDecimal(1000)).toString();
            type = "adid";
            eventName = "RESULT_ACID";
        }else{
            displayValue =  new BigDecimal(value*0.1).setScale(1, RoundingMode.HALF_UP).toString();
            type = "ketone";
            eventName = "RESULT_BT_DEVICE";
        }
        WritableMap map = Arguments.createMap();
        map.putString("deviceName", "one");
        map.putString("deviceMac", "no");
        map.putString("deviceStatusDescription", "测量成功");
        map.putString("deviceStatus", "result");
        map.putString("time", curDateString);
        map.putString("deviceTime", curDateString);
        map.putString("value", displayValue);
        map.putString("displayValue", displayValue);
        map.putString("resultType", type);

        RNLog.d(TAG,"send value:"+map);

        mEventManager.sendCustomEvent(eventName, map);
    }


    public void sendErrorValue(int value){
        SimpleDateFormat formatter =new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
        Date curDate = new Date(System.currentTimeMillis());//获取当前时间
        String curDateString = formatter.format(curDate);
        String errorMessage = "";
        switch (value){
            case 0x03:
                errorMessage="EEPROM读错误";
            break;
            case 0x04:
                errorMessage="EEPROM写错误";
            break;
            case 0x17:
                errorMessage="错误试纸";
            break;
            case 0x18:
                errorMessage="无效试纸";
            break;
            case 0x2d:
                errorMessage="测试过程中断";
                break;
            case 0x36:
                errorMessage="温度越限";
                break;
            case 0x3e:
                errorMessage="参数错误";
                break;
            case 0x4d:
                errorMessage="通讯错误";
                break;
        }

        if(errorMessage.equals("")){
            return;
        }

        String hex = Integer.toHexString(value);
        if (hex.length() == 1) {
            hex = '0' + hex ;
        }
        errorMessage = errorMessage + " " +  hex.toUpperCase();

        String type = "";
        String eventName = "";
        if(resultType == 0x10){
            type = "glucose";
            eventName = "STATUS_GLUCOSE_DEVICE";
        }else if(resultType == 0x40){
            type = "acid";
            eventName = "STATUS_ACID_DEVICE";
        }else{
            type = "ketone";
            eventName = "STATUS_KETONE_DEVICE";
        }

        WritableMap map = Arguments.createMap();
        map.putString("deviceName", "one");
        map.putString("deviceMac", "no");
        map.putString("deviceStatusDescription", "测量成功");
        map.putString("deviceStatus", "result");
        map.putString("time", curDateString);
        map.putString("deviceTime", curDateString);
        map.putString("errorMessage",errorMessage);
        map.putString("status",errorMessage);
        map.putString("resultType", type);


        mEventManager.sendCustomEvent(eventName, map);
    }

    @ReactMethod
    public void openGKUUART(){
        deviceType = GLUCOSE_DEVICE;
        GKUCommandHandler.startCheckThread();
        openUART(9600);
    }

    @ReactMethod
    public void openLMUART(){
        deviceType = LIPID_DEVICE;
        LMCommandHandler.startCheckThread();
        openUART(115200);
    }

    public  void openUART(int baudrate){
        RNLog.d(TAG,"model:"+android.os.Build.MODEL);
        if(!Build.MODEL.startsWith(MODEL)){
            return;
        }

        try {
            uartState =  PJ11UartJni.openPJ11Uart(baudrate);
            findDevice =false;
            RNLog.d(TAG,"open uart "+uartState+" baudrate:"+baudrate);
            String status = readDeviceStatus();
//            RNLog.d(TAG,"device status:"+status);
            if(status.startsWith("0")){
                sendStatus("设备未连接",0x00,0);
                return;
            }
            switch (deviceType) {
                case GLUCOSE_DEVICE:
                    GKUCommandHandler.sendInitStatus();
                    break;
                case LIPID_DEVICE:
                    LMCommandHandler.sendInitStatus();
                    break;
                default:
                    RNLog.d(TAG,"Invalid value: "+deviceType);
                    break;
            }
            BleDevice device = BleDeviceManager.get(mContext).addSerialPortDevice(ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE_MAC,ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE);
            long currentTime = System.currentTimeMillis()+(long)30*24*3600*1000;
            device.setDeviceDate(currentTime);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @ReactMethod
    public  void  closeUART(){
        if(!Build.MODEL.startsWith(MODEL)){
            return;
        }
        GKUCommandHandler.stopCheckThread();
        LMCommandHandler.stopCheckThread();
        RNLog.d(TAG,"close uart");
         PJ11UartJni.closePJ11Uart();
        uartState = -2;
        BleDevice device = BleDeviceManager.get(mContext).getSerialPortDevice(ENDeviceConst.DEVICE_TYPE_YASEE_UART_GLUCOSE_MAC);
        if(device == null){
            return;
        }
        BleDeviceManager.get(mContext).removeDevice(device);

    }

    public synchronized static String  readDeviceStatus() throws IOException {
        String result = null;
        try{
            String cmd = "/proc/driver/uart_state";
            BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(cmd)), 1000);
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null){
                sb.append(line).append("\n");
            }
            result = sb.toString();
//            RNLog.d(TAG,"/proc/driver/uart_state : " + sb.toString());
            reader.close();
        }catch (Exception ex){
            ex.printStackTrace();
            RNLog.d(TAG,"/proc/driver/uart_state exception : " + ex.toString());
        }
        return  result;
    }

    public static String Bytes2HexString(byte[] b, int start, int len) {
        String ret = "";
        for (int i = start; i < len; i++) {
            String hex = Integer.toHexString(b[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex ;
            }
            ret = ret + " " +  hex.toUpperCase();
        }
        return ret;
    }
}
