#include<SensorIS11.h>
#include"servo.h"
Ds1302 ds1302_date(0, 8, 7);
Ds1302::DateTime sys_time;

struct IS11_datastruct IS11_datastruct_fanshelv;

STRSensorInfo SensorIS11::initSensor()
{
   // IS1Sensor.SetPortName(id);
    pinMode(5,OUTPUT);
    pinMode(6,OUTPUT);
    radiance_struct_up.shutter = 1;
    radiance_struct_down.shutter = 1;

    for (uint32_t i = 0; i < 2048; i++)
    {
        radiance_struct_up.gain[i] = 1;
        radiance_struct_down.gain[i] = 1;
        radiance_struct_up.offset[i] = 0;
        radiance_struct_down.offset[i] = 0;
    }
    SensorInfo.BandNum = 2048;
    SensorInfo.maxValue = 65535;
    uint8_t buff[4];
    String  path2 = "/system/index.bin";
      File file;
    if(SD_MMC.exists(path2))
    {
      
        file = SD_MMC.open(path2,"rb");
        file.read(buff,4);
        file.flush();
        file.close();
        memcpy(&index,buff,4);

        write_log(log_path,"index is " + String(index),10);
    }

    return SensorInfo=GetSensorInfo();
    // return SensorInfo;
    // return true;
}

STRSensorInfo SensorIS11::GetSensorInfo()
{    
    // Serial.println("init ok");
    // write_log(log_path,"init isSensorInit",10);
    STRSensorInfo setem;
    if (!isSensorInit())
    {
        // Serial.println("sensor is 123123");
        // write_log(log_path,"sensor is 123123",10);
        return setem;
    }

      
    // write_log(log_path,"init ok",10);
    int retlenth= SendGetSensorInfo((u_char *)GET_SERIAL_NUMBER,sizeof(GET_SERIAL_NUMBER));
    vTaskDelay(100);
    // write_log(log_path,String(retlenth),10);

    char * result=new char[retlenth];
    memcpy(result,DataRetrun+3,retlenth);
    //result[4]='\0';
    // std::string str11(result);
    // setem.serialnumber = str11;
    setem.serialnumber = String(result);
    delete[] result;
    // Serial.println(String(setem.serialnumber.c_str()));
    
    // write_log(log_path,"serialnumber :"+String(setem.serialnumber.c_str()),10);
    // write_log(log_path,"serialnumber :"+setem.serialnumber,10);
    retlenth= SendGetSensorInfo((u_char *)GET_PRODUCT_NAME,sizeof(GET_PRODUCT_NAME));
    vTaskDelay(100);
    result=new char[retlenth];
    memcpy(result,DataRetrun+3,retlenth);
   // vTaskDelay(500);

    //  result[4]='\0';
    // std::string str1(result);
    // write_log(log_path,"productname :"+String(setem.SensorName.c_str()),10);

    setem.SensorName = String(result);
    // write_log(log_path,"productname :"+setem.SensorName,10);

    delete result;
    setem.BandNum=2048;
    // Serial.println(String(setem.SensorName.c_str())+"_"+String(setem.serialnumber.c_str()));
    // write_log(log_path,String(setem.SensorName.c_str())+"_"+String(setem.serialnumber.c_str()),10);
    
    setem.maxValue=65535;
    setem.wavelenthlist = new float[setem.BandNum]();
    retlenth= SendGetSensorInfo((u_char *)GET_WAVELENTH_COEFF,sizeof(GET_WAVELENTH_COEFF));
    vTaskDelay(100);
    float a[4];
    memcpy(a,DataRetrun+3,16); 
    
    // write_log(log_path,"CoverLittleAndBig",10);
    CoverLittleAndBig((char *)a,4*sizeof(float));
    int bandsss= setem.BandNum;
    #ifdef ARDUINO
    

    // Serial.print("a0:");
    // Serial.print(a[0]);
    // Serial.print("  a1:");
    // Serial.print(a[1]);
    // Serial.print("  a2:");
    // Serial.print(a[2]);
    // Serial.print("  a3:");
    // Serial.println(a[3]);
    // write_log(log_path,"ARDUINO",10);
    // write_log(log_path,"a0:"+String(a[0])+"  a1:"+String(a[1])+"  a2:"+String(a[2])+"  a3:"+String(a[3]),10);

    #endif
    setem.a1=a[0];
    setem.a2=a[1];
    setem.a3=a[2];
    setem.a4=a[3];
    for ( int i = 1; i <=bandsss ; i++)
    {
        setem.wavelenthlist[i-1] = a[0] * i*i*i + a[1] * i*i + a[2] * i + a[3];
        setem.WavelenthStr=setem.WavelenthStr+String( setem.wavelenthlist[i-1]).c_str()+",";
    }
    //  vTaskDelay(500);
    // Serial.write(dataretrun,retlenth);
   // memcpy(a,dataretrun+) 
   u_char temp[2]={0x00,0x01};
    retlenth=SendSettingCommand((u_char*)SET_AVERAGE_NUMBER,sizeof(SET_AVERAGE_NUMBER),temp,sizeof(temp));
    // Serial.println("init ok");

    return setem;  
}


//shutter1 1关  2开
void SensorIS11::SetShutter(int id)
{
    switch (id) {
        case 1:{ //关
            digitalWrite(5,LOW);
            vTaskDelay(200);
            break;
        }
        case 2:{ //开
            digitalWrite(5,HIGH);
            vTaskDelay(200);
            break;
        }
    }
}


//0下 1上
void SensorIS11::servo_direction(int direction)
{
    switch (direction) 
    {
        case 0:{ 
            // servo_set_angle(12);
            servo_down();
            vTaskDelay(1500);
            break;
        }
        case 1:{
            // servo_set_angle(200);
            servo_up();
            vTaskDelay(1500);
            break;
        }
    }    
}


///这获取到的是4096的那个数组
void SensorIS11::GetOneDate(int msc)
{
    if (msc!=shutternow)
    {
        u_char shutter[2];
        shutter[0]=msc/256;
        shutter[1]=msc%256;
        SendSettingCommand((u_char *) SET_INTEGRAL_TIME,sizeof(SET_INTEGRAL_TIME),shutter,sizeof(shutter));
    }
    shutternow=msc;

    size_t retsize= SendGetData(shutternow);
    //DATABUFF  4096  需要输出的数据
    memcpy(DATABUFF,DataRetrun+4,4096);
    shortLittletoBiG(DATABUFF, SensorInfo.BandNum*2);
}


