工作笔记 GPS项目 关键2 设备状态判断之离线

环境:idea

语言:java

框架:springboot

难点:Component调用另外的service和client

思路:

  1. 创建定时任务,这里默认是3秒钟

  1. 遍历每一个设备的最新数据

  1. 根据设备的数据时间,结合设备配置的允许离线时间阈值,判断设备是否离线

  1. 设备已经处理离线状态,则不更新状态

  1. 设备未达到允许离线时间阈值,则不更新状态

  1. 设备数据时间达到允许离线时间阈值,则更新状态

部分代码参考:

new BackService().start();
package com.lhiot.lh02f000.service.job;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
//取消部分内部引用
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * **@ClassName BackService
 * **@Description
 * **@Date 2023/2/2 9:24
 * **@Created by tangbao
 **/
@Slf4j
@Component
public class BackService {
    private Integer delaySecond = 3;// 延迟时间
    private static final ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3);

    private static DeviceClient deviceClient;
    private static DeviceTypeClient deviceTypeClient;
    private static DeviceCfgService deviceCfgService;
    private static DeviceStateService deviceStateService;
    private static PointValueClient pointValueClient;
    private static DeviceCoordinateService deviceCoordinateService;

    @Resource
    public void setDeviceClient(DeviceClient deviceClient) {
        this.deviceClient = deviceClient;
    }

    @Resource
    public void setDeviceTypeClient(DeviceTypeClient deviceTypeClient) {
        this.deviceTypeClient = deviceTypeClient;
    }


    @Resource
    public void setDeviceCfgService(DeviceCfgService deviceCfgService){
        this.deviceCfgService = deviceCfgService;
    }

    @Resource
    public void setDeviceStateService(DeviceStateService deviceStateService){
        this.deviceStateService = deviceStateService;
    }

    @Resource
    public void setPointValueClient(PointValueClient pointValueClient) {
        this.pointValueClient = pointValueClient;
    }

    @Resource
    public void setDeviceCoordinateService(DeviceCoordinateService deviceCoordinateService){
        this.deviceCoordinateService = deviceCoordinateService;
    }

    public BackService() {

    }

    public void run() throws Exception {
        scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
            @Override
            public void run() {
                try {
                    //实时数据对比
                    selectRealDeviceTable();
                } catch (Exception e) {
                    log.error(JSON.toJSONString(e));
                }
            }
        }, 1, delaySecond, TimeUnit.SECONDS);
    }

    public void start() {
        try {
            //load spring frame work
//            SpringContextHolder.loadApplicationContextXml("classpath*:applicationContext.xml");
            this.run();
            log.info("(♥◠‿◠)ノ゙ GPS测温设备定时任务启动成功   ლ(´ڡ`ლ)゙  \n");
//            System.out.println("(♥◠‿◠)ノ゙ GPS测温设备定时任务启动成功   ლ(´ڡ`ლ)゙  \n");
        } catch (Exception e) {
            log.error("BackServer-BackService failed to start due to {}", JSON.toJSONString(e));
        }
    }

    /**
     * 获取设备的实时数据
     * @throws Exception
     */
    public void selectRealDeviceTable() throws Exception {
        DeviceType deviceType = new DeviceType();
        deviceType.setTypeCode("02F000");
        List<DeviceType> deviceTypeList = deviceTypeClient.list(deviceType).getData().getRecords();
        if (null == deviceTypeList || deviceTypeList.size() < 1) {
            log.error("未查询到指定的设备类型");
            return;
        }
        DeviceType deviceType1 = deviceTypeList.get(0);
        Device device = new Device();
        device.setTypeId(deviceType1.getId());
        List<Device> deviceList = deviceClient.list(device).getData().getRecords();
        Map<String, String> deviceStatusMap = deviceClient.deviceStatus(device).getData();
        for (int i = 0; i < deviceList.size(); i++) {
            Device device1 = deviceList.get(i);
            String statusWeb = deviceStatusMap.get(device1.getId());
            DeviceCfg deviceCfg = deviceCfgService.selectByDevId(device1.getId());
            DeviceState deviceState = deviceStateService.selectByDevId(device1.getId());
            if (null == deviceCfg || (deviceCfg.getOfflineMinute() == 0)) {
                if (statusWeb.equals(Common.Device.Status.OFFLINE)) {
                    //因为没有配置,这里就直接插入设备离线状态
                    this.dealDevState(device1, deviceCfg, deviceState);
                }
            } else {
                if (deviceCfg.isOfflineEn()) {
                    this.dealDevState(device1, deviceCfg, deviceState);
                }
            }
        }
    }

    /**
     * 判断设备的状态,这里只判断离线状态
     * @param device  设备对象
     * @param deviceCfg  设备配置对象
     * @param deviceState 设备状态对象
     */
    private void dealDevState(Device device, DeviceCfg deviceCfg, DeviceState deviceState) {
        if (null == deviceState) {
            //设备还没有插入状态,则不做任何处理
            return;
        } else {
            //设备已经插入了状态,则需要处理
            if (deviceState.getState() == 0) {
                //已经处于离线状态,就不需要再更新状态,直接返回
                return;
            }
            Map<Integer, Object> pointValueMap = this.getPointValueMap(device.getId(), "60");
            if (null == pointValueMap) {
                return;
            }
            long offlineMinute = 2; //如果设备没有配置离线时间,则默认为2分钟离线
            Date date = this.getDate(pointValueMap);
            long disTime = DateUtil.between(date, new Date(), DateUnit.MINUTE);
            if ((null != deviceCfg) && (deviceCfg.getOfflineMinute() > 0)) {
                //如果设备有配置,则判断离线
                offlineMinute = deviceCfg.getOfflineMinute();
            }
            if(disTime > offlineMinute) {
                log.info("设备离线判断执行");
                DeviceCoordinate deviceCoordinate = deviceCoordinateService.selectByDevId(device.getId());
                deviceState.setEndTime(new Date());
                deviceStateService.update(deviceState);
                DeviceState deviceState1 = new DeviceState();
                deviceState1.setDeviceId(device.getId());
                deviceState1.setState(0);
                deviceState1.setStartTime(date); //离线开始时间用最新信号的时间
                deviceState1.formatDeviceInfo(pointValueMap);
                deviceState1.formatDevAddr(pointValueMap, deviceCoordinate);
                deviceState1.setAlarmCode("00000");
                deviceState1.setAlarmInfo("设备离线");
                deviceStateService.add(deviceState1);
            }
        }

    }

    /**
     * 获取实时数据的信号量和信号值
     *
     * @param deviceId 设备ID
     * @param funCode  功能码
     * @return
     */
    private Map<Integer, Object> getPointValueMap(String deviceId, String funCode) {
        PointValue pointValue = pointValueClient.realtime(deviceId, funCode).getData();
        pointValue = Optional.ofNullable(pointValue).orElseGet(
                () -> (Optional.ofNullable(pointValueClient.latest(deviceId, funCode).getData()).orElseGet(() -> new PointValue())
                ));
        List<PointValue> pointValues = Optional.ofNullable(pointValue.getChildren()).orElseGet(() -> new ArrayList<>());
        if (pointValues.size() == 0) {
            return null;
        }
        //将list转换map
        Map<Integer, Object> pointValueMap = pointValues.stream().collect(Collectors.toMap(PointValue::getPointOrderNum, Function.identity(), (n1, n2) -> n1, TreeMap::new));
        if (null != pointValue.getOriginTime()) {
            ((PointValue) pointValueMap.get(0)).setOriginTime(pointValue.getOriginTime());
        }
        return pointValueMap;
    }

    private Date getDate(Map<Integer, Object> pointValueMap){
        Date date = ((PointValue) pointValueMap.get(0)).getCreateTime();
        if(null == date){
            date = ((PointValue) pointValueMap.get(0)).getOriginTime();
        }
        return date;
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值