package com.huimv.eartag.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.huimv.eartag.dao.entity.*;
import com.huimv.eartag.dao.repo.*;
import com.huimv.eartag.service.IEartagService;
import com.huimv.eartag.utils.BizConst;
import com.huimv.eartag.utils.DateUtil;
import com.huimv.eartag.service.ICacheService;
import com.huimv.eartag.service.IDeviceService;
import com.huimv.eartag.utils.MathUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.sql.Date;
import java.sql.Timestamp;
import java.text.ParseException;
import java.util.List;
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 DeviceServiceImpl implements IDeviceService {
    @Autowired
    RabbitTemplate rabbitTemplate;  //使用RabbitTemplate,这提供了接收/发送等等方法
    @Autowired
    private EartagRawRepo eartagRawRepo;
    @Autowired
    private EartagDeviceRegisterRepo deviceRegisterRepo;
    @Autowired
    private ICacheService cacheService;
    @Autowired
    private EartagDeviceOnlineRepo deviceOnlineRepo;
    @Autowired
    private EartarFarmAllStatusRepo eartagFarmAllStatusRepo;
    @Autowired
    private EartarFarmAllStatusRepo farmAllStatusRepo;
//    @Autowired
//    private IEartagService eartagService;
    @Autowired
    private EartagDeviceOnlineRepo eartagDeviceOnlineRepo;
    @Autowired
    private EartagEartagRegisterRepo eartagRegisterRepo;
    @Autowired
    private EartagConfigPropertiesRepo configPropertiesRepo;
//    @Value("${service.farmAllStatus.host}")
//    private String serviceFarmAllStatusHost;
    @Value("${service.farmAllStatus.ip}")
    private String serviceFarmAllStatusIp;
    @Value("${service.farmAllStatus.url}")
    private String serviceFarmAllStatusUrl;
    @Autowired
    private EartagHeartbeatRepo heartbeatRepo;
    @Autowired
    private EartagEnvRepo envRepo;

    //处理采集器设备信息
    @Override
    public void handleDeviceInfo() {
        //--处理注册表数据
        handleEartagRegister();
        //--处理在线记录数据
        handleEartagOnline();
        //--处理状态数据
        handleEartagAllState();
    }

    @Override
    public void saveRawData(String askText) throws ParseException {
        DateUtil dateUtil = new DateUtil();
        EartagRawEntity eartagRawEntity = new EartagRawEntity();
        eartagRawEntity.setAsk(askText);
        eartagRawEntity.setAddTime(dateUtil.getTimestamp());
        eartagRawEntity.setCreateDate(new Date(dateUtil.getTodayDate().getTime()));
        eartagRawRepo.saveAndFlush(eartagRawEntity);
    }

    @Override
    public String getDeviceCodeByChipId(String chipId) {
        //{}
        Object deviceCodeObj = cacheService.getDeviceCodeByChipId(chipId);
        if(deviceCodeObj != null){
            return (String)deviceCodeObj;
        }else{
            return null;
            //{从数据库读取设备编码返回}
//            return getDeviceCodeByChipIdFromMySQL(chipId);
        }
    }

    @Override
    public String getFarmIdByDeviceCode(String deviceCode) {
        //
        String farmId = (String)cacheService.getFarmIdByDeviceCode(deviceCode);
        if(farmId != null && farmId.trim().length()>0){
            return farmId;
        }else{
            EartagDeviceRegisterEntity deviceRegisterEntity = deviceRegisterRepo.getDeviceRegister(deviceCode);
            //{将设备注册信息保存到缓存中}
            cacheService.putDeviceRegister(deviceCode,deviceRegisterEntity);
            return deviceRegisterEntity.getFarmId();
        }
    }


    //从数据库读取deviceCode
    private String getDeviceCodeByChipIdFromMySQL(String chipId) {
        //{}
        EartagDeviceRegisterEntity deviceRegisterEntity = deviceRegisterRepo.getByChipId(chipId);
        if(deviceRegisterEntity == null){
            log.error("该芯片id不存在.");
            return null;
        }else{
            return deviceRegisterEntity.getDeviceCode();
        }
    }

    //计算设备总数
    @Override
    public int getDeviceTotalByFarmIdFromDeviceRegister(String farmId){
        //从缓存钟读取设备总数
        Integer deviceTotal = cacheService.getDeviceTotal(farmId);
        if(deviceTotal != null) {
            return deviceTotal;
        }else{
            List<Object[]> deviceRegList = deviceRegisterRepo.getDeviceCountByFarmId(farmId);
            Object[] deviceRegObj = (Object[]) deviceRegList.get(0);
            Integer total = Integer.parseInt(deviceRegObj[0].toString());
            //设置缓存
            cacheService.putDeviceTotal(total,farmId);
            //设备总数
            return total;
        }
    }

    //计算注销设备数量
    @Override
    public int getDeviceCancelTotalFromDeviceRegister(String farmId) {
        //从缓存钟读取设备总数
        Integer deviceCancel = cacheService.getDeviceCancel(farmId);
        if(deviceCancel != null) {
            return deviceCancel;
        }else {
            //注销状态
            Integer liveStatus = 2;
            List<Object[]> deviceCancelList = deviceRegisterRepo.getDeviceCountByFarmIdAndLiveStatus(farmId,liveStatus);
            Object[] deviceRegObj = (Object[]) deviceCancelList.get(0);
            Integer total = Integer.parseInt(deviceRegObj[0].toString());
            //设置注销缓存
            cacheService.putDeviceCancel(total,farmId);
            //设备总数
            return total;
        }
    }

    //计算处于不同生存状态的设备数量
    @Override
    public Integer getDeviceSum(String farmId, Integer liveStatus){
        //# 计算处于工作状态的设备总数（设备注册表）
        List<Object[]> deviceRegList = deviceRegisterRepo.getDeviceCountByFarmIdAndLiveStatus(farmId,liveStatus);
        Object[] deviceRegObj = (Object[]) deviceRegList.get(0);
        //设备总数
        return Integer.parseInt(deviceRegObj[0].toString());
    }

    //更新设备环境信息
    @Override
    public void updateEnvtempOfDeviceAllStatus(String farmId, String todayDateText, java.sql.Date todayDate, Timestamp nowTimestamp) throws ParseException {
        System.out.println("## farmId>>"+farmId);
        //{获取处于工作状态的设备数量}
        Integer deviceTotal = getDeviceTotalByFarmIdFromDeviceRegister(farmId);
        System.out.println("## 1.deviceTotal>>"+deviceTotal);
        if(deviceTotal == 0){
            log.error("出错:设备总数(deviceTotal)不能为0.");
        }
        //设备在线数量
        Integer deviceOnlineSum = cacheService.getDeviceOnlineSum(farmId,todayDateText);
        System.out.println("## 2.设备当前在线数量(deviceOnlineSum)="+deviceOnlineSum);
        deviceOnlineSum++;
        System.out.println("## 3.设备当前在线数量(deviceOnlineSum) 2="+deviceOnlineSum);
        //设备离线数量
        Integer deviceOfflineSum = 0;
        if(deviceTotal > deviceOnlineSum){
            deviceOfflineSum = deviceTotal - deviceOnlineSum;
        }
        System.out.println("## 4.deviceOfflineSum>>"+deviceOfflineSum);
        //设备在线率
        BigDecimal deviceRateBd= new BigDecimal(deviceOnlineSum).divide(new BigDecimal(deviceTotal),1,BigDecimal.ROUND_HALF_UP);
        Float deviceOnlineRate = Float.parseFloat(deviceRateBd.toString());
        System.out.println("## 5.deviceOnlineRate>>"+deviceOnlineRate);
        //{获取注销设备数量}
        Integer deviceCancelSum = getDeviceCancelTotalFromDeviceRegister(farmId);
        Integer eartagOnlineSum = 0;
        Float eartagOnlineRate = 0F;
        //耳标总数量
//        Integer eartagTotal = eartagService.getEartagRegTotalByFarmId(farmId);
        Integer eartagTotal = getEartagRegTotalByFarmId(farmId);
        if(eartagTotal != 0){
            //耳标在线数量
//            eartagOnlineSum = eartagService.getEartagOnelineTotal(farmId,todayDateText);
            eartagOnlineSum = getEartagOnelineTotal(farmId,todayDateText);
            //耳标在线率
            BigDecimal eartagRateBd= new BigDecimal(eartagOnlineSum).divide(new BigDecimal(eartagTotal),1,BigDecimal.ROUND_HALF_UP);
            eartagOnlineRate = Float.parseFloat(eartagRateBd.toString());
        }
        //
        EartarFarmAllStatusEntity farmAllStatusEntity = eartagFarmAllStatusRepo.getOneByFarmIdAndCreateDate(farmId,todayDateText);
        if(farmAllStatusEntity == null){
            //{新建设备状态记录并更新缓存cache}
            createNewFarmAllStatus(farmId,todayDate,nowTimestamp,deviceTotal,deviceOnlineSum,deviceOfflineSum,deviceCancelSum,deviceOnlineRate,eartagTotal,eartagOnlineSum,eartagOnlineRate);
        }else{
            //计算设备状态并更新缓存cache(在线数+1，离线数-1，计算设备在线率)
            farmAllStatusEntity.setDeviceTotal(deviceTotal);
            farmAllStatusEntity.setDeviceOnline(deviceOnlineSum);
            farmAllStatusEntity.setDeviceOffline(deviceOfflineSum);
            farmAllStatusEntity.setDeviceRate(deviceOnlineRate);
            farmAllStatusEntity.setDeviceCancel(deviceCancelSum);
            farmAllStatusEntity.setEartagTotal(eartagTotal);
            farmAllStatusEntity.setEartagOnline(eartagOnlineSum);
            farmAllStatusEntity.setEartagRate(eartagOnlineRate);
            farmAllStatusEntity.setUpdateTime(nowTimestamp);
            eartagFarmAllStatusRepo.saveAndFlush(farmAllStatusEntity);
            System.out.println("## 更新的内容="+farmAllStatusEntity);
            //# 同步更新牧场总状态缓存相关字段 #
            cacheService.flashAllStatusCache(farmId,farmAllStatusEntity);
        }
    }

    //读取耳标注册数据
//    @Override
    public Integer getEartagRegTotalByFarmId(String farmId){
        //从缓存读取耳标总数
        Integer eartagTotal = cacheService.getEartagTotal(farmId);
        if(eartagTotal != null){
            return eartagTotal;
        }else{
//            List<Object[]> eartagRegList = eartagRegisterRepo.getEartagCountByFarmId(farmId);
//            Object[] eartagRegObj = (Object[]) eartagRegList.get(0);
//            Integer total = Integer.parseInt(eartagRegObj[0].toString());
            ///
            Integer liveStatus = 1;
            //{读取处于工作状态的耳标总数}
            Integer total = getEartagSum(farmId,liveStatus);
            //设置耳标总数缓存
            cacheService.putEartagTotal(total,farmId);
            //处于工作状态的耳标总数
            return total;
        }
    }

    //计算处于不同生存状态的耳标数量
    private Integer getEartagSum(String farmId,Integer liveStatus){
        List<Object[]> eartagRegList = eartagRegisterRepo.getEartagCountByFarmId(farmId,liveStatus);
        Object[] eartagRegObj = (Object[]) eartagRegList.get(0);
        //处于工作状态的耳标总数
        return Integer.parseInt(eartagRegObj[0].toString());
    }

//    @Override
    public Integer getEartagOnelineTotal(String farmId, String todayDateText) {
        return cacheService.getEartagOnlineTotalFromCache(farmId,todayDateText);
    }

    //# 创建总状态记录 #
    private void createNewFarmAllStatus(String farmId, java.sql.Date todayDate, Timestamp nowTimestamp, Integer deviceTotal, Integer deviceOnlineSum, Integer deviceOfflineSum, Integer deviceCancelSum, Float deviceOnlineRate, Integer eartagTotal, Integer eartagOnlineSum, Float eartagOnlineRate) {
        Integer liveStatus = 1;
        if(getDeviceSum(farmId,liveStatus) == 0){
            log.error("该牧场没有任何处于工作状态的采集器设备.");
        }else{
            //# 计算耳标总数（耳标注册表）
            EartarFarmAllStatusEntity farmAllStatusEntity = new EartarFarmAllStatusEntity();
            farmAllStatusEntity.setDeviceTotal(deviceTotal);
            farmAllStatusEntity.setDeviceOnline(deviceOnlineSum);
            farmAllStatusEntity.setDeviceOffline(deviceOfflineSum);
            farmAllStatusEntity.setDeviceRate(deviceOnlineRate);
            farmAllStatusEntity.setDeviceCancel(deviceCancelSum);
            farmAllStatusEntity.setEartagTotal(eartagTotal);
            farmAllStatusEntity.setEartagOnline(eartagOnlineSum);
            farmAllStatusEntity.setEartagRate(eartagOnlineRate);
            farmAllStatusEntity.setFarmId(farmId);
            farmAllStatusEntity.setUpdateTime(nowTimestamp);
            farmAllStatusEntity.setCreateDate(todayDate);
            eartagFarmAllStatusRepo.saveAndFlush(farmAllStatusEntity);
            //设置总状态缓存
            cacheService.flashAllStatusCache(farmId,farmAllStatusEntity);
        }
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /**
     * @Method      : handleDeviceHeartbeat
     * @Description : 处理设备心跳数据
     * @Params      : [dataJo]
     * @Return      : void
     *
     * @Author      : ZhuoNing
     * @Date        : 2022/3/12
     * @Time        : 19:16
     */
    @Override
    public void handleDeviceHeartbeat(JSONObject dataJo) throws ParseException {
        System.out.println("心跳数据 dataJo>>"+dataJo);
        //逻辑处理：
        //1、保存设备心跳流水数据；
        //2、更新设备注册表（活动状态、活动更新时间，更新类型）
        //3、更新在线统计表（心跳数，心跳最早上传时间，最后一次上传时间）
        //4、更新总状态表表
        //Step1:更新设备注册表[设置活动状态为1，设置活动状态更新时间]
        //Step2:更新在线统计[心跳数+1，心跳第一次上传时间，心跳最后一次时间]，预先判断该数据是否存在，如果不存在要先添加记录，如果存在就修改数据

        System.out.println("dataJo>"+dataJo);
        String deviceCode = dataJo.getString("device");
        //{获取牧场id}
        String farmId = getFarmIdByDeviceCode(deviceCode);
        if(farmId != null){
            String todayDateText = new com.huimv.eartag.utils.DateUtil().getTodayDateText();
            java.sql.Date todayDate = new java.sql.Date(new java.util.Date().getTime());
            Timestamp nowTimestamp = new Timestamp(new java.util.Date().getTime());
            //1、{保存设备心跳记录}
            saveDeviceHeartbeat(dataJo,todayDate);

            String updateType="设备心跳";
            //2、{更新设备注册表}
            updateDeviceRegister(farmId, deviceCode,nowTimestamp,updateType);

            //3、{更新在线统计表}
            updateDeviceOnlineCountWithHeartbeat(farmId, deviceCode,todayDateText,nowTimestamp,todayDate);

            //判断该设备编号是否存在缓存在线集合当中；
            Boolean isExist = cacheService.isExistDeviceOnlineSet(farmId, deviceCode, todayDateText);
            System.out.println("心跳处理 isExist>>"+isExist);
            if (!isExist) {
                //4、{更新总状态表}
                updateEnvtempOfDeviceAllStatus(farmId, todayDateText,todayDate,nowTimestamp);

                //# 将新设备编号加入在线缓存 #
                cacheService.putDeviceToOnlineSet(farmId, deviceCode,todayDateText);
            }
        }else{
            log.error("出错:该请求的FarmId为空.请检查该设备编码["+deviceCode+"]是否存在FarmId.");
        }
        System.out.println("## END 心跳数据。 "+new com.huimv.eartag.utils.DateUtil().getTodayMissionText());
    }

    //更新在线状态
    public void updateDeviceOnlineCountWithHeartbeat(String farmId, String deviceCode, String todayDateText, Timestamp nowTimestamp, java.sql.Date todayDate) throws ParseException {
        String hashKey = BizConst.DEVICE_REGISTER_PREFIX+deviceCode;
        //计算设备别名
        String alias = (String)cacheService.getHashProperty(hashKey,"deviceAlias");
        //读取在线日期
        EartagDeviceOnlineEntity eartagDeviceOnlineEntity = eartagDeviceOnlineRepo.getDeviceOnline(deviceCode, todayDateText);
        if (eartagDeviceOnlineEntity == null) {
            Integer heartbeatTotal = 1;
            Integer envtempTotal = 0;
            Timestamp heartbeatFirstTime = nowTimestamp;
            Timestamp heartbeatLastTime = nowTimestamp;
            Timestamp envtempFirstTime = null;
            Timestamp envtempLastTime = null;
            Timestamp firstTime = nowTimestamp;
            Timestamp lastTime = nowTimestamp;
            Integer liveStatus = 1;
            //{计算耳标总数}
//            Integer eartagTotal = eartagService.getEartagRegTotalByFarmId(farmId);
            Integer eartagTotal = 0;
            //{新建设备在线统计并创建缓存}
            newDeviceOnline(deviceCode,alias,heartbeatTotal,envtempTotal,eartagTotal,todayDate,farmId,heartbeatFirstTime,heartbeatLastTime,envtempFirstTime,envtempLastTime,firstTime,lastTime,liveStatus);
        }else{
            eartagDeviceOnlineEntity.setAlias(alias);
            int heartbeatTotal = eartagDeviceOnlineEntity.getHeartbeatTotal();
            eartagDeviceOnlineEntity.setHeartbeatTotal(++heartbeatTotal);
            if(eartagDeviceOnlineEntity.getHeartbeatFirstTime() == null){
                eartagDeviceOnlineEntity.setHeartbeatFirstTime(nowTimestamp);
            }
            eartagDeviceOnlineEntity.setHeartbeatLastTime(nowTimestamp);
            if(eartagDeviceOnlineEntity.getFirstTime() == null){
                eartagDeviceOnlineEntity.setFirstTime(nowTimestamp);
            }
            eartagDeviceOnlineEntity.setLastTime(nowTimestamp);
            eartagDeviceOnlineRepo.saveAndFlush(eartagDeviceOnlineEntity);
            //更新设备在线缓存数据
            cacheService.putDeviceInOnline(deviceCode,eartagDeviceOnlineEntity);
        }
    }

    /**
     * @Method      : newDeviceOnline
     * @Description : 通过心跳创建在线统计记录
     * @Params      : [deviceCode, alias, heartbeatTotal, envtempTotal, eartagTotal, todayDate, farmId, heartbeatFirstTime, heartbeatLastTime, envtempFirstTime, envtempLastTime]
     * @Return      : void
     *
     * @Author      : ZhuoNing
     * @Date        : 2022/3/14
     * @Time        : 21:23
     */
    private void newDeviceOnline(String deviceCode, String alias, Integer heartbeatTotal, Integer envtempTotal, Integer eartagTotal, java.sql.Date todayDate, String farmId, Timestamp heartbeatFirstTime, Timestamp heartbeatLastTime, Timestamp envtempFirstTime, Timestamp envtempLastTime, Timestamp firstTime, Timestamp lastTime, Integer liveStatus) {
        EartagDeviceOnlineEntity newEartagDeviceOnlineEntity = new EartagDeviceOnlineEntity();
        newEartagDeviceOnlineEntity.setDeviceCode(deviceCode);
        newEartagDeviceOnlineEntity.setAlias(alias);
        newEartagDeviceOnlineEntity.setHeartbeatTotal(heartbeatTotal);;
        newEartagDeviceOnlineEntity.setEnvtempTotal(envtempTotal);
        newEartagDeviceOnlineEntity.setEartagTotal(eartagTotal);
        newEartagDeviceOnlineEntity.setAddDate(todayDate);
        newEartagDeviceOnlineEntity.setFarmId(farmId);
        newEartagDeviceOnlineEntity.setHeartbeatFirstTime(heartbeatFirstTime);
        newEartagDeviceOnlineEntity.setHeartbeatLastTime(heartbeatLastTime);
        newEartagDeviceOnlineEntity.setEnvtempFirstTime(envtempFirstTime);
        newEartagDeviceOnlineEntity.setEnvtempLastTime(envtempLastTime);
        newEartagDeviceOnlineEntity.setFirstTime(firstTime);
        newEartagDeviceOnlineEntity.setLastTime(lastTime);
        newEartagDeviceOnlineEntity.setLiveStatus(liveStatus);
        eartagDeviceOnlineRepo.saveAndFlush(newEartagDeviceOnlineEntity);
        //将新建的设备在线数据更新到设备在线缓存
        cacheService.putDeviceInOnline(deviceCode,newEartagDeviceOnlineEntity);
    }

    //更新设备注册表
    private void updateDeviceRegister(String farmId, String deviceCode, Timestamp nowTimestamp,String updateType) {
        //--更新mysql
        EartagDeviceRegisterEntity deviceRegisterEntity = deviceRegisterRepo.getDeviceRegister(deviceCode);
        if (deviceRegisterEntity != null) {
            //设备注册数据存在
            deviceRegisterEntity.setDeviceStatus(1);
            deviceRegisterEntity.setActiveStatus(1);
            deviceRegisterEntity.setActiveTime(nowTimestamp);
            deviceRegisterEntity.setUpdateType(updateType);
            deviceRegisterRepo.saveAndFlush(deviceRegisterEntity);
            //更新缓存中设备注册信息
            cacheService.putDeviceRegister(deviceCode,deviceRegisterEntity);
        }else{
            //设备注册数据不存在
            //新建设备注册记录
            newDeviceRegister(farmId,deviceCode,nowTimestamp,updateType);
        }
    }

    //新建设备注册记录
    public void newDeviceRegister(String farmId,String deviceCode,Timestamp nowTimestamp,String updateType){
        EartagDeviceRegisterEntity newDeviceRegisterEntity = new EartagDeviceRegisterEntity();
        newDeviceRegisterEntity.setDeviceCode(deviceCode);
        newDeviceRegisterEntity.setFarmId(farmId);
        newDeviceRegisterEntity.setRegisterTime(nowTimestamp);
        newDeviceRegisterEntity.setActiveStatus(1);
        newDeviceRegisterEntity.setActiveTime(nowTimestamp);
        newDeviceRegisterEntity.setDeviceStatus(1);
        newDeviceRegisterEntity.setUpdateType(updateType);
        deviceRegisterRepo.saveAndFlush(newDeviceRegisterEntity);
        //更新缓存中设备注册信息
        cacheService.putDeviceRegister(deviceCode,newDeviceRegisterEntity);
    }

    /**
     * @Method      : saveDeviceHeartbeat
     * @Description : 保存设备心跳数据
     * @Params      : [dataJo]
     * @Return      : void
     *
     * @Author      : ZhuoNing
     * @Date        : 2022/2/15
     * @Time        : 14:39
     */
//    @Override
    public void saveDeviceHeartbeat(JSONObject dataJo, java.sql.Date todayDate) {
        String deviceCode = dataJo.getString("device");
        EartagHeartbeatEntity addHeartbeatEntity = new EartagHeartbeatEntity();
        addHeartbeatEntity.setDeviceCode(deviceCode);
        addHeartbeatEntity.setAddTime(new Timestamp(new java.util.Date().getTime()));
        addHeartbeatEntity.setCreateDate(todayDate);
        heartbeatRepo.saveAndFlush(addHeartbeatEntity);
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /**
     * @Method      : handleDeviceEnvtemp
     * @Description : 处理设备环境温度数据
     * @Params      : [dataJo]
     * @Return      : void
     *
     * @Author      : ZhuoNing
     * @Date        : 2022/3/12
     * @Time        : 19:16
     */
    @Override
    public void handleDeviceEnvtemp(JSONObject dataJo) throws ParseException {
        System.out.println("环境数据 dataJo>>"+dataJo);
        //逻辑处理：
        //1、保存环境温度流水数据；
        //2、更新设备注册表（活动状态、活动更新时间，更新类型）
        //3、更新在线统计表（环境温度计数，环境温度最早上传时间，最新环境温度，环境温度最后一次上传时间）
        //4、更新总状态表
        String deviceCode = dataJo.getString("device");
        //{通过设备编码取货牧场id}
        String farmId = getFarmIdByDeviceCode(deviceCode);
        if(farmId != null){
            String temp = dataJo.getString("temp");
            String envtemp = com.huimv.eartag.utils.MathUtil.countEnvtemp(temp,2).toString();
            String todayDateText = new com.huimv.eartag.utils.DateUtil().getTodayDateText();
            java.sql.Date todayDate = new java.sql.Date(new java.util.Date().getTime());
            Timestamp nowTimestamp = new Timestamp(new java.util.Date().getTime());

            //1.保存环境温度流水
            saveDeviceTemp(dataJo,todayDate,nowTimestamp);

            String updateType = "环境温度";
            //2.{更新设备注册表}
            updateDeviceRegister(farmId, deviceCode,nowTimestamp,updateType);

            //3.{更新在线统计表}
            updateDeviceOnlineWithEnvtemp(farmId, deviceCode,envtemp,todayDate,nowTimestamp);

            //{检查异常温度}
            checkAbnormalEnvTemp(farmId,envtemp);

            //判断该设备编号是否存在牧场缓存在线集合当中；
            Boolean isExist = cacheService.isExistDeviceOnlineSet(farmId, deviceCode,todayDateText);
            System.out.println("## 环境温度 isExist>>"+isExist);
            if (!isExist) {
                //4.{更新总状态表}
                updateEnvtempOfDeviceAllStatus(farmId, todayDateText,todayDate,nowTimestamp);

                //{将新设备编号加入在线缓存}
                cacheService.putDeviceToOnlineSet(farmId, deviceCode, todayDateText);
            }
        }else{
            log.error("出错:该请求的FarmId为空.请检查该设备编码["+deviceCode+"]是否存在FarmId.");
        }
        System.out.println("## END 环境数据。"+new com.huimv.eartag.utils.DateUtil().getTodayMissionText());
    }

    /**
     * @Method      : checkAbnormalEnvTemp
     * @Description : 检查异常环境温度
     * @Params      : [farmId, envtemp]
     * @Return      : void
     *
     * @Author      : ZhuoNing
     * @Date        : 2022/4/6
     * @Time        : 19:14
     */
    private void checkAbnormalEnvTemp(String farmId, String envtemp) {
        //{}
        Object envTempTvObj = cacheService.getEnvTempThresholdVal(farmId);
        String envTempTv = "";
        if(envTempTvObj != null){
            envTempTv = envTempTvObj.toString();
            String[] envTempArray = envTempTv.split("-");
            if(envTempArray.length==1){
                String lowTemp = envTempArray[0];

            }else  if(envTempArray.length==2){
                String lowTemp = envTempArray[0];
                if(lowTemp == null || lowTemp.trim().length() ==0){

                }
                String highTemp = envTempArray[1];

            }


            //===============================================================================
        }else{
            String sort = "";
            //从数据库读取阈值
            EartagConfigPropertiesEntity configPropertiesEntity = configPropertiesRepo.getThresholdVal(farmId,sort);
            if(configPropertiesEntity != null){
                String lowTemp = configPropertiesEntity.getProVal1();
                String highTemp = configPropertiesEntity.getProVal2();


                //===============================================================================
            }else{
                log.error(farmId+"牧场的环境温度高低温阈值为空.请检查，否则不能进行设备的高低温异常统计.");
            }
        }
    }

    /**
     * @Method      : updateDeviceOnlineWithEnvtemp
     * @Description : 更新在线统计
     * @Params      :
     * @Return      :
     *
     * @Author      : ZhuoNing
     * @Date        : 2022/3/14
     * @Time        : 14:27
     */
    private void updateDeviceOnlineWithEnvtemp(String farmId, String deviceCode,String envtemp,java.sql.Date todayDate,Timestamp nowTimestamp) throws ParseException {
        String todayDateText = new com.huimv.eartag.utils.DateUtil().getTodayDateText();
        String hashKey = BizConst.DEVICE_REGISTER_PREFIX+deviceCode;
        //计算设备别名
        String alias = (String)cacheService.getHashProperty(hashKey,"deviceAlias");
        //读取在线日期
        EartagDeviceOnlineEntity eartagDeviceOnlineEntity = eartagDeviceOnlineRepo.getDeviceOnline(deviceCode, todayDateText);
        if (eartagDeviceOnlineEntity == null) {
            Integer heartbeatTotal = 0;
            Integer envtempTotal = 1;
            Timestamp heartbeatFirstTime = null;
            Timestamp heartbeatLastTime = null;
            Timestamp envtempFirstTime = nowTimestamp;
            Timestamp envtempLastTime = nowTimestamp;
            Timestamp firstTime = nowTimestamp;
            Timestamp lastTime = nowTimestamp;
            //{计算耳标总数}
//            Integer eartagTotal = eartagService.getEartagRegTotalByFarmId(farmId);
            Integer eartagTotal = 0;
            Integer liveStatus = 1;
            //{新建设备在线统计并创建缓存}
            newDeviceOnline(deviceCode,alias,heartbeatTotal,envtempTotal,eartagTotal,envtemp,todayDate,farmId,heartbeatFirstTime,heartbeatLastTime,envtempFirstTime,envtempLastTime,firstTime,lastTime,liveStatus);
        }else{
            eartagDeviceOnlineEntity.setAlias(alias);
            int envtempTotal = eartagDeviceOnlineEntity.getEnvtempTotal();
            eartagDeviceOnlineEntity.setEnvtempTotal(++envtempTotal);
            eartagDeviceOnlineEntity.setLastEnvtemp(envtemp);
            if(eartagDeviceOnlineEntity.getEnvtempFirstTime() == null){
                eartagDeviceOnlineEntity.setEnvtempFirstTime(nowTimestamp);
            }
            eartagDeviceOnlineEntity.setEnvtempLastTime(nowTimestamp);
            if(eartagDeviceOnlineEntity.getFirstTime() == null){
                eartagDeviceOnlineEntity.setFirstTime(nowTimestamp);
            }
            eartagDeviceOnlineEntity.setLastTime(nowTimestamp);
            eartagDeviceOnlineRepo.saveAndFlush(eartagDeviceOnlineEntity);
            //更新设备在线缓存数据
            cacheService.putDeviceInOnline(deviceCode,eartagDeviceOnlineEntity);
        }
    }

    /**
     * @Method      : newDeviceOnline
     * @Description : 创建设备在线
     * @Params      : [farmId, deviceCode]
     * @Return      : void
     *newDeviceOnline(deviceCode,alias,heartbeatTotal,envtempTotal,temp,todayDate,farmId,heartbeatFirstTime,heartbeatLastTime,nowTimestamp);
     * @Author      : ZhuoNing
     * @Date        : 2022/3/14
     * @Time        : 14:27
     */
    private void newDeviceOnline(String deviceCode, String alias, Integer heartbeatTotal, Integer envtempTotal, Integer eartagTotal, String temp, java.sql.Date todayDate, String farmId, Timestamp heartbeatFirstTime, Timestamp heartbeatLastTime, Timestamp envtempFirstTime, Timestamp envtempLastTime, Timestamp firstTime, Timestamp lastTime, Integer liveStatus) {
        EartagDeviceOnlineEntity newEartagDeviceOnlineEntity = new EartagDeviceOnlineEntity();
        newEartagDeviceOnlineEntity.setDeviceCode(deviceCode);
        newEartagDeviceOnlineEntity.setAlias(alias);
        newEartagDeviceOnlineEntity.setHeartbeatTotal(heartbeatTotal);;
        newEartagDeviceOnlineEntity.setEnvtempTotal(envtempTotal);
        newEartagDeviceOnlineEntity.setEartagTotal(eartagTotal);
        newEartagDeviceOnlineEntity.setLastEnvtemp(temp);
        newEartagDeviceOnlineEntity.setAddDate(todayDate);
        newEartagDeviceOnlineEntity.setFarmId(farmId);
        newEartagDeviceOnlineEntity.setHeartbeatFirstTime(heartbeatFirstTime);
        newEartagDeviceOnlineEntity.setHeartbeatLastTime(heartbeatLastTime);
        newEartagDeviceOnlineEntity.setEnvtempFirstTime(envtempFirstTime);
        newEartagDeviceOnlineEntity.setEnvtempLastTime(envtempLastTime);
        newEartagDeviceOnlineEntity.setFirstTime(firstTime);
        newEartagDeviceOnlineEntity.setLastTime(lastTime);
        newEartagDeviceOnlineEntity.setLiveStatus(liveStatus);
        eartagDeviceOnlineRepo.saveAndFlush(newEartagDeviceOnlineEntity);
        //将新建的设备在线数据更新到设备在线缓存
        cacheService.putDeviceInOnline(deviceCode,newEartagDeviceOnlineEntity);
    }

//    @Override
    public void saveDeviceTemp(JSONObject dataJo, java.sql.Date todayDate, Timestamp nowTimestamp) throws ParseException {
        DateUtil dateUtil = new DateUtil();
//        MathUtil mathUtil = new MathUtil();
        String device = dataJo.getString("device");
        String askTime = dateUtil.rebuildDateTime(dataJo.getString("askTime"));
        String temp = dataJo.getString("temp");
        EartagEnvEntity envEntity = new EartagEnvEntity();
        envEntity.setDeviceCode(device);
        envEntity.setTemp1(Integer.parseInt(temp));
        envEntity.setTemp2(Float.parseFloat(MathUtil.countEnvtemp(temp,2)));
        envEntity.setAddTime(nowTimestamp);
        envEntity.setAskTime(new Timestamp(dateUtil.parseDateTime(askTime).getTime()));
        envEntity.setCreateDate(todayDate);
        envEntity.setAskDate(new java.sql.Date(dateUtil.parseDate(dateUtil.getAskDate(dataJo.getString("askTime"))).getTime()));
        envRepo.saveAndFlush(envEntity);
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////

    @Override
    public void countEffectiveDeviceTotal(JSONObject deviceRegisterJo) {
        String farmId = deviceRegisterJo.getString("farmId");
        //{}
        Integer effectiveDeviceTotal = getEffectiveDeviceSum(farmId);
        System.out.println("## effectiveDeviceTotal >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"+effectiveDeviceTotal);
        //{设置设备总数}
        cacheService.putDeviceTotal(effectiveDeviceTotal,farmId);
    }

    @Override
    public void countEffectiveDeviceTotal(Map inMap) {
        String farmId = inMap.get("farmId").toString();
        //{}
        Integer effectiveDeviceTotal = getEffectiveDeviceSum(farmId);
        System.out.println("##<注销设备> effectiveDeviceTotal>>"+effectiveDeviceTotal);
        //{设置设备总数}
        cacheService.putDeviceTotal(effectiveDeviceTotal,farmId);
    }

    //读取有效的设备数量
    public Integer getEffectiveDeviceSum(String farmId){
        List<Object[]> deviceRegisterList = deviceRegisterRepo.getDeviceCountByFarmId(farmId);
        Object[] deviceRegObj = (Object[]) deviceRegisterList.get(0);
        //设备总数
        return Integer.parseInt(deviceRegObj[0].toString());
    }

    @Override
    public void countFarmAllStatus(JSONObject deviceRegisterJo) throws ParseException {
        String farmId = deviceRegisterJo.getString("farmId");
        //{}
//        remoteProcessFarmAllStatus(farmId);
        String todayDateText = new com.huimv.eartag.utils.DateUtil().getTodayDateText();
        java.sql.Date todayDate = new java.sql.Date(new java.util.Date().getTime());
        Timestamp nowTimestamp = new Timestamp(new java.util.Date().getTime());
        //{更新牧场总状态}
        updateEnvtempOfDeviceAllStatus(farmId,todayDateText,todayDate,nowTimestamp);
    }

    @Override
    public void unCancelDeviceOnlineLiveStatus(JSONObject deviceRegisterJo, String todayDateText) {
        String deviceCode = deviceRegisterJo.getString("deviceCode");
        String farmId = deviceRegisterJo.getString("farmId");
        System.out.println("## <unCancelDeviceOnlineLiveStatus> deviceCode="+deviceCode);
        System.out.println("## <unCancelDeviceOnlineLiveStatus> todayDateText="+todayDateText);
        EartagDeviceOnlineEntity deviceOnlineEntity = eartagDeviceOnlineRepo.getDeviceOnline(deviceCode,todayDateText);
        if(deviceOnlineEntity == null){
            log.error("该设备当天在线记录不存在.");
            //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        }else{
            Integer liveStatus = 1;
            deviceOnlineEntity.setLiveStatus(liveStatus);
            eartagDeviceOnlineRepo.saveAndFlush(deviceOnlineEntity);
            //更新缓存(从缓存里将该设备从set里取出,同时将该数据表对应的缓存更新)
            cacheService.putDeviceInOnline(deviceCode,deviceOnlineEntity);
            //从在线集合种删除设备编码
            cacheService.putDeviceToOnlineSet(farmId,deviceCode,todayDateText);
        }
    }

    @Override
    public void cancelFarmAllStatus(Map map) throws ParseException {
        String farmId = map.get("farmId").toString();
        String todayDateText = new com.huimv.eartag.utils.DateUtil().getTodayDateText();
        java.sql.Date todayDate = new java.sql.Date(new java.util.Date().getTime());
        Timestamp nowTimestamp = new Timestamp(new java.util.Date().getTime());
        //{取消牧场总状态}
        cancelEnvtempOfDeviceAllStatus(farmId,todayDateText,todayDate,nowTimestamp);
    }

    public void cancelEnvtempOfDeviceAllStatus(String farmId, String todayDateText, java.sql.Date todayDate, Timestamp nowTimestamp) throws ParseException {
//        System.out.println("## farmId>>"+farmId);
        //{获取处于工作状态的设备数量}
        Integer deviceTotal = getDeviceTotalByFarmIdFromDeviceRegister(farmId);
        System.out.println("## A.deviceTotal>>"+deviceTotal);
        if(deviceTotal == 0){
            log.error("出错:设备总数(deviceTotal)不能为0.");
        }
        //设备在线数量
        Integer deviceOnlineSum = cacheService.getDeviceOnlineSum(farmId,todayDateText);
        System.out.println("# B.设备当前在线数量(deviceOnlineSum)="+deviceOnlineSum);
//        deviceOnlineSum--;
//        System.out.println("# 设备当前在线数量(deviceOnlineSum) 2="+deviceOnlineSum);
        //设备离线数量
        Integer deviceOfflineSum = 0;
        if(deviceTotal > deviceOnlineSum){
            deviceOfflineSum = deviceTotal - deviceOnlineSum;
        }
        System.out.println("## C.deviceOnlineSum>>"+deviceOnlineSum);
        System.out.println("## D.deviceOfflineSum>>"+deviceOfflineSum);
        //设备在线率
        BigDecimal deviceRateBd= new BigDecimal(deviceOnlineSum).divide(new BigDecimal(deviceTotal),1,BigDecimal.ROUND_HALF_UP);
        Float deviceOnlineRate = Float.parseFloat(deviceRateBd.toString());
        System.out.println("## E.deviceOnlineRate>>"+deviceOnlineRate);
        //{获取注销设备数量}
        Integer deviceCancelSum = getDeviceCancelTotalFromDeviceRegister(farmId);
        Integer eartagOnlineSum = 0;
        Float eartagOnlineRate = 0F;
        //耳标总数量
        Integer eartagTotal = getEartagRegTotalByFarmId(farmId);
        if(eartagTotal != 0){
            //耳标在线数量
            eartagOnlineSum = getEartagOnelineTotal(farmId,todayDateText);
            //耳标在线率
            BigDecimal eartagRateBd= new BigDecimal(eartagOnlineSum).divide(new BigDecimal(eartagTotal),1,BigDecimal.ROUND_HALF_UP);
            eartagOnlineRate = Float.parseFloat(eartagRateBd.toString());
        }
        //
        EartarFarmAllStatusEntity farmAllStatusEntity = eartagFarmAllStatusRepo.getOneByFarmIdAndCreateDate(farmId,todayDateText);
        if(farmAllStatusEntity == null){
            //{新建设备状态记录并更新缓存cache}
            createNewFarmAllStatus(farmId,todayDate,nowTimestamp,deviceTotal,deviceOnlineSum,deviceOfflineSum,deviceCancelSum,deviceOnlineRate,eartagTotal,eartagOnlineSum,eartagOnlineRate);
        }else{
            //计算设备状态并更新缓存cache(在线数+1，离线数-1，计算设备在线率)
            farmAllStatusEntity.setDeviceTotal(deviceTotal);
            farmAllStatusEntity.setDeviceOnline(deviceOnlineSum);
            farmAllStatusEntity.setDeviceOffline(deviceOfflineSum);
            farmAllStatusEntity.setDeviceRate(deviceOnlineRate);
            farmAllStatusEntity.setDeviceCancel(deviceCancelSum);
            farmAllStatusEntity.setEartagTotal(eartagTotal);
            farmAllStatusEntity.setEartagOnline(eartagOnlineSum);
            farmAllStatusEntity.setEartagRate(eartagOnlineRate);
            farmAllStatusEntity.setUpdateTime(nowTimestamp);
            eartagFarmAllStatusRepo.saveAndFlush(farmAllStatusEntity);
            System.out.println("## 更新的内容="+farmAllStatusEntity);
            //# 同步更新牧场总状态缓存相关字段 #
            cacheService.flashAllStatusCache(farmId,farmAllStatusEntity);
        }
    }

    @Override
    public void cancelDeviceOnlineLiveStatus(Map map, String todayDateText) {
        String deviceCode = map.get("deviceCode").toString();
        String farmId = map.get("farmId").toString();
        System.out.println("## <cancelDeviceOnlineLiveStatus> todayDateText="+todayDateText);
        System.out.println("## <cancelDeviceOnlineLiveStatus> deviceCode="+deviceCode);
        EartagDeviceOnlineEntity deviceOnlineEntity = eartagDeviceOnlineRepo.getDeviceOnline(deviceCode,todayDateText);
        System.out.println("## <cancelDeviceOnlineLiveStatus> deviceOnlineEntity="+deviceOnlineEntity);
        if(deviceOnlineEntity == null){
            log.error("该设备当天在线记录不存在.");
            //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        }else{
            Integer liveStatus = 0;
            deviceOnlineEntity.setLiveStatus(liveStatus);
            eartagDeviceOnlineRepo.saveAndFlush(deviceOnlineEntity);
            //更新缓存(从缓存里将该设备从set里取出,同时将该数据表对应的缓存更新)
            cacheService.putDeviceInOnline(deviceCode,deviceOnlineEntity);
            //从在线集合种删除设备编码
            cacheService.deleteDeviceToOnlineSet(farmId,deviceCode,todayDateText);
        }
    }

    //--处理状态数据
    private void handleEartagAllState() {

    }

    //--处理在线记录数据
    private void handleEartagOnline() {

    }

    //--处理注册表数据
    private void handleEartagRegister() {

    }
}