//获取SHUTTER时间，返回的是最大值
// int SensorIS11::OptSnenser(int persent)
// {
//     long maxtime = 20000;
//     int maxvalue=SensorInfo.maxValue*1.0*persent / 100;
//     int maxvaluenow = 0;
//     static float shutternow = 100;
//     GetOneDate(100);
//     maxvaluenow= Getmaxvalue(DATABUFF, SensorInfo.BandNum);
//     // Serial.print("now Shutter is :");
//     // Serial.print(shutternow);
//     // Serial.print("  maxvalue is :");
//     // Serial.println(maxvaluenow);
//     // write_log(log_path,"now Shutter is :"+String(shutternow)+"  maxvalue is :"+String(maxvaluenow),10);

//     static int numberoftry;
//     write_log(log_path,"numberoftry is :"+String(numberoftry),10);
//     while (maxvaluenow<maxvalue*0.95 || maxvaluenow>maxvalue) {
//         if(numberoftry == 0) shutternow = 100;
//         if (maxvaluenow > maxvalue)
//         {
//             shutternow = shutternow *0.7;
//         }
//         else
//         {
//             shutternow = maxvalue * 0.98 / (maxvaluenow * 1.0)*shutternow + 1;
//         }
//         if (shutternow > maxtime)
//         {
//             shutternow = maxtime;
//             break;
//         }
//         GetOneDate(shutternow);
//         maxvaluenow= Getmaxvalue(DATABUFF, SensorInfo.BandNum);
// #ifdef ARDUINO
//         // Serial.print("now Shutter is :");
//         // Serial.print(shutternow);
//         // Serial.print("  maxvalue is :");
//         // Serial.println(maxvaluenow);
//         // write_log(log_path,"now Shutter is :"+String(shutternow)+"  maxvalue is :"+String(maxvaluenow),10);
// #endif
//         numberoftry++;
//         if (numberoftry > 200)
//         {
//             numberoftry = 1;
//             return maxtime;
//         }
//         if (shutternow == maxtime)
//         {

//             return  maxtime;
//         }
//         vTaskDelay(1);
//     }    
// #ifdef ARDUINO
//     // Serial.print("zi dong value:");
//     // Serial.println(shutternow);
//     write_log(log_path,"zi dong value:"+String(shutternow),10);
// #endif
//     if (shutternow<0)
//     {
//         shutternow=maxtime;
//         /* code */
//     }
//     write_log(log_path,"Finish OptSnenser",10);
//     shutternow = shutternow;
//     return shutternow;
// }


int SensorIS11::OptSnenser(int persent)
{
    long maxtime = 20000;
    int minvalue=(float)SensorInfo.maxValue * ((float)persent / 100.f);
    int maxvalue=(float)SensorInfo.maxValue * 0.95;
    int maxvaluenow = 0;
    int shutternow = 100;
    GetOneDate(shutternow);
    maxvaluenow= Getmaxvalue(DATABUFF, SensorInfo.BandNum);

    int numberoftry = 0;
    while (maxvaluenow<minvalue || maxvaluenow>maxvalue) 
    {
        if (maxvaluenow > maxvalue)
        {
            shutternow = shutternow *0.7;
        }
        else
        {
            shutternow = ((float)maxvalue  / (float)(maxvaluenow)) *shutternow + 1;
        }

        if (shutternow > maxtime)
        {
            shutternow = maxtime;
            break;
        }
        GetOneDate(shutternow);
        maxvaluenow = Getmaxvalue(DATABUFF, SensorInfo.BandNum);
#ifdef ARDUINO

#endif
        numberoftry++;
        if (numberoftry > 200)
        {
            numberoftry = 1;
            return maxtime;
        }

        if (shutternow == maxtime)
        {
            return  maxtime;
        }
        vTaskDelay(1);
    }
#ifdef ARDUINO
    write_log(log_path,"zi dong value:"+String(shutternow),10);
#endif
    if (shutternow<0)
    {
        shutternow=maxtime;
        /* code */
    }
    write_log(log_path,"Finish OptSnenser",10);
    shutternow = shutternow;
    return shutternow;
}





void SensorIS11::shortLittletoBiG(unsigned short *data,int lenth)
{
    CoverLittleAndBig((char *)data,lenth);
}


int SensorIS11::Getmaxvalue(unsigned short *data,int lenth)
{
    int ret=-1;
    for (int i = 0; i < lenth; ++i) {
        if (data[i]>ret){
            ret=data[i];
        }
    }
    return ret;
}


struct IS11_datastruct IS11_datastruct_up;
struct IS11_datastruct IS11_datastruct_down;
struct IS11_datastruct IS11_datastruct_dark_up;
struct IS11_datastruct IS11_datastruct_dark_down;

