package com.huimv.eartag.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.huimv.eartag.dao.entity.EartagDataEntity;
import com.huimv.eartag.dao.entity.EartagEnvEntity;
import com.huimv.eartag.dao.entity.EartagHeartbeatEntity;
import com.huimv.eartag.dao.entity.EartagRawEntity;
import com.huimv.eartag.dao.repo.EartagDataRepo;
import com.huimv.eartag.dao.repo.EartagEnvRepo;
import com.huimv.eartag.dao.repo.EartagHeartbeatRepo;
import com.huimv.eartag.dao.repo.EartagRawRepo;
import com.huimv.eartag.utils.Const;
import com.huimv.eartag.utils.BizConst;
import com.huimv.eartag.producer.InputProducer;
import com.huimv.eartag.service.ICacheService;
import com.huimv.eartag.service.IDataService;
import com.huimv.eartag.service.IDeviceService;
import com.huimv.eartag.service.IEartagService;
import com.huimv.eartag.utils.DateUtil2;
import com.huimv.eartag.utils.RegexUtil;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @Project : huimv.shiwan
 * @Package : com.huimv.biosafety.uface.controller
 * @Description : TODO
 * @Version : 1.0
 * @Author : ZhuoNing
 * @Create : 2020-12-25
 **/
@Service
@Slf4j
public class DataServiceImpl implements IDataService {
    @Autowired
    private DateUtil2 dateUtil;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private EartagRawRepo rawRepo;
    @Autowired
    private EartagHeartbeatRepo heartbeatRepo;
    @Autowired
    private EartagEnvRepo envRepo;
    @Autowired
    private EartagDataRepo eartagDataRepo;
    @Autowired
    RabbitTemplate rabbitTemplate;  //使用RabbitTemplate,这提供了接收/发送等等方法
    @Autowired
    private IDeviceService deviceService;
    @Autowired
    private IEartagService eartagService;
    @Autowired
    private InputProducer producer;
    @Autowired
    private RegexUtil regexUtil;
    @Autowired
    private ICacheService cacheService;

    //处理接收数据
    @Override
    public String handleClientAsk(String askText) throws ParseException {
//        System.out.println("000拆分粘包之后数据>>"+askText);
        //--对接收的上报数据解析
        String answer = parseAskText2(askText);

        //--将原始数据保存到rabbitMQ(重构之后代码)
        producer.sendClientAsk2(askText);

        return answer;
    }

