Merge remote-tracking branch 'origin/cjl' into qa
1 files added
15 files modified
| | |
| | | int i = 0; |
| | | return new ResultMessage(); |
| | | } |
| | | |
| | | @GetMapping("insertHistoryFiveMinutely") |
| | | @ApiOperation(value = "5分钟数据", notes = "5分钟数据") |
| | | public ResultMessage insertHistoryFiveMinutely() { |
| | | historyFiveMinutelyService.insertHistoryFiveMinutely(); |
| | | return new ResultMessage(); |
| | | } |
| | | |
| | | @GetMapping("FiveMinutelyTest") |
| | | @ApiOperation(value = "5分钟数据1", notes = "5分钟数据1") |
| | | public ResultMessage FiveMinutelyTest(String yz,String mac) { |
| | |
| | | package com.moral.api.entity; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.IdType; |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.extension.activerecord.Model; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = false) |
| | | @JsonIgnoreProperties(ignoreUnknown = true) |
| | | public class Device extends Model<Device> { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | |
| | | /** |
| | | * 创建(生产)时间 |
| | | */ |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") |
| | | private Date createTime; |
| | | |
| | | /** |
| | | * 更新时间 |
| | | */ |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") |
| | | private Date updateTime; |
| | | |
| | | /** |
| | | * 安装时间 |
| | | */ |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") |
| | | private Date installTime; |
| | | |
| | | /** |
| | |
| | | */ |
| | | private Integer townCode; |
| | | |
| | | |
| | | @Override |
| | | protected Serializable pkVal() { |
| | | return this.id; |
| | | } |
| | | /* |
| | | * 设备型号 |
| | | * */ |
| | | @TableField(exist = false) |
| | | private Version version; |
| | | /* |
| | | *序号 |
| | | * */ |
| | | private Integer devNum; |
| | | |
| | | } |
| | |
| | | package com.moral.api.entity; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.IdType; |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.extension.activerecord.Model; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import java.io.Serializable; |
| | |
| | | /** |
| | | * 公司自定义因子编号 |
| | | */ |
| | | @TableField(value = "`desc`") |
| | | private String desc; |
| | | |
| | | /** |
| | | * 国标因子编码 |
| | | */ |
| | | @TableField(value = "`code`") |
| | | private String code; |
| | | |
| | | /** |
| | |
| | | */ |
| | | private String isDelete; |
| | | |
| | | @TableField(exist = false) |
| | | private String unit; |
| | | |
| | | @Override |
| | | protected Serializable pkVal() { |
| | | return this.id; |
| | | } |
| | | @TableField(exist = false) |
| | | private String unitKey; |
| | | |
| | | @TableField(exist = false) |
| | | private String showUnit; |
| | | |
| | | @TableField(exist = false) |
| | | private String showUnitKey; |
| | | |
| | | @TableField(exist = false) |
| | | private String alarmLevel; |
| | | |
| | | @TableField(exist = false) |
| | | private String formula; |
| | | |
| | | } |
New file |
| | |
| | | package com.moral.api.entity; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.IdType; |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.extension.activerecord.Model; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * <p> |
| | | * 型号表 |
| | | * </p> |
| | | * |
| | | * @author moral |
| | | * @since 2021-05-14 |
| | | */ |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = false) |
| | | public class Version extends Model<Version> { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | | * 主键 |
| | | */ |
| | | @TableId(value = "id", type = IdType.AUTO) |
| | | private Integer id; |
| | | |
| | | /** |
| | | * 名称 |
| | | */ |
| | | private String name; |
| | | |
| | | /** |
| | | * 创建时间 |
| | | */ |
| | | private Date createTime; |
| | | |
| | | /** |
| | | * 更新时间 |
| | | */ |
| | | private Date updateTime; |
| | | |
| | | /** |
| | | * 是否删除 |
| | | */ |
| | | private String isDelete; |
| | | |
| | | /** |
| | | * 描述 |
| | | */ |
| | | @TableField(value = "`desc`") |
| | | private String desc; |
| | | |
| | | /* |
| | | * 版本拥有的因子 |
| | | * */ |
| | | @TableField(exist = false) |
| | | private List<Sensor> sensors; |
| | | |
| | | |
| | | |
| | | |
| | | } |
| | |
| | | |
| | | List<Map<String, Object>> getHistoryMinutelyData(Map<String, Object> params); |
| | | |
| | | List<String> getHistoryMinutelyMacData(Map<String, Object> params); |
| | | |
| | | List<Map<String, Object>> getHourlyData(Map<String, Object> params); |
| | | } |
| | |
| | | @Override |
| | | public void judgeOffLineDevice() { |
| | | QueryWrapper<Device> queryWrapper = new QueryWrapper<>(); |
| | | queryWrapper.ne("state", Constants.DEVICE_STATE_OFFLINE); |
| | | queryWrapper.eq("state", Constants.DEVICE_STATE_OFFLINE); |
| | | queryWrapper.eq("is_delete",Constants.NOT_DELETE); |
| | | //获取所有在线设备 |
| | | List<Device> devices = deviceMapper.selectList(queryWrapper); |
| | | for (Device device : devices) { |
| | | Map<String, Object> data = (Map<String, Object>) redisTemplate.opsForHash().get(RedisConstants.DATA_SECOND, device.getMac()); |
| | | Map<String, Object> data = (Map<String, Object>) redisTemplate.opsForHash().get(RedisConstants.DATA_FIVE_MINUTES, device.getMac()); |
| | | device.setState(Constants.DEVICE_STATE_OFFLINE); |
| | | if (data != null && data.containsKey("DataTime")) { |
| | | Date time = DateUtils.getDate((String) data.get("DataTime"), DateUtils.yyyyMMddHHmmss_EN); |
| | | if (data != null && data.containsKey("dataTime")) { |
| | | Date time = DateUtils.getDate((String) data.get("dataTime"), DateUtils.yyyyMMddHHmmss_EN); |
| | | //超过两分钟无数据就离线 |
| | | if (DateUtils.getDateOfMin(time, 2).getTime() < new Date().getTime()) { |
| | | if (DateUtils.getDateOfMin(time, 12).getTime() > new Date().getTime()) { |
| | | device.setState("1"); |
| | | updateDeviceState(device); |
| | | } |
| | | } else { |
| | | updateDeviceState(device); |
| | | } |
| | | } |
| | | } |
| | |
| | | package com.moral.api.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; |
| | | import com.googlecode.aviator.AviatorEvaluator; |
| | | import com.googlecode.aviator.Expression; |
| | | import com.moral.api.entity.Device; |
| | | import com.moral.api.service.DeviceService; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.data.redis.core.RedisTemplate; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.util.CollectionUtils; |
| | | import org.springframework.util.ObjectUtils; |
| | | |
| | | import java.util.*; |
| | |
| | | @Service |
| | | public class HistoryFiveMinutelyServiceImpl implements HistoryFiveMinutelyService { |
| | | |
| | | @Value("${result.device.list}") |
| | | private String deviceList; |
| | | @Autowired |
| | | private HistoryFiveMinutelyMapper historyFiveMinutelyMapper; |
| | | |
| | |
| | | |
| | | @Autowired |
| | | private RedisTemplate redisTemplate; |
| | | |
| | | @Autowired |
| | | private DeviceService deviceService; |
| | | |
| | | @Override |
| | | public void createTable(String timeUnits) { |
| | |
| | | if (fiveMinutelyData.size() == 0) { |
| | | return; |
| | | } |
| | | |
| | | listDistDeviceState(params); |
| | | //按mac分组 |
| | | Map<String, List<Map<String, Object>>> data = fiveMinutelyData.parallelStream() |
| | | .collect(Collectors.groupingBy(o -> (String) o.get("mac"))); |
| | |
| | | //银行家算法修约 |
| | | double sciCal = AmendUtils.sciCal(average.getAsDouble(), 4); |
| | | jsonMap.put(sensorCode, sciCal); |
| | | |
| | | } |
| | | |
| | | }); |
| | |
| | | jsonMap.put("dataTime", DateUtils.dateToDateString(start)); |
| | | redisTemplate.opsForHash().put(RedisConstants.DATA_FIVE_MINUTES, key, jsonMap); |
| | | insertData.add(dataMap); |
| | | judgeDeviceState(key,jsonMap); |
| | | }); |
| | | |
| | | //5分钟表后缀 |
| | |
| | | //存入数据库 |
| | | historyFiveMinutelyMapper.insertHistoryFiveMinutely(insertData, insertTimeUnits); |
| | | } |
| | | |
| | | // 修改设备状态 |
| | | private void judgeDeviceState(String mac,Map<String, Object> dataMap){ |
| | | Device device = (Device) redisTemplate.opsForHash().get(RedisConstants.DEVICE_INFO, mac); |
| | | List<Sensor> sensors = device.getVersion().getSensors(); |
| | | Expression expression; |
| | | int state = 1; |
| | | for (Sensor sensor : sensors) { |
| | | //因子报警等级 |
| | | String alarmLevel = sensor.getAlarmLevel(); |
| | | if (StringUtils.isEmpty(alarmLevel)) { |
| | | continue; |
| | | } |
| | | List<Object> list = JSONObject.parseObject(alarmLevel, List.class); |
| | | String sensorCode = sensor.getCode(); |
| | | //转换公式 |
| | | String formula = sensor.getFormula(); |
| | | |
| | | //设备所传因子与配置型号因子不一致的处理逻辑 |
| | | if (dataMap.get(sensorCode) != null) { |
| | | String sensorValue = String.valueOf(dataMap.get(sensorCode)); |
| | | double value = Double.parseDouble(sensorValue); |
| | | if (formula != null) { |
| | | //转换后因子值 |
| | | sensorValue = formula.replace("{0}", sensorValue); |
| | | expression = AviatorEvaluator.compile(sensorValue); |
| | | value = Double.parseDouble(expression.execute().toString()); |
| | | } |
| | | int sensorState = judgeState(list, value); |
| | | if (sensorState > state) { |
| | | state = sensorState; |
| | | } |
| | | } |
| | | } |
| | | //修改设备状态 |
| | | Device devices = new Device(); |
| | | devices.setId(device.getId()); |
| | | devices.setState(String.valueOf(state)); |
| | | deviceService.updateById(devices); |
| | | } |
| | | |
| | | |
| | | private int judgeState(List<Object> levels, Double data) { |
| | | int state = 1; |
| | | for (int i = levels.size() - 1; i >= 0; i--) { |
| | | Double level = Double.parseDouble(levels.get(i).toString()); |
| | | if (data >= level) { |
| | | state = i + 2; |
| | | break; |
| | | } |
| | | } |
| | | return state; |
| | | } |
| | | |
| | | private void listDistDeviceState(Map<String, Object> params){ |
| | | QueryWrapper<Device> queryWrapper = new QueryWrapper<>(); |
| | | queryWrapper.eq("is_delete",Constants.NOT_DELETE); |
| | | //获取所有在线设备 |
| | | List<Device> devices = deviceService.list(queryWrapper); |
| | | List<String> macOldList = devices.stream().map(Device::getMac).collect(Collectors.toList()); |
| | | List<String> macList = historyMinutelyMapper.getHistoryMinutelyMacData(params); |
| | | if(!CollectionUtils.isEmpty(macOldList)){ |
| | | List<String> listDictDevice = Arrays.asList(deviceList.split(",")); |
| | | List<String> list2 = macOldList.stream().filter(e -> !listDictDevice.contains(e)).collect(Collectors.toList()); |
| | | List<String> list3 = list2.stream().filter(e -> !macList.contains(e)).collect(Collectors.toList()); |
| | | List<Integer> idList = devices.stream().filter(e->list3.contains(e.getMac())).map(Device::getId).collect(Collectors.toList()); |
| | | for(Integer i : idList){ |
| | | Device device = new Device(); |
| | | device.setId(i); |
| | | device.setState(Constants.DEVICE_STATE_OFFLINE); |
| | | deviceService.updateById(device); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | @Override |
| | | public void insertHistoryFiveMinutely(String yz, String mac) { |
| | |
| | | //获取数据的分钟表后缀 |
| | | String timeUnits = DateUtils.dateToDateString(start, DateUtils.yyyyMM_EN); |
| | | params.put("timeUnits", timeUnits); |
| | | if(!StringUtils.isEmpty(mac)){ |
| | | /*if(!StringUtils.isEmpty(mac)){ |
| | | params.put("macs", Arrays.asList(mac)); |
| | | } |
| | | }*/ |
| | | //因子 |
| | | QueryWrapper<Sensor> sensorQueryWrapper = new QueryWrapper<>(); |
| | | sensorQueryWrapper.select("code", "lower", "upper").eq("is_delete", Constants.NOT_DELETE); |
| | | if(!StringUtils.isEmpty(yz)){ |
| | | /*if(!StringUtils.isEmpty(yz)){ |
| | | sensorQueryWrapper.eq("code",yz); |
| | | } |
| | | }*/ |
| | | List<Sensor> sensors = sensorService.list(sensorQueryWrapper); |
| | | |
| | | //获取所有设备的5分钟内的数据 |
| | |
| | | if (fiveMinutelyData.size() == 0) { |
| | | return; |
| | | } |
| | | |
| | | listDistDeviceState(params); |
| | | //按mac分组 |
| | | Map<String, List<Map<String, Object>>> data = fiveMinutelyData.parallelStream() |
| | | .collect(Collectors.groupingBy(o -> (String) o.get("mac"))); |
| | |
| | | jsonMap.put("dataTime", DateUtils.dateToDateString(start)); |
| | | // redisTemplate.opsForHash().put(RedisConstants.DATA_FIVE_MINUTES, key, jsonMap); |
| | | //insertData.add(dataMap); |
| | | judgeDeviceState(key,jsonMap); |
| | | System.out.println(dataMap); |
| | | }); |
| | | |
| | |
| | | redis: |
| | | host: r-bp1xdlb9wfc6zt0msppd13.redis.rds.aliyuncs.com |
| | | port: 6379 |
| | | password: QX_moral_2023 |
| | | password: QxPcRedis_moarl_2320 |
| | | timeout: 30000 |
| | | jedis: |
| | | pool: |
| | |
| | | tokenRedis: |
| | | host: r-bp1xdlb9wfc6zt0msppd13.redis.rds.aliyuncs.com |
| | | port: 6379 |
| | | password: QX_moral_2023 |
| | | password: QxPcRedis_moarl_2320 |
| | | timeout: 30000 |
| | | database: 14 |
| | | pool: |
| | |
| | | filters: stat |
| | | type: com.alibaba.druid.pool.DruidDataSource |
| | | max-wait: 60000 |
| | | url: jdbc:mysql://rm-bp1pr3rx9m3fnkwsk8o13.mysql.rds.aliyuncs.com:3306/moral?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai |
| | | username: moral_qx |
| | | password: QX_moral_2023 |
| | | url: jdbc:mysql://rm-bp1pr3rx9m3fnkwskso.mysql.rds.aliyuncs.com:3306/moral?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai |
| | | username: root |
| | | password: Qx_moralPc_2320 |
| | | test-on-borrow: false |
| | | sql-script-encoding: utf-8 |
| | | pool-prepared-statements: true |
| | |
| | | result: |
| | | date: |
| | | changshu: P5DND7A0245358,P5DND7A0245364,P5DND7A0245413,P5DND7A0245355,P5DND7A0245416,P5DND7A0245426,P5DND7A0245398,P5DND7A0245441,P5DND7A0245429,P5DND7A0245435,P5DND7A0245372,P5DND7A0245397,P5DND7A0245415,P5DND7A0245411,P5DND7A0245407,P5DND7A0245418,P5DND7A0245430,P5DND7A0245493,P5DND7A0245414,P5DND7A0245366,P5DND7A0245442,P5DND7A0245386,P5DND7A0245431,P5DND7A0245394,P5DND7A0245380,P5DND7A0245420,P5DND7A0245440,P5DND7A0245432,P5DND7A0391974,P5DND7A0391989,P5DND7A0245481,P5DND7A0392001,P5DND7A0391991,P5DND7A0391978,P5DND7A0245499 |
| | | device: |
| | | list: p5dnd7a0245499,p5dnd7a0391962 |
| | |
| | | result: |
| | | date: |
| | | changshu: P5DND7A0245358,P5DND7A0245364,P5DND7A0245413,P5DND7A0245355,P5DND7A0245416,P5DND7A0245426,P5DND7A0245398,P5DND7A0245441,P5DND7A0245429,P5DND7A0245435,P5DND7A0245372,P5DND7A0245397,P5DND7A0245415,P5DND7A0245411,P5DND7A0245407,P5DND7A0245418,P5DND7A0245430,P5DND7A0245493,P5DND7A0245414,P5DND7A0245366,P5DND7A0245442,P5DND7A0245386,P5DND7A0245431,P5DND7A0245394,P5DND7A0245380,P5DND7A0245420,P5DND7A0245440,P5DND7A0245432,P5DND7A0391974,P5DND7A0391989,P5DND7A0245481,P5DND7A0392001,P5DND7A0391991,P5DND7A0391978,P5DND7A0245499 |
| | | |
| | | device: |
| | | list: p5dnd7a0245499,p5dnd7a0391962 |
| | |
| | | result: |
| | | date: |
| | | changshu: P5DND7A0245358,P5DND7A0245364,P5DND7A0245413,P5DND7A0245355,P5DND7A0245416,P5DND7A0245426,P5DND7A0245398,P5DND7A0245441,P5DND7A0245429,P5DND7A0245435,P5DND7A0245372,P5DND7A0245397,P5DND7A0245415,P5DND7A0245411,P5DND7A0245407,P5DND7A0245418,P5DND7A0245430,P5DND7A0245493,P5DND7A0245414,P5DND7A0245366,P5DND7A0245442,P5DND7A0245386,P5DND7A0245431,P5DND7A0245394,P5DND7A0245380,P5DND7A0245420,P5DND7A0245440,P5DND7A0245432,P5DND7A0391974,P5DND7A0391989,P5DND7A0245481,P5DND7A0392001,P5DND7A0391991,P5DND7A0391978,P5DND7A0245499 |
| | | |
| | | device: |
| | | list: p5dnd7a0245499,p5dnd7a0391962 |
| | | |
| | |
| | | </if> |
| | | </select> |
| | | |
| | | <select id="getHistoryMinutelyMacData" resultType="java.lang.String"> |
| | | SELECT |
| | | mac |
| | | FROM |
| | | history_minutely_${timeUnits} |
| | | WHERE `time` <![CDATA[>=]]> #{start} |
| | | AND `time` <![CDATA[<]]> #{end} |
| | | <if test="macs != null"> |
| | | AND mac IN |
| | | <foreach collection="macs" item="mac" open="(" close=")" separator=","> |
| | | #{mac} |
| | | </foreach> |
| | | </if> |
| | | group by mac |
| | | </select> |
| | | |
| | | <select id="getHourlyData" resultType="java.util.Map"> |
| | | SELECT mac, `time`, `value` |
| | | FROM history_minutely_${timeUnits} |
| | |
| | | *序号 |
| | | * */ |
| | | private Integer devNum; |
| | | |
| | | } |
| | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.kafka.clients.consumer.ConsumerRecord; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.data.redis.core.RedisTemplate; |
| | | import org.springframework.kafka.annotation.KafkaListener; |
| | | import org.springframework.kafka.support.Acknowledgment; |
| | | import org.springframework.stereotype.Component; |
| | | import org.springframework.util.ObjectUtils; |
| | | |
| | | import java.util.HashMap; |
| | | import java.util.Iterator; |
| | | import java.util.Map; |
| | | |
| | | import java.util.*; |
| | | |
| | | |
| | | @Component |
| | | @Slf4j |
| | | public class DeviceConsumer { |
| | | |
| | | @Value("${result.device.list}") |
| | | private String deviceList; |
| | | @Autowired |
| | | private HistoryMinutelyService historyMinutelyService; |
| | | |
| | |
| | | public void listenSecond(ConsumerRecord<String, String> record, Acknowledgment ack) { |
| | | String msg = record.value(); |
| | | try { |
| | | |
| | | Map<String, Object> data = JSON.parseObject(msg, Map.class); |
| | | Object mac = data.get("mac"); |
| | | Object time = data.get("DataTime"); |
| | | if (ObjectUtils.isEmpty(time) || ObjectUtils.isEmpty(mac)) { |
| | | log.warn("some properties is null, param{}", msg); |
| | | ack.acknowledge(); |
| | | return; |
| | | } |
| | | List<String> listDictDevice = Arrays.asList(deviceList.split(",")); |
| | | if(!listDictDevice.contains(mac.toString())){ |
| | | ack.acknowledge(); |
| | | } |
| | | //数据过滤 |
| | | data.remove("time"); |
| | |
| | | ack.acknowledge(); |
| | | } catch (Exception e) { |
| | | log.error("param{}" + msg); |
| | | ack.acknowledge(); |
| | | } |
| | | } |
| | | |
| | |
| | | TOKEN: |
| | | KEY: |
| | | foh3wi2ooghiCh5 |
| | | result: |
| | | device: |
| | | list: p5dnd7a0245499,p5dnd7a0391962 |
| | | |
| | | |
| | |
| | | TOKEN: |
| | | KEY: |
| | | foh3wi2ooghiCh5 |
| | | result: |
| | | device: |
| | | list: p5dnd7a0245499,p5dnd7a0391962 |
| | | |
| | | |
| | |
| | | TOKEN: |
| | | KEY: |
| | | foh3wi2ooghiCh5 |
| | | |
| | | result: |
| | | device: |
| | | list: p5dnd7a0245499,p5dnd7a0391962 |
| | | |