void SensorIS11::TakeOneJob1(bool dingbing)
{
    ds1302_date.getDateTime(&sys_time);
    // String path = "/guangpu_data/"+ String(sys_time.year) + "/" + String(sys_time.month) + "/" + String(sys_time.day)+ "/"+  String(sys_time.hour) + "-" + String(sys_time.minute) + "-" + String(sys_time.second) + ".bin";
    String  time =  String(sys_time.year) +"."+ String(sys_time.month) +"."+ String(sys_time.day)+" "+String(sys_time.hour)+":"+String(sys_time.minute)+":"+String(sys_time.second);
    write_log(log_path,time,20);
    write_log(log_path,"start take one job.",20);
    work_progress = 0 ;
    float temp[8];
    getall_temp(temp);
    //opt_up opt_down dark_up dn_up dn_down dark_down

    //1 opt_up
    servo_direction(1);
    SetShutter(2);
    shutterup=OptSnenser(70);
    SetShutter(1);
    work_progress = 15;

    //2 opt_down
    servo_direction(0);
    SetShutter(2);
    shutterdown=OptSnenser(70);
    SetShutter(1);
    work_progress = 30;

    //3 dark_up
    SetShutter(1);
    GetOneDate(shutterup);
    for (int i = 0; i < SensorInfo.BandNum;i++) 
    {
        IS11_datastruct_dark_up.data[i] = DATABUFF[i];
    }

    IS11_datastruct_dark_up.type = 0;
    IS11_datastruct_dark_up.direction = 2;
    IS11_datastruct_dark_up.tuigan_stat = get_tuigan_status();
    IS11_datastruct_dark_up.year = sys_time.year;
    IS11_datastruct_dark_up.month = sys_time.month;
    IS11_datastruct_dark_up.day = sys_time.day;
    IS11_datastruct_dark_up.hour = sys_time.hour;
    IS11_datastruct_dark_up.minute = sys_time.minute;
    IS11_datastruct_dark_up.second = sys_time.second;
    IS11_datastruct_dark_up.shutter_time  = shutterup;
    IS11_datastruct_dark_up.index = index;
    memcpy(IS11_datastruct_dark_up.temprature,temp,8*sizeof(float));
    work_progress = 45;

    //4 dn_up
    servo_direction(1);
    SetShutter(2);
    GetOneDate(shutterup);
    SetShutter(1);
    SensorInfo.BandNum = 2048;

    for (int i = 0; i < SensorInfo.BandNum;i++) 
    {
        IS11_datastruct_up.data[i] = DATABUFF[i];
    }
    IS11_datastruct_up.type = 0;
    IS11_datastruct_up.direction = 0;
    IS11_datastruct_up.tuigan_stat = get_tuigan_status();
    IS11_datastruct_up.year = sys_time.year;
    IS11_datastruct_up.month = sys_time.month;
    IS11_datastruct_up.day = sys_time.day;
    IS11_datastruct_up.hour = sys_time.hour;
    IS11_datastruct_up.minute = sys_time.minute;
    IS11_datastruct_up.second = sys_time.second;
    IS11_datastruct_up.shutter_time  = shutterup;
    IS11_datastruct_up.index = index;
    memcpy(IS11_datastruct_up.temprature,temp,8*sizeof(float));
    work_progress = 60;

    //5 dn_down
    servo_direction(0);
    SetShutter(2);
    GetOneDate(shutterdown);
    SetShutter(1);
    
    for (int i = 0; i < SensorInfo.BandNum;i++) {
        IS11_datastruct_down.data[i] = DATABUFF[i];
    }
    IS11_datastruct_down.type = 0;
    IS11_datastruct_down.direction = 1;
    IS11_datastruct_down.tuigan_stat = get_tuigan_status();
    IS11_datastruct_down.year = sys_time.year;
    IS11_datastruct_down.month = sys_time.month;
    IS11_datastruct_down.day = sys_time.day;
    IS11_datastruct_down.hour = sys_time.hour;
    IS11_datastruct_down.minute = sys_time.minute;
    IS11_datastruct_down.second = sys_time.second;
    IS11_datastruct_down.shutter_time  = shutterdown;
    IS11_datastruct_down.index = index;
    memcpy(IS11_datastruct_down.temprature,temp,8*sizeof(float));
    work_progress = 75;

    //6 dark_down
    SetShutter(1);
    GetOneDate(shutterdown);
    for (int i = 0; i < SensorInfo.BandNum;i++) 
    {
        IS11_datastruct_dark_down.data[i] = DATABUFF[i];
    }
    IS11_datastruct_dark_down.type = 0;
    IS11_datastruct_dark_down.direction = 3;
    IS11_datastruct_dark_down.tuigan_stat = get_tuigan_status();
    IS11_datastruct_dark_down.year = sys_time.year;
    IS11_datastruct_dark_down.month = sys_time.month;
    IS11_datastruct_dark_down.day = sys_time.day;
    IS11_datastruct_dark_down.hour = sys_time.hour;
    IS11_datastruct_dark_down.minute = sys_time.minute;
    IS11_datastruct_dark_down.second = sys_time.second;
    IS11_datastruct_dark_down.shutter_time  = shutterdown;
    IS11_datastruct_dark_down.index = index;
    memcpy(IS11_datastruct_dark_down.temprature,temp,8*sizeof(float));
    servo_off();
    work_progress = 90;
    //save data to file

    if(!SD_MMC.exists("/guangpu_data/"+ String(sys_time.year)))
    {
      sdcard::Mkdir("/guangpu_data/"+ String(sys_time.year));
    }
    if(!SD_MMC.exists("/guangpu_data/"+ String(sys_time.year) + "/" + String(sys_time.month)))
    {
      sdcard::Mkdir("/guangpu_data/"+ String(sys_time.year) + "/" + String(sys_time.month));
    }
    if(!SD_MMC.exists("/guangpu_data/"+ String(sys_time.year) + "/" + String(sys_time.month) + "/" + String(sys_time.day)))
    {
      sdcard::Mkdir("/guangpu_data/"+ String(sys_time.year) + "/" + String(sys_time.month) + "/" + String(sys_time.day));
    }
    String path1 = "/guangpu_data/"+ String(sys_time.year) + "/" + String(sys_time.month) + "/" + String(sys_time.day)+ "/"+ String(sys_time.hour) + "-" + String(sys_time.minute) + "-" + String(sys_time.second);
    sdcard::Mkdir(path1);

    String path2 = path1 + "/up.bin";
    File file;
    file = SD_MMC.open(path2,"wb");
    file.write((uint8_t *)(&IS11_datastruct_up),sizeof(IS11_datastruct));
    file.flush();
    file.close();
    work_progress = 92;

    path2 = path1 + "/dark_up.bin";
    file = SD_MMC.open(path2,"wb");
    file.write((uint8_t *)(&IS11_datastruct_dark_up),sizeof(IS11_datastruct));
    file.flush();
    file.close();
    work_progress = 94;

    path2 = path1 + "/down.bin";
    file = SD_MMC.open(path2,"wb");
    file.write((uint8_t *)(&IS11_datastruct_down),sizeof(IS11_datastruct));
    file.flush();
    file.close();
    work_progress = 96;

    path2 = path1 + "/dark_down.bin";
    file = SD_MMC.open(path2,"wb");
    file.write((uint8_t *)(&IS11_datastruct_dark_down),sizeof(IS11_datastruct));
    file.flush();
    file.close();

    index++;
    work_progress = 100 ;
    IS11_datastruct_fanshelv.NCa == 0;
    write_log(log_path,"take one job end.",20);
}