    @Override
    public Map parseDeviceAsk(String askText) throws ParseException {
        Map resultMap = new HashMap();
        log.info("#开始解析Ask请求数据>>" + askText.trim().replace("\n", ""));
        String[] dataArray = askText.split("\\+");
        String cmdHeader = dataArray[0];
        String answer = null;
        if (cmdHeader.trim().equalsIgnoreCase("hm")) {
            //采集器原始数据
            //芯片id/设备编码
            String idCode = dataArray[1];
            String cmd = dataArray[2];
            //采集器应答数据
            if (cmd.trim().equalsIgnoreCase("0")) {
                //不需要处理
//                answer = null;
                resultMap.put("clientType", "device");
                resultMap.put("answerStatus", false);
                resultMap.put("answerText", null);
                resultMap.put("mqStatus", false);
                resultMap.put("askText", askText);
                return resultMap;
            } else if (cmd.trim().equalsIgnoreCase("1")) {
                //获取设备编码
                //{读取设备编码}
                String deviceCode = getDeviceCodeByChipId(idCode);
                if (deviceCode == null) {
                    log.error("异常:该芯片ID[" + idCode + "]未获取到设备编码，该设备为非法未注册设备.");
                    resultMap.put("validStatus",false);
                }else {
                    answer = "hm+1+0+" + deviceCode + "+123+8+end";
                    log.info("##获取设备编码-应答数据>>" + answer);
//                resultMap.put("chipId", idCode);
//                resultMap.put("deviceCode", deviceCode);
                    resultMap.put("validStatus",true);
                    resultMap.put("clientType", "device");
                    resultMap.put("answerStatus", true);
                    resultMap.put("answerText", answer);
                    resultMap.put("mqStatus", false);
                    resultMap.put("askText", askText);
                }
                return resultMap;
            } else if (cmd.trim().equalsIgnoreCase("2")) {
                //获取服务器时间命令
//                answer = "hm+2+0+"+dateUtil.getNowText()+"+4+end";
                answer = "hm+2+" + dateUtil.getNowText() + "+4+end";
                log.info("##获取服务器时间-应答数据>>" + answer);
                resultMap.put("validStatus",true);
                resultMap.put("clientType", "device");
                resultMap.put("answerStatus", true);
                resultMap.put("answerText", answer);
                resultMap.put("mqStatus", false);
                resultMap.put("askText", askText);
                return resultMap;

            } else if (cmd.trim().equalsIgnoreCase("3")) {
                //心跳包命令
//                heartbeatMap = new HashMap();
//                answer = "hm+3+0+6+end";
                answer = "hm+3+6+end";
                log.info("##心跳包-应答数据>>" + answer);
                resultMap.put("validStatus",true);
                resultMap.put("clientType", "device");
                resultMap.put("answerStatus", true);
                resultMap.put("answerText", answer);
                resultMap.put("mqStatus", true);
                resultMap.put("askText", askText);
                return resultMap;
            } else if (cmd.trim().equalsIgnoreCase("4")) {
                //环境温度-设备、数值、上传时间
//                answer = "hm+4+0+7+end";
                answer = "hm+4+7+end";
                log.info("##环境温度-应答数据>>" + answer);
                resultMap.put("validStatus",true);
                resultMap.put("clientType", "device");
                resultMap.put("answerStatus", true);
                resultMap.put("answerText", answer);
                resultMap.put("mqStatus", true);
                resultMap.put("askText", askText);
                return resultMap;
            } else {
                log.error("##当前数据为非法数据>>" + askText);
                resultMap.put("validStatus",false);
                resultMap.put("clientType", "device");
                resultMap.put("answerStatus", false);
                resultMap.put("answerText", null);
                resultMap.put("mqStatus", false);
                return resultMap;
            }
//            return answer;
        } else if (cmdHeader.trim().equalsIgnoreCase("zj")) {
            //耳标应答数据（不需要应答）
            answer = null;
            resultMap.put("validStatus",true);
            resultMap.put("clientType", "eartag");
            resultMap.put("answerStatus", false);
            resultMap.put("answerText", null);
            resultMap.put("mqStatus", true);
            resultMap.put("askText", askText);
            return resultMap;
        } else {
            log.error("##当前请求数据为非法数据>>" + askText);
            resultMap.put("validStatus",false);
            resultMap.put("clientType", "不清楚设备类型");
            resultMap.put("answerStatus", false);
            resultMap.put("answerText", null);
            resultMap.put("mqStatus", false);
            return resultMap;
        }
    }

    @Override
    public boolean isValidDevice(String cmdHeader, String idCode, String cmd) {
        if (cmdHeader.trim().equalsIgnoreCase("hm") && cmd.trim().equalsIgnoreCase("1")) {
            //{读取设备编码}
            String deviceCode = getDeviceCodeByChipId(idCode);
            log.info("芯片id>>"+idCode+", 设备编码>>"+deviceCode);
            if(deviceCode == null){
                return false;
            }else{
                return true;
            }
        }else{
            return true;
        }
    }

    @Override
    public String getDeviceAnswer(String cmdHeader, String cmd, String idCode) throws ParseException {
        String answer = null;
        if (cmdHeader.trim().equalsIgnoreCase("hm")) {
            //采集器应答数据
            if (cmd.trim().equalsIgnoreCase("0")) {
                //获取目标服务器的通信地址和端口号(不需要处理)
                answer = null;
            } else if (cmd.trim().equalsIgnoreCase("1")) {
                //{读取设备编码}
                String deviceCode = getDeviceCodeByChipId(idCode);
                answer = "hm+1+0+" + deviceCode + "+123+8+end";
                log.info("##获取设备编码-应答数据>>" + answer);
            } else if (cmd.trim().equalsIgnoreCase("2")) {
                //获取服务器时间命令
                answer = "hm+2+" + dateUtil.getNowText() + "+4+end";
                log.info("##获取服务器时间-应答数据>>" + answer);
            } else if (cmd.trim().equalsIgnoreCase("3")) {
                //心跳包命令
                answer = "hm+3+6+end";
                log.info("##心跳包-应答数据>>" + answer);
            } else if (cmd.trim().equalsIgnoreCase("4")) {
                //环境温度-设备、数值、上传时间
                answer = "hm+4+7+end";
                log.info("##环境温度-应答数据>>" + answer);
            } else {
                log.error("##当前数据为非法数据>>");
            }
            return answer;
        } else if (cmdHeader.trim().equalsIgnoreCase("zj")) {
            //耳标应答数据（不需要应答）
           return null;
        } else {
            log.error("##当前请求数据为非法数据>>");
            return null;
        }
    }

