package com.xy.service;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xy.config.DeviceThreadPoolConfig;
import com.xy.dbmapper.SyncUpdate;
import com.xy.device.EnumDevcieDoorStatus;
import com.xy.device.EnumDeviceTempConfig;
import com.xy.dto.ActivityInfoDto;
import com.xy.dto.DeviceEventMsgDto;
import com.xy.dto.DeviceStatusDto;
import com.xy.dto.DeviceTempRecordsDto;
import com.xy.entity.DeviceConfig;
import com.xy.entity.DeviceStatus;
import com.xy.entity.DeviceSysinfo;
import com.xy.mapper.DeviceStatusMapper;
import com.xy.mapper.entity.DeviceStatusCount;
import com.xy.utils.*;
import com.xy.utils.enums.DeviceErrorRecordTypesEnum;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import static com.xy.utils.Beans.copy;
/**
*
* 设备-状态 服务实现类
*
*
* @author lijin
* @since 2022-12-23
*/
@Service
@AllArgsConstructor
@Slf4j
@Api(tags = "设备-状态")
public class DeviceStatusServiceImpl extends ServiceImpl implements DeviceStatusService {
private DeviceTempRecordsServiceImpl deviceTempRecordsService;
private ActivityInfoService activityInfoService;
private DeviceConfigServiceImpl deviceConfigService;
private DeviceEventMsgService deviceEventMsgService;
private RedisService redisService;
private DeviceSysinfoServiceImpl deviceSysinfoService;
@Override
@ApiOperation("上报信息")
public R up(DeviceStatusDto.Up up) {
log.info("设备信息上报:{}", JSONUtil.toJsonStr(up));
DeviceStatus deviceStatusInfo = getById(up.getDeviceId());
if (deviceStatusInfo == null) {
return R.ok();
}
DeviceStatus deviceStatus = copy(DeviceStatus.class, up).setUpdateTime(LocalDateTime.now());
updateById(deviceStatus);
//温度上报
if (Emptys.check(deviceStatus.getTempValue())) {
DeviceSysinfo deviceSysinfo = deviceSysinfoService.getById(up.getDeviceId());
//添加设备温度日志
if (deviceSysinfo.getIsHaveTemp()) {
DeviceTempRecordsDto.Save save = new DeviceTempRecordsDto.Save()
.setDeviceId(up.getDeviceId());
save.setTempValue(deviceStatus.getTempValue());
deviceTempRecordsService.save(save);
//查询设备配置
DeviceConfig deviceConfig = deviceConfigService.getById(deviceStatus.getDeviceId());
Integer tempMax = deviceConfig.getTempMax();
Integer tempMin = deviceConfig.getTempMin();
//温度有异常
String key = String.format("device_temp_error:%s:%s", deviceStatus.getDeviceId(), deviceStatus.getTempValue() >= tempMax ? "max" : "min");
if (deviceStatus.getTempValue() > tempMax || deviceStatus.getTempValue() < tempMin) {
//校验异常次数
Integer errorSize = SysDictUtils.getValue(EnumDeviceTempConfig.Code.CODE.getCode(), EnumDeviceTempConfig.ERROR_SIZE.getCode(), Integer.class);
boolean fal = false;
Integer maxSize = redisService.get(key);
if (maxSize == null) {
redisService.set(key, 1, 60 * 60);
} else {
if (maxSize >= errorSize) {
fal = true;
redisService.remove(key);
} else {
redisService.set(key, maxSize + 1, 60 * 60);
}
}
//添加事件
if (fal) {
DeviceEventMsgDto.Save deviceEventMsg = new DeviceEventMsgDto.Save()
.setDeviceId(deviceStatus.getDeviceId());
deviceEventMsg.setCode(DeviceErrorRecordTypesEnum.T.getCode());
String msg = "温度异常-温度阈值%d,当前温度%d";
if (deviceStatus.getTempValue() >= tempMax) {
deviceEventMsg.setMsg(String.format(msg, tempMax, deviceStatus.getTempValue()));
}
if (deviceStatus.getTempValue() <= tempMin) {
deviceEventMsg.setMsg(String.format(msg, tempMin, deviceStatus.getTempValue()));
}
deviceEventMsgService.save(deviceEventMsg);
}
} else {
redisService.remove(key);
}
}
}
//上报关门
if (Emptys.check(deviceStatus.getDoorStateL())) {
Integer value = SysDictUtils.getValue(EnumDevcieDoorStatus.Code.CODE.getCode(), EnumDevcieDoorStatus.LOCKED.getCode(), Integer.class);
if (deviceStatus.getDoorStateL().equals(value)) {
ThreadPoolUtils.excPoll(DeviceThreadPoolConfig.DEVICE_COMMON_POLL, 1)
.execute(() -> activityInfoService.abort(new ActivityInfoDto.Abort()
.setDeviceId(up.getDeviceId())
.setWorkType(2)
.setTimeout(60 * 1)
));
}
}
return R.ok();
}
@Override
@ApiOperation("开关门")
public R door(DeviceStatusDto.Door door) {
DeviceStatus deviceStatus = copy(DeviceStatus.class, door).setUpdateTime(LocalDateTime.now());
updateById(deviceStatus);
return R.ok();
}
/**
* 修改库存
*
* @return
*/
public R upStock(long deviceId, int stock) {
DeviceStatus deviceStatusInfo = getById(deviceId);
if (deviceStatusInfo == null) {
return R.ok();
}
new SyncUpdate().update(DeviceStatus.class)
.set(DeviceStatus::getStock, new BigDecimal(stock))
.udateDateTime(DeviceStatus::getUpdateTime)
.eq(DeviceStatus::getDeviceId, deviceId)
.exec();
return R.ok();
}
@Override
@ApiOperation("更新联网状态")
public R updateNetState(DeviceStatusDto.UpdateNetState dto) {
updateById(new DeviceStatus().setDeviceId(dto.getDeviceId()).setNetState(dto.getNetState()));
return R.ok();
}
@PostMapping("obj")
@ApiOperation("对象查询")
public R obj(@RequestBody DeviceStatusDto.Vo vo) {
LambdaQueryWrapper lambdaQueryWrapper = new MybatisPlusQuery().eqWrapper(vo, DeviceStatus.class).build();
List list = list(lambdaQueryWrapper);
if (!Emptys.check(list)) {
return R.ok();
}
return R.ok(copy(DeviceStatusDto.Vo.class, list.get(0)));
}
@PostMapping("list")
@ApiOperation("集合查询")
public R> list(@RequestBody DeviceStatusDto.SelectList selectList) {
LambdaQueryWrapper lambdaQueryWrapper = new MybatisPlusQuery().eqWrapper(selectList, DeviceStatus.class)
.in(DeviceStatus::getDeviceId, selectList.getDeviceIds())
.build();
List list = list(lambdaQueryWrapper);
return R.ok(copy(DeviceStatusDto.Vo.class, list));
}
@PostMapping("statusCount")
@ApiOperation("统计状态数量")
public R statusCount() {
DeviceStatusCount deviceStatusCount = baseMapper.statusCount();
return R.ok(deviceStatusCount);
}
}