void SensorIS11::TakeOneJob()
{
    index++;
    ds1302_date.getDateTime(&sys_time);
    String  time = String(sys_time.year) +"."+ String(sys_time.month) +"."+ String(sys_time.day)+" "+String(sys_time.hour)+":"+String(sys_time.minute)+":"+String(sys_time.second);
    write_log(log_path,time + " start take one job",10);
    SensorInfo.BandNum = 2048;
    work_progress = 0 ;
    float temp[8];
    getall_temp(temp);
    //opt_up opt_down dark_up dn_up dn_down dark_down
    // write_log(log_path,"start take one jon",20);
    // write_log(log_path,"start",10);

    //1 opt_up
    servo_direction(1);
    SetShutter(2);
    shutterup=OptSnenser(70);
    shutterdown = shutterup;
    SetShutter(1);
    work_progress = 30;

    //2 dark
    //dark_up
    SetShutter(1);
    GetOneDate(shutterup);
    for (int i = 0; i < SensorInfo.BandNum;i++) 
    {
        IS11_datastruct_dark_up.data[i]  = DATABUFF[i];
        IS11_datastruct_dark_down.data[i] = DATABUFF[i];
    }
    IS11_datastruct_dark_up.type = 0;
    IS11_datastruct_dark_up.direction = 2;
    IS11_datastruct_dark_up.tuigan_stat = get_tuigan_status();
    IS11_datastruct_dark_up.year = sys_time.year;
    IS11_datastruct_dark_up.month = sys_time.month;
    IS11_datastruct_dark_up.day = sys_time.day;
    IS11_datastruct_dark_up.hour = sys_time.hour;
    IS11_datastruct_dark_up.minute = sys_time.minute;
    IS11_datastruct_dark_up.second = sys_time.second;
    IS11_datastruct_dark_up.shutter_time  = shutterup;
    IS11_datastruct_dark_up.index = index;
    memcpy(IS11_datastruct_dark_up.temprature,temp,8*sizeof(float));

    // dark_down
    IS11_datastruct_dark_down.type = 0;
    IS11_datastruct_dark_down.direction = 3;
    IS11_datastruct_dark_down.tuigan_stat = get_tuigan_status();
    IS11_datastruct_dark_down.year = sys_time.year;
    IS11_datastruct_dark_down.month = sys_time.month;
    IS11_datastruct_dark_down.day = sys_time.day;
    IS11_datastruct_dark_down.hour = sys_time.hour;
    IS11_datastruct_dark_down.minute = sys_time.minute;
    IS11_datastruct_dark_down.second = sys_time.second;
    IS11_datastruct_dark_down.shutter_time  = shutterdown;
    IS11_datastruct_dark_down.index = index;
    memcpy(IS11_datastruct_dark_down.temprature,temp,8*sizeof(float));
    
    work_progress = 45;
   
    //3 dn_up
    SetShutter(2);
    GetOneDate(shutterup);
    SetShutter(1);
    for (int i = 0; i < SensorInfo.BandNum;i++) 
    {
        IS11_datastruct_up.data[i] = DATABUFF[i];
    }
    IS11_datastruct_up.type = 0;
    IS11_datastruct_up.direction = 0;
    IS11_datastruct_up.tuigan_stat = get_tuigan_status();
    IS11_datastruct_up.year = sys_time.year;
    IS11_datastruct_up.month = sys_time.month;
    IS11_datastruct_up.day = sys_time.day;
    IS11_datastruct_up.hour = sys_time.hour;
    IS11_datastruct_up.minute = sys_time.minute;
    IS11_datastruct_up.second = sys_time.second;
    IS11_datastruct_up.shutter_time  = shutterup;
    IS11_datastruct_up.index = index;
    memcpy(IS11_datastruct_up.temprature,temp,8*sizeof(float));
    work_progress = 60;

    //4 dn_down
    servo_direction(0);
    SetShutter(2);
    GetOneDate(shutterup);
    SetShutter(1);
    
    for (int i = 0; i < SensorInfo.BandNum;i++) {
        IS11_datastruct_down.data[i] = DATABUFF[i];
    }
    IS11_datastruct_down.type = 0;
    IS11_datastruct_down.direction = 1;
    IS11_datastruct_down.tuigan_stat = get_tuigan_status();
    IS11_datastruct_down.year = sys_time.year;
    IS11_datastruct_down.month = sys_time.month;
    IS11_datastruct_down.day = sys_time.day;
    IS11_datastruct_down.hour = sys_time.hour;
    IS11_datastruct_down.minute = sys_time.minute;
    IS11_datastruct_down.second = sys_time.second;
    IS11_datastruct_down.shutter_time  = shutterdown;
    IS11_datastruct_down.index = index;
    memcpy(IS11_datastruct_down.temprature,temp,8*sizeof(float));
    servo_off();
    work_progress = 75;

    write_log(log_path,"start SD.",10);
    if(!SD_MMC.exists("/guangpu_data/"+ String(sys_time.year)))
    {
      sdcard::Mkdir("/guangpu_data/"+ String(sys_time.year));
    }
    if(!SD_MMC.exists("/guangpu_data/"+ String(sys_time.year) + "/" + String(sys_time.month)))
    {
      sdcard::Mkdir("/guangpu_data/"+ String(sys_time.year) + "/" + String(sys_time.month));
    }
    if(!SD_MMC.exists("/guangpu_data/"+ String(sys_time.year) + "/" + String(sys_time.month) + "/" + String(sys_time.day)))
    {
      sdcard::Mkdir("/guangpu_data/"+ String(sys_time.year) + "/" + String(sys_time.month) + "/" + String(sys_time.day));
    }
    String path1 = "/guangpu_data/"+ String(sys_time.year) + "/" + String(sys_time.month) + "/" + String(sys_time.day);
    
    // sdcard::Mkdir(path1);

    String path2 = path1 + "/" + String(sys_time.hour) + "-" + String(sys_time.minute) + "-" + String(sys_time.second) + ".bin";
    File file;
    file = SD_MMC.open(path2,"wb");
    file.write((uint8_t *)(&IS11_datastruct_up),sizeof(IS11_datastruct));
    file.write((uint8_t *)(&IS11_datastruct_dark_up),sizeof(IS11_datastruct));
    file.write((uint8_t *)(&IS11_datastruct_down),sizeof(IS11_datastruct));
    file.write((uint8_t *)(&IS11_datastruct_dark_down),sizeof(IS11_datastruct));
    file.flush();
    file.close();
    work_progress = 90;


    path2 = "/system/index.bin";
    file = SD_MMC.open(path2,"wb");
    file.write((uint8_t *) &index,4);
    file.flush();
    file.close();

    
    work_progress = 100;
    IS11_datastruct_fanshelv.NCa == 0;
    write_log(log_path,"take one job end.",10);
}