    /**
     * @Method      : sendBizMQ
     * @Description : 注意：askText中第三位cmd对于耳标数据而言是耳标号，对于设备而言是命令。
     * @Params      : [cmdHeader, cmd, askText]
     * @Return      : void
     * 
     * @Author      : ZhuoNing
     * @Date        : 2022/3/23       
     * @Time        : 17:20
     */
    @Override
    public void sendBizMQ(String cmdHeader, String cmd, String askText) {
        askText = askText.replaceAll("\r","").replaceAll("\n","");
        Map map = new HashMap();
        map.put("askText",askText);
        System.out.println("-->3.1");
        if (cmdHeader.trim().equalsIgnoreCase("hm") && (cmd.trim().equalsIgnoreCase("3") || cmd.trim().equalsIgnoreCase("4"))) {
            System.out.println("-->3.2");
            //发送到设备处理消息队列
            rabbitTemplate.convertAndSend(Const.EXCHANGE_ASK_DEVICE, Const.ROUTING_KEY_ASK_DEVICE, map);
            System.out.println("## --> 发送设备处理模块.");
        } else if (cmdHeader.trim().equalsIgnoreCase("zj")) {
            System.out.println("-->3.3");
            //{发送消息}
            if(cmd.trim().equalsIgnoreCase("ffffffffffffffff") || cmd.trim().equalsIgnoreCase("0000000000000000")){
                log.error("舍弃掉未配置耳标号的耳标，"+askText+"");
            }else{
                System.out.println("-->3.4");
                //{检查设备是否在处于工作状态或待机状态}
                if(isWorkStatusDevice(cmdHeader)){
                    //发送到耳标处理消息队列
                    rabbitTemplate.convertAndSend(Const.EXCHANGE_ASK_EARTAG, Const.ROUTING_KEY_ASK_EARTAG, map);
                    System.out.println("## --> 发送耳标处理模块.");
                }
            }
        }
        System.out.println("-->3.5");
    }

    @Override
    public void sendEartagMQ(Map map) {
        //发送到耳标处理消息队列
        rabbitTemplate.convertAndSend(Const.EXCHANGE_ASK_EARTAG, Const.ROUTING_KEY_ASK_EARTAG, map);
    }


    public String handleClientAsk_1(String askText) throws ParseException {
//        System.out.println("000拆分粘包之后数据>>"+askText);
        //--对接收的上报数据解析
        String answer = parseAskText2(askText);

        //--将原始数据保存到rabbitMQ(重构之后代码)
        producer.sendClientAsk2(askText);

        return answer;
    }

    //--处理客户端请求
    public String handleClientAsk_old(String askText, ChannelHandlerContext ctx) throws ParseException {
        //原始数据
        Map rawMap = new HashMap();
        //心跳数据
        Map heartbeatMap = new HashMap();
        //温度数据
        Map envtempMap = new HashMap();
        //耳标数据
        JSONObject eartagJo = new JSONObject();
        //--对接收的上报数据解析
        String answer = parseAskText(askText, rawMap, heartbeatMap, envtempMap, eartagJo);
        //--保存数据
        save(rawMap, heartbeatMap, envtempMap, eartagJo);
        //--处理分支流程
//        handleBranch();
        //--处理采集器信息
        deviceService.handleDeviceInfo();
        //--处理耳标信息
        eartagService.handleEartagInfo();
        return answer;
    }

    /**
     * @Method : handleBranch
     * @Description : 处理分支流程
     * @Params : []
     * @Return : void
     * @Author : ZhuoNing
     * @Date : 2022/1/24
     * @Time : 11:35
     */
    private void handleBranch() {
        //--处理注册表数据
        handleRegister();
        //--处理在线记录数据
        handleOnline();
        //--处理状态数据
        handleAllState();
    }

    /**
     * @Method : handleAllState
     * @Description : 处理状态数据
     * @Params : []
     * @Return : void
     * @Author : ZhuoNing
     * @Date : 2022/1/24
     * @Time : 14:26
     */
    private void handleAllState() {

    }

    /**
     * @Method : handleOnline
     * @Description : 处理在线记录数据
     * @Params : []
     * @Return : void
     * @Author : ZhuoNing
     * @Date : 2022/1/24
     * @Time : 14:26
     */
    private void handleOnline() {

    }

