DeviceStatusServiceImpl.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. package com.xy.service;
  2. import cn.hutool.json.JSONObject;
  3. import cn.hutool.json.JSONUtil;
  4. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  5. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  6. import com.xy.config.DeviceThreadPoolConfig;
  7. import com.xy.dbmapper.SyncUpdate;
  8. import com.xy.device.EnumDevcieDoorStatus;
  9. import com.xy.device.EnumDeviceTempConfig;
  10. import com.xy.device.EnumMqttCmdTempletTask;
  11. import com.xy.dto.*;
  12. import com.xy.entity.*;
  13. import com.xy.mapper.DeviceStatusMapper;
  14. import com.xy.mapper.entity.DeviceStatusCount;
  15. import com.xy.utils.*;
  16. import com.xy.utils.enums.DeviceErrorRecordTypesEnum;
  17. import io.swagger.annotations.Api;
  18. import io.swagger.annotations.ApiOperation;
  19. import lombok.AllArgsConstructor;
  20. import lombok.extern.slf4j.Slf4j;
  21. import org.springframework.context.annotation.Lazy;
  22. import org.springframework.stereotype.Service;
  23. import org.springframework.web.bind.annotation.PostMapping;
  24. import org.springframework.web.bind.annotation.RequestBody;
  25. import java.math.BigDecimal;
  26. import java.time.LocalDateTime;
  27. import java.util.Arrays;
  28. import java.util.List;
  29. import java.util.Map;
  30. import static com.xy.utils.Beans.copy;
  31. /**
  32. * <p>
  33. * 设备-状态 服务实现类
  34. * </p>
  35. *
  36. * @author lijin
  37. * @since 2022-12-23
  38. */
  39. @Slf4j
  40. @Service
  41. @AllArgsConstructor(onConstructor_ = @Lazy)
  42. @Api(tags = "设备-状态")
  43. public class DeviceStatusServiceImpl extends ServiceImpl<DeviceStatusMapper, DeviceStatus> implements DeviceStatusService {
  44. private DeviceTempRecordsServiceImpl deviceTempRecordsService;
  45. private ActivityInfoService activityInfoService;
  46. private DeviceConfigServiceImpl deviceConfigService;
  47. private DeviceEventMsgService deviceEventMsgService;
  48. private RedisService<Integer> redisService;
  49. private DeviceSysinfoServiceImpl deviceSysinfoService;
  50. private DeviceVersionUpServiceImpl deviceVersionUpService;
  51. private RedisService<DeviceVersionUpServiceImpl.UpInfo> upInfoRedisService;
  52. private MqttServiceImpl mqttService;
  53. @Override
  54. @ApiOperation("上报信息")
  55. public R up(DeviceStatusDto.Up up) {
  56. log.info("设备信息上报:{}", JSONUtil.toJsonStr(up));
  57. ThreadPoolUtils.excPoll(DeviceThreadPoolConfig.DEVICE_STATUS_UP, 4)
  58. .execute(() -> {
  59. //修改状态信息
  60. updateById(copy(DeviceStatus.class, up).setUpdateTime(LocalDateTime.now()));
  61. })
  62. .execute(() -> {
  63. //上报关门
  64. if (!Emptys.check(up.getDoorStateL())) {
  65. return;
  66. }
  67. Integer value = SysDictUtils.getValue(EnumDevcieDoorStatus.Code.CODE.getCode(), EnumDevcieDoorStatus.LOCKED.getCode(), Integer.class);
  68. if (!up.getDoorStateL().equals(value)) {
  69. return;
  70. }
  71. activityInfoService.abort(new ActivityInfoDto.Abort()
  72. .setDeviceId(up.getDeviceId())
  73. .setWorkType(2)
  74. .setTimeout(60 * 1)
  75. );
  76. })
  77. .execute(() -> {
  78. //温度上报
  79. if (!Emptys.check(up.getTempValue())) {
  80. return;
  81. }
  82. DeviceSysinfo deviceSysinfo = deviceSysinfoService.getById(up.getDeviceId());
  83. //添加设备温度日志
  84. if (!deviceSysinfo.getIsHaveTemp()) {
  85. return;
  86. }
  87. DeviceTempRecordsDto.Save save = new DeviceTempRecordsDto.Save()
  88. .setDeviceId(up.getDeviceId());
  89. save.setTempValue(up.getTempValue());
  90. deviceTempRecordsService.save(save);
  91. //查询设备配置
  92. DeviceConfig deviceConfig = deviceConfigService.getById(up.getDeviceId());
  93. int tempMax, tempMin;
  94. if (deviceConfig == null) {
  95. Map<String, SysDictRedis> stringSysDictRedisMap = SysDictUtils.get(EnumDeviceTempConfig.Code.CODE.getCode());
  96. tempMax = Integer.valueOf(stringSysDictRedisMap.get(EnumDeviceTempConfig.MAX.getCode()).getValue());
  97. tempMin = Integer.valueOf(stringSysDictRedisMap.get(EnumDeviceTempConfig.MIN.getCode()).getValue());
  98. } else {
  99. tempMax = deviceConfig.getTempMax();
  100. tempMin = deviceConfig.getTempMin();
  101. }
  102. //温度有异常
  103. String key = String.format("device_temp_error:%d", up.getDeviceId());
  104. if (up.getTempValue() > tempMax || up.getTempValue() < tempMin) {
  105. //校验异常次数
  106. Integer errorSize = SysDictUtils.getValue(EnumDeviceTempConfig.Code.CODE.getCode(), EnumDeviceTempConfig.ERROR_SIZE.getCode(), Integer.class);
  107. Integer maxSize = redisService.get(key);
  108. maxSize = maxSize == null ? 1 : maxSize;
  109. if (maxSize >= errorSize) {
  110. //添加事件
  111. String msg = "温度异常-温度阈值%d - %d,当前温度%d";
  112. DeviceEventMsgDto.Save deviceEventMsg = new DeviceEventMsgDto.Save()
  113. .setDeviceId(up.getDeviceId());
  114. deviceEventMsg.setCode(DeviceErrorRecordTypesEnum.T.getCode());
  115. deviceEventMsg.setMsg(String.format(msg, tempMin, tempMax, up.getTempValue()));
  116. deviceEventMsgService.save(deviceEventMsg);
  117. redisService.remove(key);
  118. return;
  119. }
  120. redisService.set(key, maxSize + 1, 60 * 60);
  121. return;
  122. }
  123. redisService.remove(key);
  124. })
  125. .execute(() -> {
  126. //检查是否可升级
  127. if (!Emptys.check(up.getIsUpVersion()) || !up.getIsUpVersion()) {
  128. return;
  129. }
  130. DeviceVersionUpServiceImpl.UpInfo upInfo = upInfoRedisService.get(DeviceVersionUpServiceImpl.upInfoKey);
  131. if (upInfo == null || !upInfo.getEnable()) {
  132. return;
  133. }
  134. LambdaQueryWrapper<DeviceVersionUp> lambdaQueryWrapper = new LambdaQueryWrapper<DeviceVersionUp>()
  135. .eq(DeviceVersionUp::getDeviceId, up.getDeviceId())
  136. .ge(DeviceVersionUp::getDeviceVersion, upInfo.getVersion())
  137. .and(deviceVersionUpLambdaQueryWrapper -> deviceVersionUpLambdaQueryWrapper
  138. .in(DeviceVersionUp::getStatus, Arrays.asList(2, 4, 5))
  139. .or()
  140. .eq(DeviceVersionUp::getProgress, 100)
  141. );
  142. long count = deviceVersionUpService.count(lambdaQueryWrapper);
  143. if (count > 0) {
  144. return;
  145. }
  146. //下发升级指令
  147. String templetStr = SysDictUtils.getValue(EnumMqttCmdTempletTask.Code.CODE.getCode(), EnumMqttCmdTempletTask.APPUPDATE.getCode(), String.class);
  148. String appId = LambdaUtils.getProperty(DeviceVersionUpServiceImpl.UpInfo::getAppId);
  149. String appKey = LambdaUtils.getProperty(DeviceVersionUpServiceImpl.UpInfo::getAppKey);
  150. String version = LambdaUtils.getProperty(DeviceVersionUpServiceImpl.UpInfo::getVersion);
  151. String src = LambdaUtils.getProperty(DeviceVersionUpServiceImpl.UpInfo::getSrc);
  152. JSONObject templet = JSONUtil.parseObj(templetStr);
  153. JSONObject data = templet.getJSONObject("data")
  154. .set(appId, upInfo.getAppId())
  155. .set(appKey, upInfo.getAppKey())
  156. .set(version, upInfo.getVersion())
  157. .set(src, upInfo.getSrc());
  158. templet.set("data", data);
  159. CommandMqtt commandMqtt = new CommandMqtt()
  160. .setDeviceId(up.getDeviceId())
  161. .setTemplet(templet);
  162. mqttService.senCommand(Arrays.asList(commandMqtt));
  163. });
  164. return R.ok();
  165. }
  166. @Override
  167. @ApiOperation("开关门")
  168. public R door(DeviceStatusDto.Door door) {
  169. DeviceStatus deviceStatus = copy(DeviceStatus.class, door).setUpdateTime(LocalDateTime.now());
  170. updateById(deviceStatus);
  171. return R.ok();
  172. }
  173. /**
  174. * 修改库存
  175. *
  176. * @return
  177. */
  178. public R upStock(long deviceId, int stock) {
  179. DeviceStatus deviceStatusInfo = getById(deviceId);
  180. if (deviceStatusInfo == null) {
  181. return R.ok();
  182. }
  183. new SyncUpdate().update(DeviceStatus.class)
  184. .set(DeviceStatus::getStock, new BigDecimal(stock))
  185. .udateDateTime(DeviceStatus::getUpdateTime)
  186. .eq(DeviceStatus::getDeviceId, deviceId)
  187. .exec();
  188. return R.ok();
  189. }
  190. @Override
  191. @ApiOperation("更新联网状态")
  192. public R updateNetState(DeviceStatusDto.UpdateNetState dto) {
  193. updateById(new DeviceStatus().setDeviceId(dto.getDeviceId()).setNetState(dto.getNetState()));
  194. return R.ok();
  195. }
  196. @PostMapping("obj")
  197. @ApiOperation("对象查询")
  198. public R<DeviceStatusDto.Vo> obj(@RequestBody DeviceStatusDto.Vo vo) {
  199. LambdaQueryWrapper<DeviceStatus> lambdaQueryWrapper = new MybatisPlusQuery().eqWrapper(vo, DeviceStatus.class).build();
  200. List<DeviceStatus> list = list(lambdaQueryWrapper);
  201. if (!Emptys.check(list)) {
  202. return R.ok();
  203. }
  204. return R.ok(copy(DeviceStatusDto.Vo.class, list.get(0)));
  205. }
  206. @PostMapping("list")
  207. @ApiOperation("集合查询")
  208. public R<List<DeviceStatusDto.Vo>> list(@RequestBody DeviceStatusDto.SelectList selectList) {
  209. LambdaQueryWrapper<DeviceStatus> lambdaQueryWrapper = new MybatisPlusQuery().eqWrapper(selectList, DeviceStatus.class)
  210. .in(DeviceStatus::getDeviceId, selectList.getDeviceIds())
  211. .build();
  212. List<DeviceStatus> list = list(lambdaQueryWrapper);
  213. return R.ok(copy(DeviceStatusDto.Vo.class, list));
  214. }
  215. @PostMapping("statusCount")
  216. @ApiOperation("统计状态数量")
  217. public R<DeviceStatusCount> statusCount() {
  218. DeviceStatusCount deviceStatusCount = baseMapper.statusCount();
  219. return R.ok(deviceStatusCount);
  220. }
  221. }