SensorIS11::SensorIS11()
{
    shutternow = 0;
    DataRetrun = GetDataBufferPTR();
}


///////////////////////////////////////////////////////////
void SensorIS11::send_dn(HardwareSerial  *wb485Serial,IS11_datastruct *IS11_datastructure,uint32_t fengbao_num)
{
    int32_t send_lenth;
    u_char *send_buff = new u_char[sizeof(IS11_datastruct) + 7];

    if(fengbao_num >= 1)
    {
        u_char *data_buff = new u_char[960+1];
        data_buff[0] = fengbao_num;
        uint32_t x = sizeof(IS11_datastruct) / 960;
        uint32_t n = 960;
        if(fengbao_num == x+1)
        {
            data_buff[0] = fengbao_num | 0x80;
            n = sizeof(IS11_datastruct) % 960;
        }
        memcpy(data_buff+1,(uint8_t *)IS11_datastructure+960*(fengbao_num-1),n);
        send_lenth = IRIS_Protocol_Pack(0x02,n+1,data_buff,send_buff);
        wb485Serial->write(send_buff,send_lenth);
        delete data_buff;
    }
    else
    {
        send_lenth = IRIS_Protocol_Pack(0x02,(uint16_t)sizeof(IS11_datastruct), (uint8_t *)IS11_datastructure,send_buff);
        wb485Serial->write(send_buff,send_lenth);
    }

    // send_lenth = IRIS_Protocol_Pack(0x02,(uint16_t)sizeof(IS11_datastruct), (uint8_t *)IS11_datastructure,send_buff);
    // wb485Serial->write(send_buff,send_lenth);
    delete send_buff;
    vTaskDelay(50);
}


void SensorIS11::send_radiance(HardwareSerial  *wb485Serial,IS11_datastruct *IS11_datastructure,uint32_t fengbao_num)
{
    struct IS11_datastruct IS11_datastruct_send = *IS11_datastructure;
    int32_t send_lenth;
    u_char *send_buff = new u_char[sizeof(IS11_datastruct) + 7];
    IS11_datastruct_send.type = 0x01;
    if(fengbao_num <= 1 )
    {    
        if(IS11_datastructure == &IS11_datastruct_up)
        {
            for (int i = 0; i < 2048;i++) 
            {
                IS11_datastruct_send.data[i] = IS11_datastruct_send.data[i] / IS11_datastruct_send.shutter_time * radiance_struct_up.shutter * radiance_struct_up.gain[i]  - radiance_struct_up.offset[i];  
            }
        }
        else if(IS11_datastructure == &IS11_datastruct_down)
        {
            for (int i = 0; i < 2048;i++) 
            {
                IS11_datastruct_send.data[i] = IS11_datastruct_send.data[i] / IS11_datastruct_send.shutter_time * radiance_struct_down.shutter * radiance_struct_down.gain[i]  - radiance_struct_down.offset[i];
            }
        }
    }

    if(fengbao_num >= 1)
    {
        // uint32_t n= 960;
        // if(fengbao_num == 8) n = 568;
        // send_lenth = IRIS_Protocol_Pack(0x02,n,(uint8_t *)(&IS11_datastruct_send) + 960*(fengbao_num-1),send_buff);
        // wb485Serial->write(send_buff,send_lenth);

        u_char *data_buff = new u_char[960+1];
        data_buff[0] = fengbao_num;
        uint32_t x = sizeof(IS11_datastruct) / 960;
        uint32_t n = 960;
        if(fengbao_num == x+1)
        {
            data_buff[0] = fengbao_num | 0x80;
            n = sizeof(IS11_datastruct) % 960;
        }
        memcpy(data_buff+1,(uint8_t *)(&IS11_datastruct_send)+960*(fengbao_num-1),n);
        send_lenth = IRIS_Protocol_Pack(0x02,n+1,data_buff,send_buff);
        wb485Serial->write(send_buff,send_lenth);
        delete data_buff;
    }
    else
    {
        send_lenth = IRIS_Protocol_Pack(0x02,(uint16_t)sizeof(IS11_datastruct), (uint8_t *)(&IS11_datastruct_send),send_buff);
        wb485Serial->write(send_buff,send_lenth);
    }
    // send_lenth = IRIS_Protocol_Pack(0x02,(uint16_t)sizeof(IS11_datastruct), (uint8_t *)(&IS11_datastruct_send),send_buff);
    // wb485Serial->write(send_buff,send_lenth);
    delete send_buff;
    vTaskDelay(50);
}


void SensorIS11::send_chongcaiyang(HardwareSerial  *wb485Serial,IS11_datastruct *IS11_datastructure,uint32_t fengbao_num)
{   
    struct IS11_datastruct IS11_datastruct_send = *IS11_datastructure;
    int32_t send_lenth;
    u_char *send_buff = new u_char[sizeof(IS11_datastruct) + 7];
    IS11_datastruct_send.type = 0x02;

    if(fengbao_num <= 1 )
    {
        const int numValues = 2048;
        float xValues[2048];
        float *yValues = IS11_datastructure->data;
        for (uint32_t i = 0; i < 2048; i++)
        {
            xValues[i] = SensorInfo.a1 * i * i * i + SensorInfo.a2 * i * i + SensorInfo.a3 * i+ SensorInfo.a4;
        }

        if(chongcaiyang_step <= 0.5)
        {
            chongcaiyang_step = 0.5;
        }

        float xValue_target =  ceil(SensorInfo.a4);
        float xValue_stop =  SensorInfo.a1 * 2047 *2047*2047 + SensorInfo.a2 *2047*2047 + SensorInfo.a3 *2047 + SensorInfo.a4;


        uint32_t b = 0;
        while(xValue_target < xValue_stop)
        {
            IS11_datastruct_send.data[b] = CatmullSpline(xValues, yValues, numValues, xValue_target);
            b++;
            xValue_target += chongcaiyang_step;
        }

        for(uint32_t c = b; c < 2048; c++)
        {
            IS11_datastruct_send.data[c] = 0;
        }
        IS11_datastruct_send.index = b+1;
    }

    if(fengbao_num >= 1)
    {
        // uint32_t n= 960;
        // if(fengbao_num == 8) n = 568;
        // send_lenth = IRIS_Protocol_Pack(0x02,n,(uint8_t *)(&IS11_datastruct_send) + 960*(fengbao_num-1),send_buff);
        // wb485Serial->write(send_buff,send_lenth);

        u_char *data_buff = new u_char[960+1];
        data_buff[0] = fengbao_num;
        uint32_t x = sizeof(IS11_datastruct) / 960;
        uint32_t n = 960;
        if(fengbao_num == x+1)
        {
            data_buff[0] = fengbao_num | 0x80;
            n = sizeof(IS11_datastruct) % 960;
        }
        memcpy(data_buff+1,(uint8_t *)(&IS11_datastruct_send)+960*(fengbao_num-1),n);
        send_lenth = IRIS_Protocol_Pack(0x02,n+1,data_buff,send_buff);
        wb485Serial->write(send_buff,send_lenth);
        delete data_buff;
    }
    else
    {
        send_lenth = IRIS_Protocol_Pack(0x02,(uint16_t)sizeof(IS11_datastruct), (uint8_t *)(&IS11_datastruct_send),send_buff);
        wb485Serial->write(send_buff,send_lenth);
    }
    // send_lenth = IRIS_Protocol_Pack(0x02,(uint16_t)sizeof(IS11_datastruct), (uint8_t *)(&IS11_datastruct_send),send_buff);
    // wb485Serial->write(send_buff,send_lenth);

    delete send_buff;
    vTaskDelay(50);
}