    /**
     * @Method : handleRegister
     * @Description : 处理注册表数据
     * @Params : []
     * @Return : void
     * @Author : ZhuoNing
     * @Date : 2022/1/24
     * @Time : 14:26
     */
    private void handleRegister() {
        Map map = new HashMap();

        //将消息携带绑定键值：topic.device.register 发送到交换机TestDirectExchange
        rabbitTemplate.convertAndSend("deviceTopicExchange", "topic.device.register", map);
    }

    /**
     * @Method : save
     * @Description : 保存数据
     * @Params : [rawMap, heartbeatMap, envtempMap, eartagJo]
     * @Return : void
     * @Author : ZhuoNing
     * @Date : 2022/1/24
     * @Time : 11:35
     */
    private void save(Map rawMap, Map heartbeatMap, Map envtempMap, JSONObject eartagJo) throws ParseException {
        //--保存原始数据
        saveRawData(rawMap);
        //心跳
        if (heartbeatMap.size() > 0) {
            //--保存心跳流水数据
            saveHeartBeat(heartbeatMap);
        }
        //采集器温度
        if (envtempMap.size() > 0) {
            //--保存采集器温度流水数据
            saveEnvTempData(envtempMap);
        }
        //耳标
        if (eartagJo.size() > 0) {
            //--保存耳标流水数据
            saveEartagData(eartagJo);
        }
    }

    /**
     * 保存心跳数据
     */
    private void saveHeartBeat(Map heartbeatMap) {
        String deviceCode = heartbeatMap.get("device").toString();
        EartagHeartbeatEntity addHeartbeatEntity = new EartagHeartbeatEntity();
        addHeartbeatEntity.setDeviceCode(deviceCode);
        addHeartbeatEntity.setAddTime(new Timestamp(new Date().getTime()));
        heartbeatRepo.saveAndFlush(addHeartbeatEntity);
    }

    /**
     * 保存采集器温度数据
     */
    private void saveEnvTempData(Map tempMap) throws ParseException {
        EartagEnvEntity envEntity = new EartagEnvEntity();
        envEntity.setDeviceCode(tempMap.get("device").toString());
        envEntity.setTemp1(Integer.parseInt(tempMap.get("temp").toString()));
        envEntity.setTemp2(0F);
        envEntity.setAddTime(new Timestamp(new Date().getTime()));
        envRepo.saveAndFlush(envEntity);
    }

    /**
     * 保存耳标数据
     */
    private void saveEartagData(JSONObject eartagJo) {
        EartagDataEntity dataEntity = new EartagDataEntity();
        dataEntity.setCmdHeader(eartagJo.getString("cmdHeader"));
        dataEntity.setDevice(eartagJo.getString("device"));
        dataEntity.setEarmark(eartagJo.getString("earmark"));
        dataEntity.setBat(Integer.parseInt(eartagJo.getString("bat")));
        dataEntity.setEarTemp(Integer.parseInt(eartagJo.getString("earTemp")));
        dataEntity.setEarTemp1(eartagJo.getFloat("earTemp1"));
        dataEntity.setEnvTemp(Integer.parseInt(eartagJo.getString("envTemp")));
        dataEntity.setEnvTemp1(eartagJo.getFloat("envTemp1"));
        dataEntity.setAct(Integer.parseInt(eartagJo.getString("act")));
        dataEntity.setAct1(Integer.parseInt(eartagJo.getString("act1")));
        dataEntity.setSignal1(Integer.parseInt(eartagJo.getString("signal")));
        dataEntity.setAskTime(getAskTime(eartagJo.getString("askTime")));
        dataEntity.setOther(eartagJo.getString("other"));
        dataEntity.setAddTime(new Timestamp(new Date().getTime()));
        eartagDataRepo.saveAndFlush(dataEntity);

        //最新的耳标数据覆盖老数据
        Map<String, String> map = new HashMap<>();
        map.put("cmdHeader", dataEntity.getCmdHeader());
        map.put("device", dataEntity.getDevice());
        map.put("earmark", dataEntity.getEarmark());
        map.put("bat", dataEntity.getBat().toString());
        map.put("earTemp", dataEntity.getEarTemp().toString());
        map.put("earTemp1", dataEntity.getEarTemp1().toString());
        map.put("envTemp", dataEntity.getEnvTemp().toString());
        map.put("envTemp1", dataEntity.getEnvTemp1().toString());
        map.put("act", dataEntity.getAct().toString());
        map.put("act1", dataEntity.getAct1().toString());
        map.put("signal1", dataEntity.getSignal1().toString());
        map.put("askTime", dataEntity.getAskTime());
        map.put("other", dataEntity.getOther());
        map.put("addTime", dataEntity.getAddTime().toString());
        //为hash结构设置多个键值对(hmset)
        redisTemplate.opsForHash().putAll(dataEntity.getDevice(), map);
    }

    //
    public String getAskTime(String askTime) {
        String newAskTime = askTime.substring(0, 4) + "-" + askTime.substring(4, 6) + "-" + askTime.substring(6, 8) + " " + askTime.substring(8, 10) + ":" + askTime.substring(10, 12) + ":" + askTime.substring(12, 14);
        return newAskTime;
    }

    /**
     * 保存原始数据
     */
    private void saveRawData(Map rawMap) {
        //类型、设备、命令、数据内容、日期
        EartagRawEntity addRawEntity = new EartagRawEntity();
        addRawEntity.setCmdHeader(rawMap.get("cmdHeader").toString());
        addRawEntity.setDevice(rawMap.get("device").toString());
        addRawEntity.setCmd(rawMap.get("cmd").toString());
        addRawEntity.setAsk(rawMap.get("ask").toString());
        addRawEntity.setAddTime(new Timestamp(new Date().getTime()));
        rawRepo.saveAndFlush(addRawEntity);
    }

    //处理耳标数据
    private void handleEartag(Map dataMap) {
        log.info("耳标数据>>" + dataMap.toString());
    }

    /* 根本设备id获取设备编码 */
    @Override
    public String getDeviceCodeByChipId(String chipId) {
//        ValueOperations ops = redisTemplate.opsForValue();
//        ops.set("deviceCode", "202007239999869");
//        String deviceCode = (String) ops.get("deviceCode");
//        System.out.println("redis->deviceCode>>" + deviceCode);

//        String deviceCode = "";
//        if (chipId.trim().equalsIgnoreCase("a848fad42b8a")) {
//            deviceCode = "202007239999866";
//        } else if (chipId.trim().equalsIgnoreCase("a848fad3fefb")) {
//            deviceCode = "202007239999873";
//        } else {
//            deviceCode = "202007239999869";
//        }

        //{根据芯片id读取设备编码}
        String deviceCode = deviceService.getDeviceCodeByChipId(chipId);
//        System.out.println("chipId>>" + chipId + " ,deviceCode>>" + deviceCode);
        return deviceCode;
    }

    @Override
    public void sendDeviceMQ(Map map) {
        //发送到耳标处理消息队列
        rabbitTemplate.convertAndSend(Const.EXCHANGE_ASK_DEVICE, Const.ROUTING_KEY_ASK_DEVICE, map);
    }

    @Override
    public boolean isWorkStatusDevice(String idCode) {
        String key = BizConst.DEVICE_REGISTER_PREFIX+idCode;
        String hashKey = "deviceStatus";
        Object deviceStatusObj = redisTemplate.opsForHash().get(key,hashKey);
        System.out.println("## deviceStatusObj>>"+deviceStatusObj);
        if(deviceStatusObj == null){
            return false;
        }else{
            String deviceStatus = deviceStatusObj.toString();
            if(deviceStatus.trim().equalsIgnoreCase("0") || deviceStatus.trim().equalsIgnoreCase("1")){
                return true;
            }else{
                return false;
            }
        }
    }

    @Override
    public boolean isEffectiveDevice(String idCode) {
        //{检查有效设备集合}
        return cacheService.checkEffectiveDeviceSet(idCode);
    }

    /**
     * 解析接收数据
     */
    private String parseAskText2(String askText) throws ParseException {
        log.info("#开始解析Ask请求数据>>" + askText.trim().replace("\n", ""));
        String[] dataArray = askText.split("\\+");
        String cmdHeader = dataArray[0];
        String answer = null;
        if (cmdHeader.trim().equalsIgnoreCase("hm")) {
            //采集器原始数据
            //芯片id/设备编码
            String idCode = dataArray[1];
            String cmd = dataArray[2];
            //采集器应答数据
            if (cmd.trim().equalsIgnoreCase("0")) {
                //不需要处理
                answer = null;
            } else if (cmd.trim().equalsIgnoreCase("1")) {
                //获取设备编码
                //{读取设备编码}
                String deviceCode = getDeviceCodeByChipId(idCode);
                answer = "hm+1+0+" + deviceCode + "+123+8+end";
                log.info("##获取设备编码-应答数据>>" + answer);
            } else if (cmd.trim().equalsIgnoreCase("2")) {
                //获取服务器时间命令
//                answer = "hm+2+0+"+dateUtil.getNowText()+"+4+end";
                answer = "hm+2+" + dateUtil.getNowText() + "+4+end";
                log.info("##获取服务器时间-应答数据>>" + answer);
            } else if (cmd.trim().equalsIgnoreCase("3")) {
                //心跳包命令
//                heartbeatMap = new HashMap();
//                answer = "hm+3+0+6+end";
                answer = "hm+3+6+end";
                log.info("##心跳包-应答数据>>" + answer);
            } else if (cmd.trim().equalsIgnoreCase("4")) {
                //环境温度-设备、数值、上传时间
//                answer = "hm+4+0+7+end";
                answer = "hm+4+7+end";
                log.info("##环境温度-应答数据>>" + answer);
            } else {
                log.error("##当前数据为非法数据>>" + askText);
            }
            return answer;
        } else if (cmdHeader.trim().equalsIgnoreCase("zj")) {
            //耳标应答数据（不需要应答）
            answer = null;
        } else {
            log.error("##当前请求数据为非法数据>>" + askText);
        }
        return answer;
    }