void SensorIS11::get_fanshelv()
{
    IS11_datastruct_fanshelv.type = 0x06;
    IS11_datastruct_fanshelv.direction = IS11_datastruct_up.direction;
    IS11_datastruct_fanshelv.tuigan_stat = IS11_datastruct_up.tuigan_stat;
    IS11_datastruct_fanshelv.year = IS11_datastruct_up.year;
    IS11_datastruct_fanshelv.month = IS11_datastruct_up.month;
    IS11_datastruct_fanshelv.day = IS11_datastruct_up.day;
    IS11_datastruct_fanshelv.minute = IS11_datastruct_up.minute;
    IS11_datastruct_fanshelv.hour = IS11_datastruct_up.hour;
    IS11_datastruct_fanshelv.second = IS11_datastruct_up.second;
    IS11_datastruct_fanshelv.NCa = IS11_datastruct_up.NCa;
    IS11_datastruct_fanshelv.NCb = IS11_datastruct_up.NCb;
    IS11_datastruct_fanshelv.NCc = IS11_datastruct_up.NCc;
    IS11_datastruct_fanshelv.NCc = 0;
    IS11_datastruct_fanshelv.shutter_time = IS11_datastruct_up.shutter_time;
    IS11_datastruct_fanshelv.index = IS11_datastruct_up.index;
    for(int i = 0; i < 8;i++)
    {
        IS11_datastruct_fanshelv.temprature[i] = IS11_datastruct_up.temprature[i];
    }
    for (int i = 0; i < 2048;i++) 
    {
        IS11_datastruct_fanshelv.data[i]  =  (IS11_datastruct_down.data[i] - IS11_datastruct_dark_down.data[i]) / (IS11_datastruct_up.data[i] - IS11_datastruct_dark_up.data[i]);
        if(fanshelv_struct.shutter == 1)
        {
            IS11_datastruct_fanshelv.data[i] =IS11_datastruct_fanshelv.data[i]*fanshelv_struct.gain[i];
        }
    }
    IS11_datastruct_fanshelv.NCa = 1;
}


// void SensorIS11::send_fanshelv(HardwareSerial  *wb485Serial)
// {   
//     if(IS11_datastruct_fanshelv.NCa == 0)
//     {
//         get_fanshelv();
//     }

//     int32_t send_lenth;
//     u_char *send_buff = new u_char[sizeof(IS11_datastruct) + 7];

//     send_lenth = IRIS_Protocol_Pack(0x02,(uint16_t)sizeof(IS11_datastruct), (uint8_t *)(&IS11_datastruct_fanshelv),send_buff);
//     wb485Serial->write(send_buff,send_lenth);
//     delete send_buff;
//     vTaskDelay(50);
// }

void SensorIS11::send_fanshelv(HardwareSerial  * wb485Serial,uint32_t fengbao_num)
{ 
    if(fengbao_num <= 1)
    {    
        if(IS11_datastruct_fanshelv.NCa == 0)
        {
            get_fanshelv();
        }
    }

    int32_t send_lenth;
    u_char *send_buff = new u_char[sizeof(IS11_datastruct) + 7];
    if(fengbao_num >= 1)
    {
        u_char *data_buff = new u_char[960+1];
        data_buff[0] = fengbao_num;
        uint32_t x = sizeof(IS11_datastruct) / 960;
        uint32_t n = 960;
        if(fengbao_num == x+1)
        {
            data_buff[0] = fengbao_num | 0x80;
            n = sizeof(IS11_datastruct) % 960;
        }
        memcpy(data_buff+1,(uint8_t *)(&IS11_datastruct_fanshelv)+960*(fengbao_num-1),n);
        send_lenth = IRIS_Protocol_Pack(0x02,n+1,data_buff,send_buff);
        wb485Serial->write(send_buff,send_lenth);
        delete data_buff;
    }
    else
    {
        send_lenth = IRIS_Protocol_Pack(0x02,(uint16_t)sizeof(IS11_datastruct), (uint8_t *)(&IS11_datastruct_fanshelv),send_buff);
        wb485Serial->write(send_buff,send_lenth);
    }

    delete send_buff;
    vTaskDelay(50);
}


void SensorIS11::calculation(float bochang1,float bochang2)
{
    if(IS11_datastruct_fanshelv.NCa == 0)
    {
        get_fanshelv();
    }

    float xValues[2048];
    float *yValues = IS11_datastruct_fanshelv.data;
    const int numValues = 2048;
    for(uint32_t i = 0; i < 2048; i++)
    {
        xValues[i] = SensorInfo.a1 * i * i * i + SensorInfo.a2 * i * i + SensorInfo.a3 * i+ SensorInfo.a4;
    }
    float R1 = CatmullSpline(xValues, yValues, numValues, bochang1);
    float R2 = CatmullSpline(xValues, yValues, numValues, bochang2);

    calculation_value = (R1 - R2) / (R1 + R2);
}




//send_data_type 0x00 DN类型  只回传up、down、up_darknoise、down_darknoise
//send_data_type 0x01 DN类型  只回传up、down
//send_data_type 0x02 DN类型  只回传up
//send_data_type 0x03 DN类型  只回传down
//send_data_type 0x04 DN类型  只回传up_darknosie
//send_data_type 0x05 DN类型  只回传down_darknoise
//send_data_type 0x06 DN类型  只回传dark （这个dark主要是在高级模式下才有，高级模式下dark不用区分方向）