    //old
    private String parseAskText(String askText, Map rawMap, Map heartbeatMap, Map envTempMap, JSONObject eartagJo) throws ParseException {
        log.info("#开始解析Ask请求数据>>" + askText.trim().replace("\n", ""));
        String[] dataArray = askText.split("\\+");
        String cmdHeader = dataArray[0];
        String answer = null;
        if (cmdHeader.trim().equalsIgnoreCase("hm")) {
            //采集器原始数据
            String device = dataArray[1];
            String cmd = dataArray[2];
            rawMap.put("cmdHeader", cmdHeader);
            rawMap.put("device", device);
            rawMap.put("cmd", cmd);
            rawMap.put("ask", askText);
            //耳标数据
            //采集器应答数据
            if (cmd.trim().equalsIgnoreCase("0")) {
                //不需要处理
                answer = null;
            } else if (cmd.trim().equalsIgnoreCase("1")) {
                //获取设备编码
                /* 读取设备编码 */
                String deviceCode = getDeviceCodeByChipId(device);
                answer = "hm+1+0+" + deviceCode + "+123+8+end";
                log.info("##获取设备编码-应答数据>>" + answer);
            } else if (cmd.trim().equalsIgnoreCase("2")) {
                //获取服务器时间命令
                //应答数据
//                answer = "hm+2+0+"+dateUtil.getNowText()+"+4+end";
                answer = "hm+2+" + dateUtil.getNowText() + "+4+end";
                log.info("##获取服务器时间-应答数据>>" + answer);
            } else if (cmd.trim().equalsIgnoreCase("3")) {
                //心跳包命令
//                heartbeatMap = new HashMap();
                heartbeatMap.put("device", device);
//                answer = "hm+3+0+6+end";
                answer = "hm+3+6+end";
                log.info("##心跳包-应答数据>>" + answer);
            } else if (cmd.trim().equalsIgnoreCase("4")) {
                //环境温度-设备、数值、上传时间
                envTempMap.put("device", dataArray[1]);
                envTempMap.put("temp", dataArray[4]);
                envTempMap.put("askTime", dataArray[5]);
                //应答数据
//                answer = "hm+4+0+7+end";
                answer = "hm+4+7+end";
                log.info("##环境温度-应答数据>>" + answer);
            } else {
                log.error("##当前数据为非法数据>>" + askText);
            }
            return answer;
        } else if (cmdHeader.trim().equalsIgnoreCase("zj")) {
            //应答数据
            answer = null;
            //采集器原始数据
            String device = dataArray[1];
            rawMap.put("cmdHeader", cmdHeader);
            rawMap.put("device", device);
            rawMap.put("cmd", "");
            rawMap.put("ask", askText);
            rawMap.put("addTime", dateUtil.getTodayMissionText());
            //-- 耳标数据 --//
            //计算耳标温度
            Double earTemp = 0D;
            String other = dataArray[9];
            if (other != null && other.trim().length() > 0) {
                String[] otherArray = other.split("#");
                String resi = otherArray[2];
                Double temp = ln(Integer.parseInt(resi));
                earTemp = new BigDecimal(temp).setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();
            }
            //--计算运动量
            Integer act1Int = countAct(dataArray[1], dataArray[6]);
            //命令头
            eartagJo.put("cmdHeader", dataArray[0]);
            //采集器id
            eartagJo.put("device", dataArray[1]);
            //耳标号
            eartagJo.put("earmark", dataArray[2]);
            //电池电量
            eartagJo.put("bat", dataArray[3]);
            //耳标温度
            eartagJo.put("earTemp", dataArray[4]);
            eartagJo.put("earTemp1", earTemp);
            //环境温度
            eartagJo.put("envTemp", dataArray[5]);
            //运动量
            eartagJo.put("act", dataArray[6]);
            eartagJo.put("act1", act1Int);
            //信号强度
            eartagJo.put("signal", dataArray[7]);
            //采集时间
            eartagJo.put("askTime", dataArray[8]);
            //预留字段
            eartagJo.put("other", dataArray[9]);
        } else {
            log.error("##当前请求数据为非法数据>>" + askText);
            //采集器原始数据
            String device = dataArray[1];
            rawMap.put("cmdHeader", cmdHeader);
            rawMap.put("device", device);
            rawMap.put("cmd", "");
            rawMap.put("ask", askText);
//            rawMap.put("addTime",dateUtil.getTodayMissionText());
        }
        return answer;
    }

    /**
     * @Method : countAct
     * @Description : 计算act数值
     * @Params : [deviceCode, nowAct0]
     * @Return : java.lang.Integer
     * @Author : ZhuoNing
     * @Date : 2022/1/18
     * @Time : 15:25
     */
    private Integer countAct(String deviceCode, String nowAct) {
        //读取hash
        Object actObj = redisTemplate.opsForHash().get(deviceCode, "act");
        if (actObj == null) {
            //--初始化最新的redis记录
            initRedisObj(deviceCode);
            Object lastAct = redisTemplate.opsForHash().get(deviceCode, "act");
            if (lastAct == null) {
                log.error("#--- redis数据库有问题，请检查redis是否能正常连接 ---# ");
                return 0;
            }
        }
        Object lastAct = redisTemplate.opsForHash().get(deviceCode, "act");
        Integer act1 = Integer.parseInt(nowAct) - Integer.parseInt(lastAct.toString());
//        redisTemplate.opsForHash().put(deviceCode, "act1", act1);
        return act1;
    }

    /**
     * 初始化redis最新记录
     */
    private void initRedisObj(String deviceCode) {
        System.out.println("deviceCode>>" + deviceCode);
        //
//        Optional optional = eartagDataRepo.getLastEartagData(deviceCode);
        EartagDataEntity lastEartagDataEntity = eartagDataRepo.getLastEartagData(deviceCode);
        if (lastEartagDataEntity != null) {
//            EartagDataEntity lastEartagDataEntity = (EartagDataEntity) optional.get();
            System.out.println("## lastEartagDataEntity.toString>>" + lastEartagDataEntity.toString());
            //--从数据库读取最新记录并覆盖redis
            Map<String, String> map = new HashMap<>();
            map.put("cmdHeader", lastEartagDataEntity.getCmdHeader());
            map.put("device", lastEartagDataEntity.getDevice());
            map.put("earmark", lastEartagDataEntity.getEarmark());
            map.put("bat", lastEartagDataEntity.getBat().toString());
            map.put("earTemp", lastEartagDataEntity.getEarTemp().toString());
            map.put("earTemp1", lastEartagDataEntity.getEarTemp1().toString());
            map.put("envTemp", lastEartagDataEntity.getEnvTemp().toString());
            map.put("envTemp1", lastEartagDataEntity.getEnvTemp1().toString());
            map.put("act", lastEartagDataEntity.getAct().toString());
            map.put("act1", lastEartagDataEntity.getAct1().toString());
            map.put("signal1", lastEartagDataEntity.getSignal1().toString());
            map.put("askTime", lastEartagDataEntity.getAskTime());
            map.put("other", lastEartagDataEntity.getOther());
            map.put("addTime", lastEartagDataEntity.getAddTime().toString());
            //为hash结构设置多个键值对(hmset)
            redisTemplate.opsForHash().putAll(deviceCode, map);
        }
    }

    public static double A = 0.00335396319311466;
    public static double B = 0.000256376549039663;
    public static double C = 0.00000248933580817244;
    public static double D = 0.0000000753805242068686;
    public static double E = -0.0000000204758173596178;

    //保留一位小数
    public static double changeDouble(Double dou) {
        NumberFormat nf = new DecimalFormat("0.0 ");
        dou = Double.parseDouble(nf.format(dou));
        return dou;
    }

    public static double ln(int rv) {
        int R_REF = 10000;
        double ln = Math.log((double) rv / R_REF);
        //保留一位小数
        return changeDouble(1 / (A + B * ln + C * Math.pow(ln, 2) + D * Math.pow(ln, 3) + E * Math.pow(ln, 4)) - 273.15) + 0.001;
    }