//send_data_type 0x10 radiance类型  只回传up、down和DN类型的 up_darknoise、down_darknoise
//send_data_type 0x11 radiance类型  只回传up、down
//send_data_type 0x12 radiance类型  只回传up
//send_data_type 0x13 radiance类型  只回传down
//send_data_type 0x14 radiance类型  反射率

//send_data_type 0x20  重采样值 只回传up、down和DN类型的 up_darknoise、down_darknoise
//send_data_type 0x21  重采样值 只回传up、down
//send_data_type 0x22  重采样值 只回传up
//send_data_type 0x23  重采样值 只回传down
//send_data_type 0x24  重采样值 只回传up_darknosie
//send_data_type 0x25  重采样值 只回传down_darknoise
//send_data_type 0x26  重采样值 只回传dark （这个dark主要是在高级模式下才有，高级模式下dark不用区分方向）

void SensorIS11::senddata(HardwareSerial  *wb485Serial,u_int32_t send_data_type,uint32_t fengbao_num)
{   
    switch (send_data_type)
    {
        case 0X00:
            send_dn(wb485Serial,&IS11_datastruct_up, fengbao_num);
            send_dn(wb485Serial,&IS11_datastruct_down, fengbao_num);
            send_dn(wb485Serial,&IS11_datastruct_dark_up, fengbao_num);
            send_dn(wb485Serial,&IS11_datastruct_dark_down, fengbao_num);
            break;
        case 0X01:
            send_dn(wb485Serial,&IS11_datastruct_up, fengbao_num);
            send_dn(wb485Serial,&IS11_datastruct_down, fengbao_num);
            break;
        case 0X02:
            send_dn(wb485Serial,&IS11_datastruct_up, fengbao_num);
            break;
        case 0X03:
            send_dn(wb485Serial,&IS11_datastruct_down, fengbao_num);
            break;
        case 0X04:
            send_dn(wb485Serial,&IS11_datastruct_dark_up, fengbao_num);
            break;
        case 0X05:
            send_dn(wb485Serial,&IS11_datastruct_dark_down, fengbao_num);
            break;

        case 0X10:
            send_radiance(wb485Serial,&IS11_datastruct_up, fengbao_num);
            send_radiance(wb485Serial,&IS11_datastruct_down, fengbao_num);
            send_dn(wb485Serial,&IS11_datastruct_dark_up, fengbao_num);
            send_dn(wb485Serial,&IS11_datastruct_dark_down, fengbao_num);            
            break;
        case 0X11:
            send_radiance(wb485Serial,&IS11_datastruct_up, fengbao_num);
            send_radiance(wb485Serial,&IS11_datastruct_down, fengbao_num);
            break;
        case 0X12:
            send_radiance(wb485Serial,&IS11_datastruct_up, fengbao_num);
            break;
        case 0X13:
            send_radiance(wb485Serial,&IS11_datastruct_down, fengbao_num);
            break;
        case 0X14:
            send_fanshelv(wb485Serial,fengbao_num);
            // send_fanshelv(wb485Serial);
            break;

        case 0X20:
            send_chongcaiyang(wb485Serial,&IS11_datastruct_up, fengbao_num);
            send_chongcaiyang(wb485Serial,&IS11_datastruct_down, fengbao_num);
            send_chongcaiyang(wb485Serial,&IS11_datastruct_dark_up, fengbao_num);
            send_chongcaiyang(wb485Serial,&IS11_datastruct_dark_down, fengbao_num);            
            break;
        case 0X21:
            send_chongcaiyang(wb485Serial,&IS11_datastruct_up, fengbao_num);
            send_chongcaiyang(wb485Serial,&IS11_datastruct_down, fengbao_num);
            break;
        case 0X22:
            send_chongcaiyang(wb485Serial,&IS11_datastruct_up, fengbao_num);
            break;
        case 0X23:
            send_chongcaiyang(wb485Serial,&IS11_datastruct_down, fengbao_num);
            break;
        case 0X24:
            send_chongcaiyang(wb485Serial,&IS11_datastruct_dark_up, fengbao_num);
            break;
        case 0X25:
            send_chongcaiyang(wb485Serial,&IS11_datastruct_dark_down, fengbao_num);
            break;
        case 0X26:
            send_chongcaiyang(wb485Serial,&IS11_datastruct_dark_up, fengbao_num);
            break;
        default:
            break;
    }
}

///