    //暂存老代码
    private String parseAskText_0(String askText, Map rawMap, Map heartbeatMap, Map envTempMap, Map eartagMap) throws ParseException {
        log.info("#开始解析Ask请求数据>>" + askText.trim().replace("\n", ""));
        String[] dataArray = askText.split("\\+");
        String cmdHeader = dataArray[0];
        String answer = null;
        heartbeatMap = null;
        envTempMap = null;
        eartagMap = null;
        if (cmdHeader.trim().equalsIgnoreCase("hm")) {
            //采集器原始数据
            String device = dataArray[1];
            String cmd = dataArray[2];
            rawMap.put("cmdHeader", cmdHeader);
            rawMap.put("device", device);
            rawMap.put("cmd", cmd);
            rawMap.put("ask", askText);
//            rawMap.put("addTime",dateUtil.getTodayMissionText());
            //耳标数据
            eartagMap = null;
            //采集器应答数据
            if (cmd.trim().equalsIgnoreCase("0")) {
                //需要不处理,默认cmdHeader = null
                answer = null;
            } else if (cmd.trim().equalsIgnoreCase("1")) {
                //获取设备编码
                /* 读取设备编码 */
                String deviceCode = getDeviceCodeByChipId(device);
                answer = "hm+1+0+" + deviceCode + "+123+8+end";
                log.info("##获取设备编码-应答数据>>" + answer);
            } else if (cmd.trim().equalsIgnoreCase("2")) {
                //获取服务器时间命令
                //应答数据
//                answer = "hm+2+0+"+dateUtil.getNowText()+"+4+end";
                answer = "hm+2+" + dateUtil.getNowText() + "+4+end";
                log.info("##获取服务器时间-应答数据>>" + answer);
            } else if (cmd.trim().equalsIgnoreCase("3")) {
                //心跳包命令
                heartbeatMap = new HashMap();
                heartbeatMap.put("device", device);
//                answer = "hm+3+0+6+end";
                answer = "hm+3+6+end";
                log.info("##心跳包-应答数据>>" + answer);
            } else if (cmd.trim().equalsIgnoreCase("4")) {
                //环境温度-设备、数值、上传时间
                envTempMap = new HashMap();
                envTempMap.put("device", dataArray[1]);
                envTempMap.put("temp", dataArray[4]);
                envTempMap.put("askTime", dataArray[5]);
                System.out.println("envTempMap.toString()>>" + envTempMap.toString());
                //应答数据
//                answer = "hm+4+0+7+end";
                answer = "hm+4+7+end";
                log.info("##环境温度-应答数据>>" + answer);
            } else {
                log.error("##当前数据为非法数据>>" + askText);
            }
            return answer;
        } else if (cmdHeader.trim().equalsIgnoreCase("zj")) {
            //应答数据
            answer = null;
            //采集器原始数据
            String device = dataArray[1];
            rawMap.put("cmdHeader", cmdHeader);
            rawMap.put("device", device);
            rawMap.put("cmd", "");
            rawMap.put("ask", askText);
            rawMap.put("addTime", dateUtil.getTodayMissionText());
            //耳标数据
            eartagMap = new HashMap();
            //命令头
            eartagMap.put("cmdHeader", dataArray[0]);
            //采集器id
            eartagMap.put("device", dataArray[1]);
            //耳标号
            eartagMap.put("earmark", dataArray[2]);
            //电池电量
            eartagMap.put("bat", dataArray[3]);
            //耳标温度
            eartagMap.put("earTemp", dataArray[4]);
            //环境温度
            eartagMap.put("envTemp", dataArray[5]);
            //运动量
            eartagMap.put("act", dataArray[6]);
            //信号强度
            eartagMap.put("signal", dataArray[7]);
            //采集时间
            eartagMap.put("askTime", dataArray[8]);
            //预留字段
            eartagMap.put("other", dataArray[9]);
            System.out.println("11111111111111111 >>" + eartagMap.toString());
        } else {
            log.error("##当前请求数据为非法数据>>" + askText);
            //采集器原始数据
            String device = dataArray[1];
            rawMap.put("cmdHeader", cmdHeader);
            rawMap.put("device", device);
            rawMap.put("cmd", "");
            rawMap.put("ask", askText);
//            rawMap.put("addTime",dateUtil.getTodayMissionText());
        }
        return answer;
    }

}