/*
////////////////////////////////////////////////////////////////////////////////////////////////////////////
高级模式
支持选择采集的方向，up、down、dark
是否自动扣除暗电流
不支持自动曝光,
平均次数


direction  0:up 1:down 2:dark 
shutter_time  使用指定时间曝光 单位毫秒 最大时长30秒 必须大于0
remove_dark  0:不扣除 1:扣除
collect_times  采集次数
////////////////////////////////////////////////////////////////////////////////////////////////////////////
*/
void SensorIS11::advanced_mode(u_int32_t direction,u_int32_t shutter_time,u_int32_t collect_times,u_int32_t remove_dark)
{

    work_progress = 0;
    struct IS11_datastruct *IS11_datastructure_avn = nullptr;
    switch (direction)
    {
        case 0:
            servo_direction(1);
            SetShutter(2);
            IS11_datastructure_avn = &IS11_datastruct_up;
            break;
        case 1:
            servo_direction(0);
            SetShutter(2);
            IS11_datastructure_avn = &IS11_datastruct_down;
            break;
        case 2:
            SetShutter(1);
            IS11_datastructure_avn = &IS11_datastruct_dark_up;
            break;
        default:
            break;
    }

    int aa = collect_times;
    uint32_t caiji_times = 0;
    memset(IS11_datastructure_avn->data,0,8192);
    getall_temp(IS11_datastructure_avn->temprature);
    ds1302_date.getDateTime(&sys_time);
    IS11_datastructure_avn->year = sys_time.year;
    IS11_datastructure_avn->month = sys_time.month;
    IS11_datastructure_avn->day = sys_time.day;
    IS11_datastructure_avn->hour = sys_time.hour;
    IS11_datastructure_avn->minute = sys_time.minute;
    IS11_datastructure_avn->second = sys_time.second;
    
    while(aa > 0)
    {
        work_progress = (caiji_times * 100) / (collect_times * 2) ;

        GetOneDate(shutter_time);
        for (int i = 0; i < SensorInfo.BandNum;i++) 
        {
            IS11_datastructure_avn->data[i] +=  DATABUFF[i];
        }
        IS11_datastructure_avn->type = 0;
        IS11_datastructure_avn->direction = direction;
        IS11_datastructure_avn->tuigan_stat = get_tuigan_status();
        IS11_datastructure_avn->shutter_time  = shutter_time;
        IS11_datastructure_avn->index = index;

        if(remove_dark == 1 && direction != 2)
        {

            // write_log(log_path,"remove_dark",10);
            SetShutter(1);
            GetOneDate(shutter_time);
            SetShutter(2);
            for (int i = 0; i < SensorInfo.BandNum;i++) 
            {
                // if (i==1000)
                // {
                //     write_log(log_path,"or data:"+String(IS11_datastructure_avn->data[i])+ "  darkdata:"+String(DATABUFF[i]),10);
                    
                //     /* code */
                // }
                IS11_datastructure_avn->data[i] -= DATABUFF[i];
                IS11_datastruct_dark_up.data[i]  = DATABUFF[i];                
            }
            
            IS11_datastruct_dark_up.type = 0;
            IS11_datastruct_dark_up.direction = 2;
            IS11_datastruct_dark_up.tuigan_stat = get_tuigan_status();
            IS11_datastruct_dark_up.shutter_time  = shutter_time;
            IS11_datastruct_dark_up.index = index;
          //  getall_temp(IS11_datastruct_dark_up.temprature);
        }
        aa--;
        caiji_times++;
    }
    for (int i = 0; i < SensorInfo.BandNum;i++) 
    {
        IS11_datastructure_avn->data[i] = IS11_datastructure_avn->data[i] / collect_times;
    }
    SetShutter(1);
    servo_off();
    IS11_datastruct_fanshelv.NCa == 0;
    work_progress = 100;  
}

/*
////////////////////////////////////////////////////////////////////////////////////////////////////////////
opt
方向有up、down、dark
////////////////////////////////////////////////////////////////////////////////////////////////////////////
*/
void SensorIS11::opt(u_int32_t direction)
{
    switch (direction)
    {
        case 0:
            // servo_direction(1);
            SetShutter(2);
            break;
        case 1:
            // servo_direction(0);
            SetShutter(2);
            break;
        case 2:
            SetShutter(1);
            break;
        default:
            break;
    }
    work_progress = 50;
    dingbiao_shutter = OptSnenser(70);
    work_progress = 100;
    SetShutter(1);
}



//////////////////////////////////////////////////////////////////////////////////////////////
void SensorIS11::save_dingbiao(uint8_t * data)
{
    IS11_datastruct *IS11_datastructure = (IS11_datastruct *)data;
    float ab = 0;
    write_log(log_path,"save_dingbiao",10);
    write_log(log_path,"direction:"+String(IS11_datastructure->direction),10);
    write_log(log_path,"type:"+String(IS11_datastructure->type),10);
    if(IS11_datastructure->direction == 0) //up
    {   
        if (IS11_datastructure->type == 4)
        {
            radiance_struct_up.shutter = IS11_datastructure->shutter_time;
            write_log(log_path,"shutter_time:"+String(IS11_datastructure->shutter_time),10);            
            for (int i = 0; i < BANDNUMBER;i++) 
            {
                radiance_struct_up.gain[i] = IS11_datastructure->data[i]; 
            }
            ab = IS11_datastructure->data[0] * 1000000;
            write_log(log_path,"gain:"+String(ab),10);
        }
        else if (IS11_datastructure->type == 5)
        {
            for (int i = 0; i < BANDNUMBER;i++) 
            {
                radiance_struct_up.offset[i] = IS11_datastructure->data[i];
            }
            write_log(log_path,"offset:"+String(IS11_datastructure->data[0]),10);
        }
        else if (IS11_datastructure->type == 6)
        {
            for (int i = 0; i < BANDNUMBER;i++) 
            {
                fanshelv_struct.shutter = 1;
                fanshelv_struct.gain[i] = IS11_datastructure->data[i];
            }
        }
        else
        {
            return;
        }
        
    }
    else if(IS11_datastructure->direction == 1) //down
    {
        if (IS11_datastructure->type == 4)
        {
            radiance_struct_down.shutter = IS11_datastructure->shutter_time;
            write_log(log_path,"shutter_time:"+String(IS11_datastructure->shutter_time),10);   
            for (int i = 0; i < BANDNUMBER;i++) 
            {
                radiance_struct_down.gain[i] = IS11_datastructure->data[i]; 
            }
            ab = IS11_datastructure->data[0] * 1000000;
            write_log(log_path,"gain:"+String(ab),10);
        }
        else if (IS11_datastructure->type == 5)
        {
            for (int i = 0; i < BANDNUMBER;i++) 
            {
                radiance_struct_down.offset[i] = IS11_datastructure->data[i]; 
            }
            write_log(log_path,"offset:"+String(IS11_datastructure->data[0]),10);
        }
        else
        {
            return;
        }
    }
    else
    {
        return;
    }
}







//////////////////////////////////////////////////////////////////////////////////////////////
/*
////////////////////////////
波长                        序列号x            能量值
=a1*x^3+a2*x^2+a3*x+a4      0                  1111


DC 
暗电流测量的目的 设备本身的干扰  主要受到温度的影响
测试不同的波长对应的能量 

DN
通过光栅将光分解为不同的波长 然后照射到CCD上 
CCD的将不同波长的能量采集出来转换为DN值 


opt 最佳曝光的时长
采集到的能量和曝光时间有关
CCD采集能量的最好范围是 70%到90%之间是线性的 可信度最高 准确率最好
*/


/*
    Radiance  = DN / shuttertime * shutter * a -b;



*/





//send_data_type 0x02 DN类型  只回传up
//send_data_type 0x03 DN类型  只回传down
//send_data_type 0x04 DN类型  只回传up_darknosie
//send_data_type 0x05 DN类型  只回传down_darknoise

//send_data_type 0x12 radiance类型  只回传up
//send_data_type 0x13 radiance类型  只回传down
//send_data_type 0x14 radiance类型  反射率

//send_data_type 0x22  重采样值 只回传up
//send_data_type 0x23  重采样值 只回传down