Commit 4d500f0e by 罗志长

Merge branch 'dev'

parents aed900b0 8d009a5a
Showing with 1345 additions and 222 deletions
ALTER TABLE `plat_device_other`
ALTER TABLE `plat_device_other`
......@@ -85,3 +85,9 @@ CREATE TABLE `saas_pid_manage` (
ALTER TABLE `plat_alarm_record`
ADD COLUMN `wechat_read_flag` char(1) DEFAULT 0 COMMENT '小程序端是否读取 0未读 1已读' AFTER `misinformation_flag`;
-- 12.15 end
ALTER TABLE `plat_tenant`
ADD COLUMN `open_api_url` varchar(128) COMMENT '第三方接口url' AFTER `secret`;
\ No newline at end of file
......@@ -65,4 +65,6 @@ public class PlatTenantDTOVO extends BaseIdDTO {
private String appid;
@ApiModelProperty(value = "secret")
private String secret;
@ApiModelProperty(value = "openApiUrl")
private String openApiUrl;
}
......@@ -35,6 +35,8 @@ public class PlatTenantVO extends BaseIdDTO implements Serializable {
@ApiModelProperty(value = "租户管理员用户名")
private String userName;
@ApiModelProperty(value = "openApiUrl")
private String openApiUrl;
/**
* 创建时间
......
......@@ -10,10 +10,8 @@ import com.makeit.module.iot.dto.IotQueryParam;
import com.makeit.module.iot.dto.IotSort;
import com.makeit.module.iot.dto.Term;
import com.makeit.module.iot.util.HttpRequest;
import com.makeit.module.iot.vo.DeviceInstanceEntity;
import com.makeit.module.iot.vo.DeviceOperationLogEntity;
import com.makeit.module.iot.vo.IotPagerResult;
import com.makeit.module.iot.vo.ResponseMessage;
import com.makeit.module.iot.util.SimpleHttpRequest;
import com.makeit.module.iot.vo.*;
import com.makeit.module.iot.vo.analysis.AnalysisVO;
import com.makeit.module.iot.vo.breathe.DeviceInfoContentBreathe;
import com.makeit.module.iot.vo.fall.DeviceInfoContentFall;
......@@ -33,10 +31,7 @@ import java.io.IOException;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.*;
import java.util.stream.Collectors;
/**
......@@ -78,18 +73,36 @@ public class IotProductDeviceService extends IotCommonService {
return Lists.newArrayList();
}
public DeviceDetail getDetail(String deviceId) {
String url = iotUrl + DEVICE_PREFIX_URL + "/" + deviceId + "/detail";
HttpRequest request = new SimpleHttpRequest(url, httpClient);
request.headers(headerUtils.createHeadersOfParams(new HashMap<>()));
try {
ResponseMessage responseMessage = sendGet(url, request);
if (responseMessage.getStatus() == 200) {
log.info("获取设备详情成功:{}", deviceId);
return JSON.parseObject(responseMessage.getResult().toString(), DeviceDetail.class);
} else {
log.error("获取设备详情失败:{}", responseMessage.getMessage());
}
} catch (IOException e) {
log.error("调用:{}接口异常:{}", url, e.getMessage());
}
return null;
}
@Async
public void syncUpdateDeviceInfo(String id, String name, String productId) {
public void syncUpdateDeviceInfo(String id, String name, String productId, String describe) {
String url = iotUrl + "/device-instance";
Map<String,Object> reqMap = Maps.newHashMap();
reqMap.put("id",id);
reqMap.put("name",name);
reqMap.put("productId",productId);
reqMap.put("id", id);
reqMap.put("name", name);
reqMap.put("productId", productId);
reqMap.put("describe", describe);
String body = JsonUtil.toJson(reqMap);
HttpRequest request = buildRequest(url, body);
request.encode("UTF-8");
request.contentType("application/json");
try {
ResponseMessage responseMessage = sendPatch(url, request);
if (responseMessage.getStatus() == 200) {
......
......@@ -106,7 +106,7 @@ public class SimpleHttpRequest implements HttpRequest {
public Response patch() throws IOException {
HttpPatch delete = new HttpPatch(url);
if (requestBody != null)
delete.setEntity(new StringEntity(requestBody, ContentType.create(contentType)));
delete.setEntity(new StringEntity(requestBody, ContentType.create(contentType, encode)));
else {
delete.setEntity(createUrlEncodedFormEntity());
}
......
package com.makeit.module.iot.vo;
import lombok.Data;
@Data
public class DeviceDetail {
// 固件信息
private DeviceFirmwareInfo firmwareInfo;
// 上线时间
private long onlineTime;
//说明
private String description;
}
package com.makeit.module.iot.vo;
import lombok.Data;
import java.util.Map;
@Data
public class DeviceFirmwareInfo {
// 固件版本
private String version;
// 创建时间(只读)
private Long createTime;
// 修改时间
private Long updateTime;
// 其他配置
private Map<String, Object> properties;
}
......@@ -12,10 +12,13 @@ public class DiseaseReportVO {
private String score;
private String evaluate;
@Data
public static class Condition {
// 条件直接的关联关系、and or
private String resultRelational;
/**
* 0:正常 1:呼吸暂停 2:呼吸过速 3:呼吸过缓 4:心率过速 5:心率过缓
*/
private String resultCondition;
}
}
package com.makeit.utils.redis;
import cn.hutool.core.collection.CollUtil;
import com.makeit.utils.ThreadUtil;
import com.makeit.utils.data.convert.JsonUtil;
import com.makeit.utils.old.StringUtils;
......@@ -193,6 +194,21 @@ public class RedisUtil {
return bucket.get();
}
/**
* 获取字符串
*/
public static <T> List<T> getLike(String key) {
RKeys keys = client.getKeys();
Iterable<String> keyList = keys.getKeysByPattern(getProjectName() + key + "*");
RBatch rBatch = client.createBatch();
if(CollUtil.isNotEmpty(keyList)){
keyList.forEach(k-> rBatch.getBucket(k).getAsync());
}
List<?> dbList = rBatch.execute().getResponses();
return dbList.stream().map(e -> (T) e).collect(Collectors.toList());
}
public static <T> List<T> get(List<String> key) {
RBatch rBatch = client.createBatch();
......
......@@ -51,7 +51,7 @@ public class PlatDeviceController {
@ApiOperation("分页列表")
@PostMapping("page")
public ApiResponseEntity<PageVO<PlatDeviceListVO>> page(@RequestBody PageReqDTO<PlatDeviceQueryDTO> pageReqDTO) {
return ApiResponseUtils.success(platDeviceService.page(pageReqDTO));
return ApiResponseUtils.success(platDeviceService.platPage(pageReqDTO));
}
@ApiOperation("编辑")
......
package com.makeit.module.controller.elder;
import com.alibaba.fastjson.JSONObject;
import com.makeit.common.response.ApiResponseEntity;
import com.makeit.common.response.ApiResponseUtils;
import com.makeit.dto.wechat.device.PlatDeviceAttrWechatDTO;
import com.makeit.entity.platform.elder.PlatElderBreatheAnalysis;
import com.makeit.external.huineng.HuiNengService;
import com.makeit.global.annotation.AuthIgnore;
import com.makeit.global.aspect.tenant.TenantIdIgnore;
import com.makeit.service.platform.device.PlatDeviceService;
import com.makeit.service.platform.elder.*;
import com.makeit.task.PlatElderReportTask;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* <p>
......@@ -42,6 +43,8 @@ public class PlatElderSleepController {
private PlatElderBreatheAnalysisService platElderBreatheAnalysisService;
@Autowired
private PlatElderCoordinateRecordService platElderCoordinateRecordService;
@Autowired
private HuiNengService huiNengService;
......@@ -63,11 +66,11 @@ public class PlatElderSleepController {
}
@ApiOperation("测试")
@PostMapping("test3")
@GetMapping("test3")
@AuthIgnore
public ApiResponseEntity<Void> elderHeartRespiratoryAnalysisTask() {
platElderBreatheAnalysisService.elderHeartRespiratoryAnalysisTask();
return ApiResponseUtils.success();
public ApiResponseEntity<List<PlatElderBreatheAnalysis>> elderHeartRespiratoryAnalysisTask(@RequestParam Integer month,
@RequestParam Integer day) {
return ApiResponseUtils.success(platElderBreatheAnalysisService.elderHeartRespiratoryAnalysisTask(month, day));
}
@ApiOperation("测试")
......@@ -103,5 +106,34 @@ public class PlatElderSleepController {
return ApiResponseUtils.success(platDeviceService.readDeviceProperties(dto));
}
@ApiOperation("读设备属性")
@PostMapping("healthReport")
@AuthIgnore
@TenantIdIgnore
public ApiResponseEntity<?> healthReport() {
JSONObject jsonObject = new JSONObject();
jsonObject.put("hr","80");
jsonObject.put("br","30");
jsonObject.put("person","1");
jsonObject.put("personState","2");
jsonObject.put("distance","100");
jsonObject.put("bodymove","30");
huiNengService.healthReport("1712384736845950978","1712376790484275200",jsonObject);
return ApiResponseUtils.success();
}
@ApiOperation("读设备属性")
@PostMapping("bodyAlarm")
@AuthIgnore
@TenantIdIgnore
public ApiResponseEntity<?> bodyAlarm() {
JSONObject jsonObject = new JSONObject();
jsonObject.put("person","1");
jsonObject.put("personState","1");
huiNengService.bodyAlarm("1712384736845950978","219A04X1856F6D8",jsonObject);
return ApiResponseUtils.success();
}
}
......@@ -123,4 +123,11 @@ public class PlatSpaceController {
return ApiResponseUtils.success(data);
}
@ApiOperation("修复空间层级数据")
@GetMapping("fixPlacePath")
public ApiResponseEntity<String> fixPlacePath(@RequestParam String spaceId) {
spaceService.fixPlacePath(spaceId);
return ApiResponseUtils.success();
}
}
......@@ -38,6 +38,7 @@ public class PlatAlarmRecordWechatController {
public ApiResponseEntity<Map<String,Object>> page(@RequestBody PageReqDTO<PlatAlarmRecordQueryDTO> dto) {
//小程序告警记录只看到发给自己的告警
String userId = CommonUserUtil.getUserId();
// String userId = "1700085146788667394";
PlatAlarmRecordQueryDTO data = dto.getData();
data.setNotifyUser(userId);
......
......@@ -30,6 +30,7 @@ public class PlatDeviceEditDTO extends BaseTenantDTO {
@ApiModelProperty(value = "设备属性json")
private String attribute;
@ApiModelProperty(value = "描述")
private String description;
}
......@@ -42,5 +42,7 @@ public class PlatElderBreatheAnalysis extends BaseBusEntity {
@ApiModelProperty(value = "当前日期 yyyy-mm-dd")
private String happenDate;
// @TableField(exist = false)
// private String remake;
}
......@@ -65,6 +65,8 @@ public class PlatTenant extends BaseEntity {
private String url;
private String appid;
private String secret;
private String openApiUrl;
}
\ No newline at end of file
package com.makeit.enums.report;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author wangzy
*/
@AllArgsConstructor
@Getter
public enum ConditionTypeEnum {
/**
* 0:正常 1:呼吸暂停 2:呼吸过速 3:呼吸过缓 4:心率过速 5:心率过缓
*/
NORMAL("0", "正常"),
BREATHE_STOP("1", "呼吸暂停"),
BREATHE_FAST("2", "呼吸过速"),
BREATHE_SLOW("3", "呼吸过缓"),
HEART_FAST("4", "心率过速"),
HEART_SLOW("5", "心率过缓");
private final String code;
private final String value;
}
package com.makeit.external;
public enum TenantLogoEnum {
HNGZ("汇能感知","hngz");
private String tenantName;
private String value;
public String getTenantName() {
return tenantName;
}
public String getValue() {
return value;
}
TenantLogoEnum(String tenantName, String value) {
this.tenantName = tenantName;
this.value = value;
}
}
package com.makeit.external.huineng;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.makeit.common.entity.BaseBusEntity;
import com.makeit.entity.platform.device.PlatDevice;
import com.makeit.entity.saas.PlatTenant;
import com.makeit.global.aspect.tenant.TenantIdIgnore;
import com.makeit.service.platform.device.PlatDeviceService;
import com.makeit.service.saas.PlatTenantService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
@Component
@Slf4j
public class HuiNengService {
@Autowired
private PlatTenantService platTenantService;
@Autowired
private PlatDeviceService platDeviceService;
@TenantIdIgnore
public void healthReport(String tenantId, String deviceId, JSONObject jsonObject) {
PlatTenant platTenant = platTenantService.getById(tenantId);
if (platTenant == null) {
return;
}
PlatDevice platDevice = platDeviceService.getOne(new QueryWrapper<PlatDevice>().lambda()
.eq(PlatDevice::getOriDeviceId, deviceId)
.eq(BaseBusEntity::getTenantId, tenantId));
if (platDevice == null) {
return;
}
HuinengHealthReportDTO dto = new HuinengHealthReportDTO();
dto.setId(platDevice.getOriDeviceId());
dto.setDeviceType("健康监测设备");
dto.setDtype("实时上报");
dto.setUid(platDevice.getOriDeviceId());
dto.setPk("");
dto.setDid(platDevice.getOriDeviceId());
dto.setSite("");
dto.setLatitude("");
dto.setLongitude("");
dto.setTimestamp(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now()));
dto.setCompanyName(platTenant.getName());
List<HuinengHealthReportDTO.ReportInfo> data = Lists.newArrayList();
HuinengHealthReportDTO.ReportInfo reportInfo = new HuinengHealthReportDTO.ReportInfo();
reportInfo.setECG("");
reportInfo.setBloodSugar("");
reportInfo.setBloodOxygen("");
reportInfo.setBloodPressure("");
reportInfo.setTemperature("");
reportInfo.setSleepQuality("");
reportInfo.setMedicationStatus("");
reportInfo.setAlarmReason("");
reportInfo.setAlarmType("");
reportInfo.setAlarmTime("");
reportInfo.setEventName("设备上报");
reportInfo.setEventType("1");
reportInfo.setHeartRate(jsonObject.getString("hr"));
reportInfo.setInBedState(jsonObject.getString("person"));
reportInfo.setRespiratoryRate(jsonObject.getString("br"));
String bodymove = jsonObject.getString("bodymove");
reportInfo.setTurn(bodymove);
reportInfo.setTurnState(bodymove.equals("0") ? "0" : "1");
data.add(reportInfo);
dto.setData(data);
String reqJson = JSONUtil.toJsonStr(dto);
String url = platTenant.getOpenApiUrl() + "/admin-api/v1/HealthMonitoringEquipment/TimingdataPush?token=aHVpbmVuZ2dhbnpoaV9wdXNoc2V0";
log.info("请求url:{},参数:{}",url,reqJson);
String result = HttpUtil.createPost(url)
.body(reqJson,"application/json")
.execute().body();
HuinengResultVO responseMessage = JSON.parseObject(result, HuinengResultVO.class);
log.info("接口:{},返回信息:{}", url, JSON.toJSONString(responseMessage));
}
@TenantIdIgnore
public void bodyAlarm(String tenantId, String deviceId, JSONObject jsonObject) {
PlatTenant platTenant = platTenantService.getById(tenantId);
if (platTenant == null) {
return;
}
PlatDevice platDevice = platDeviceService.getOne(new QueryWrapper<PlatDevice>().lambda()
.eq(PlatDevice::getOriDeviceId, deviceId)
.eq(BaseBusEntity::getTenantId, tenantId));
if (platDevice == null) {
return;
}
HuinengBodyReportDTO dto = new HuinengBodyReportDTO();
dto.setId(platDevice.getOriDeviceId());
dto.setDeviceType("人体感应探测器\"");
dto.setDtype("报警上报");
dto.setUid(platDevice.getOriDeviceId());
dto.setPk("");
dto.setDid(platDevice.getOriDeviceId());
dto.setSite("");
dto.setLatitude("");
dto.setLongitude("");
String currentDate = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now());
dto.setTimestamp(currentDate);
dto.setCompanyName(platTenant.getName());
List<HuinengBodyReportDTO.AlarmInfo> data = Lists.newArrayList();
HuinengBodyReportDTO.AlarmInfo alarmInfo = new HuinengBodyReportDTO.AlarmInfo();
alarmInfo.setQuantityElectricity("");
alarmInfo.setSignalStrength("");
alarmInfo.setPerson(jsonObject.getString("person"));
alarmInfo.setAlarmReason("跌倒触发报警");
alarmInfo.setAlarmType("3");
alarmInfo.setAlarmTime(currentDate);
alarmInfo.setEventName("设备告警");
alarmInfo.setEventType("1");
data.add(alarmInfo);
dto.setData(data);
String reqJson = JSON.toJSONString(dto);
String url = platTenant.getOpenApiUrl() + "/admin-api/v1/HumanBodyInductionDetector/TimingdataPush?token=aHVpbmVuZ2dhbnpoaV9wdXNoc2V0";
log.info("请求url:{},参数:{}",url,reqJson);
String result = HttpUtil.createPost(url)
.body(JSON.toJSONString(dto),"application/json")
.execute().body();
HuinengResultVO responseMessage = JSON.parseObject(result, HuinengResultVO.class);
log.info("接口:{},返回信息:{}", url, JSON.toJSONString(responseMessage));
}
}
package com.makeit.external.huineng;
import lombok.Data;
import java.util.List;
/**
* 人体感应探测器数据接口
*/
@Data
public class HuinengBodyReportDTO {
private String id;
private String pk;
private String did;
private String deviceType;
private String deviceModel;
private String uid;
private String dtype;
private String site;
private String longitude;
private String latitude;
private String companyName;
private String timestamp;
private List<AlarmInfo> data;
@Data
public static class AlarmInfo {
private String signalStrength;
private String quantityElectricity;
private String person;
private String alarmReason;
private String alarmType;
private String eventName;
private String eventType;
private String alarmTime;
}
}
package com.makeit.external.huineng;
import lombok.Data;
import java.util.List;
/**
* 健康监测设备
*/
@Data
public class HuinengHealthReportDTO {
private String id;
private String pk;
private String did;
private String deviceType;
private String deviceModel;
private String uid;
private String dtype;
private String site;
private String longitude;
private String latitude;
private String companyName;
private String timestamp;
private List<ReportInfo> data;
@Data
public static class ReportInfo {
private String signalStrength;
private String quantityElectricity;
private String ECG;
private String bloodPressure;
private String bloodSugar;
private String bloodOxygen;
private String temperature;
private String heartRate;
private String inBedState;
private String respiratoryRate;
private String turn;
private String turnState;
private String sleepQuality;
private String medicationStatus;
private String alarmReason;
private String alarmType;
private String eventName;
private String eventType;
private String alarmTime;
}
}
package com.makeit.external.huineng;
import lombok.Data;
@Data
public class HuinengResultVO {
private Integer code;
private String msg;
private boolean data;
}
package com.makeit.external.strategy;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.makeit.common.entity.BaseBusEntity;
import com.makeit.entity.platform.device.PlatDevice;
import com.makeit.entity.saas.PlatTenant;
import com.makeit.external.TenantLogoEnum;
import com.makeit.external.huineng.HuinengBodyReportDTO;
import com.makeit.external.huineng.HuinengHealthReportDTO;
import com.makeit.external.huineng.HuinengResultVO;
import com.makeit.global.aspect.tenant.TenantIdIgnore;
import com.makeit.service.platform.device.PlatDeviceService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
@Service
@Slf4j
public class HuiNengStrategy implements OpenApiBaseStrategy {
@Autowired
private PlatDeviceService platDeviceService;
@Override
@TenantIdIgnore
public void report(PlatTenant platTenant, String deviceId, JSONObject jsonObject) {
log.info("{},开始执行上报",platTenant.getName());
PlatDevice platDevice = platDeviceService.getOne(new QueryWrapper<PlatDevice>().lambda()
.eq(PlatDevice::getOriDeviceId, deviceId)
.eq(BaseBusEntity::getTenantId, platTenant.getId()));
if (platDevice == null) {
return;
}
if (StringUtils.isEmpty(platTenant.getUrl())) {
log.info("当前租户为配置openapi地址");
return;
}
HuinengHealthReportDTO dto = new HuinengHealthReportDTO();
dto.setId(platDevice.getOriDeviceId());
dto.setDeviceType("健康监测设备");
dto.setDeviceModel(platDevice.getProductId());
dto.setDtype("实时上报");
dto.setUid("");
dto.setPk(platDevice.getProductId());
dto.setDid(platDevice.getOriDeviceId());
dto.setSite("");
dto.setLatitude("");
dto.setLongitude("");
dto.setTimestamp(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now()));
dto.setCompanyName(platTenant.getName());
List<HuinengHealthReportDTO.ReportInfo> data = Lists.newArrayList();
HuinengHealthReportDTO.ReportInfo reportInfo = new HuinengHealthReportDTO.ReportInfo();
reportInfo.setECG("");
reportInfo.setBloodSugar("");
reportInfo.setBloodOxygen("");
reportInfo.setBloodPressure("");
reportInfo.setTemperature("");
reportInfo.setSleepQuality("");
reportInfo.setMedicationStatus("");
reportInfo.setAlarmReason("");
reportInfo.setAlarmType("1");
reportInfo.setAlarmTime("");
reportInfo.setEventName("设备上报");
reportInfo.setEventType("1");
reportInfo.setHeartRate(jsonObject.getString("hr"));
reportInfo.setInBedState(jsonObject.getString("person"));
reportInfo.setRespiratoryRate(jsonObject.getString("br"));
String bodymove = jsonObject.getString("bodymove");
reportInfo.setTurn(bodymove);
reportInfo.setTurnState(bodymove.equals("0") ? "0" : "1");
data.add(reportInfo);
dto.setData(data);
String reqJson = JSON.toJSONString(dto);
String url = platTenant.getOpenApiUrl() + "/admin-api/v1/HealthMonitoringEquipment/TimingdataPush?token=aHVpbmVuZ2dhbnpoaV9wdXNoc2V0";
log.info("请求url:{},参数:{}", url, reqJson);
String result = HttpUtil.createPost(url)
.body(reqJson, "application/json")
.execute().body();
HuinengResultVO responseMessage = JSON.parseObject(result, HuinengResultVO.class);
log.info("接口:{},返回信息:{}", url, JSON.toJSONString(responseMessage));
}
@Override
@TenantIdIgnore
public void alarm(PlatTenant platTenant, String deviceId, JSONObject jsonObject) {
log.info("{},开始执行告警",platTenant.getName());
PlatDevice platDevice = platDeviceService.getOne(new QueryWrapper<PlatDevice>().lambda()
.eq(PlatDevice::getOriDeviceId, deviceId)
.eq(BaseBusEntity::getTenantId, platTenant.getId()));
if (platDevice == null) {
return;
}
if (StringUtils.isEmpty(platTenant.getUrl())) {
log.info("当前租户为配置openapi地址");
return;
}
HuinengBodyReportDTO dto = new HuinengBodyReportDTO();
dto.setId(platDevice.getOriDeviceId());
dto.setDeviceType("人体感应探测器");
dto.setDtype("报警上报");
dto.setUid("");
dto.setPk(platDevice.getProductId());
dto.setDeviceModel(platDevice.getProductId());
dto.setDid(platDevice.getOriDeviceId());
dto.setSite("");
dto.setLatitude("");
dto.setLongitude("");
String currentDate = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now());
dto.setTimestamp(currentDate);
dto.setCompanyName(platTenant.getName());
List<HuinengBodyReportDTO.AlarmInfo> data = Lists.newArrayList();
HuinengBodyReportDTO.AlarmInfo alarmInfo = new HuinengBodyReportDTO.AlarmInfo();
alarmInfo.setQuantityElectricity("");
alarmInfo.setSignalStrength("");
alarmInfo.setPerson(jsonObject.getString("person"));
alarmInfo.setAlarmReason("跌倒触发报警");
alarmInfo.setAlarmType("4");
alarmInfo.setAlarmTime(currentDate);
alarmInfo.setEventName("设备告警");
alarmInfo.setEventType("1");
data.add(alarmInfo);
dto.setData(data);
String reqJson = JSON.toJSONString(dto);
String url = platTenant.getOpenApiUrl() + "/admin-api/v1/HumanBodyInductionDetector/TimingdataPush?token=aHVpbmVuZ2dhbnpoaV9wdXNoc2V0";
log.info("请求url:{},参数:{}", url, reqJson);
String result = HttpUtil.createPost(url)
.body(JSON.toJSONString(dto), "application/json")
.execute().body();
HuinengResultVO responseMessage = JSON.parseObject(result, HuinengResultVO.class);
log.info("接口:{},返回信息:{}", url, JSON.toJSONString(responseMessage));
}
@Override
public String getTenantLogo() {
return TenantLogoEnum.HNGZ.getValue();
}
}
package com.makeit.external.strategy;
import com.alibaba.fastjson.JSONObject;
import com.makeit.entity.saas.PlatTenant;
public interface OpenApiBaseStrategy {
void report(PlatTenant platTenant, String deviceId, JSONObject jsonObject);
void alarm(PlatTenant platTenant, String deviceId, JSONObject jsonObject);
String getTenantLogo();
}
package com.makeit.external.strategy;
import com.google.common.collect.Maps;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
public class OpenApiBaseStrategyFactory implements InitializingBean, ApplicationContextAware {
private static final Map<String, OpenApiBaseStrategy> HANDLER_MAP = Maps.newConcurrentMap();
private ApplicationContext appContext;
public OpenApiBaseStrategy getHandler(String logo) {
return HANDLER_MAP.get(logo);
}
@Override
public void afterPropertiesSet() {
appContext.getBeansOfType(OpenApiBaseStrategy.class)
.values()
.forEach(handler -> HANDLER_MAP.put(handler.getTenantLogo(), handler));
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
appContext = applicationContext;
}
}
......@@ -21,4 +21,5 @@ public interface PlatAlarmConfigMapper extends BaseMapper<PlatAlarmConfig> {
* @return
*/
List<PlatHealthConfigDTO> getHealthConfigList();
}
......@@ -21,5 +21,7 @@ public interface PlatDeviceMapper extends BaseMapper<PlatDevice> {
Page<PlatDeviceListVO> getDeviceIdsBySpaceId(@Param("param")PlatDeviceQueryDTO param, Page page);
Page<PlatDeviceListVO> getDeviceIdsBySpaceIdAndElder(@Param("param")PlatDeviceQueryDTO param, Page page);
Page<PlatDeviceListVO> getDevices(@Param("param")PlatDataScreenQueryDTO param, Page<PlatDevice> page);
}
......@@ -42,4 +42,6 @@ public interface PlatAlarmConfigService extends IService<PlatAlarmConfig> {
List<PlatHealthConfigDTO> getHealthConfigList();
void initData();
List<PlatAlarmConfig> listOfBed(List<String> orgIds);
}
......@@ -11,11 +11,15 @@ import com.makeit.entity.platform.alarm.PlatDayDurationRecord;
import com.makeit.entity.platform.device.PlatDevice;
import com.makeit.entity.platform.elder.PlatElder;
import com.makeit.entity.platform.space.PlatRoom;
import com.makeit.entity.saas.PlatTenant;
import com.makeit.enums.CommonEnum;
import com.makeit.enums.platform.alarm.PlatAlarmConfigEnum;
import com.makeit.enums.redis.RedisConst;
import com.makeit.external.strategy.OpenApiBaseStrategy;
import com.makeit.external.strategy.OpenApiBaseStrategyFactory;
import com.makeit.service.platform.alarm.PlatAlarmRecordService;
import com.makeit.service.platform.alarm.PlatDayDurationRecordService;
import com.makeit.service.saas.PlatTenantService;
import com.makeit.utils.AlarmConfigCacheUtil;
import com.makeit.utils.AlarmRedisDTO;
import com.makeit.utils.DayDurationUtil;
......@@ -47,7 +51,10 @@ public class FallAlarm implements IAlarm {
@Autowired
private DayDurationUtil dayDurationUtil;
@Autowired
private OpenApiBaseStrategyFactory openApiBaseStrategyFactory;
@Autowired
private PlatTenantService platTenantService;
private final PlatAlarmConfigEnum.AlarmTypeEnum alarmTypeEnum = PlatAlarmConfigEnum.AlarmTypeEnum.FALL;
@Override
......@@ -90,6 +97,21 @@ public class FallAlarm implements IAlarm {
alarmRedisDTO.setAlarm(CommonEnum.YES.getValue());
RedisUtil.set(RedisConst.ALARM_DEVICE_FALL_ID + deviceId, alarmRedisDTO);
notice(platAlarmCheckDTO);
// 跌倒了设备需要发送告警到第三方平台
PlatTenant platTenant = platTenantService.getById(platDevice.getTenantId());
if (platTenant != null) {
OpenApiBaseStrategy strategyFactoryHandler = openApiBaseStrategyFactory.getHandler(platTenant.getCode());
if (strategyFactoryHandler != null) {
try {
strategyFactoryHandler.alarm(platTenant, platDevice.getOriDeviceId(), properties);
} catch (Exception e) {
log.error("调用openapi告警接口失败:{}", e.getMessage(), e);
}
}
}
} else {
if (StringUtils.equals(alarmRedisDTO.getAlarm(), CommonEnum.YES.getValue())) {
alarmRedisDTO.setAlarm(CommonEnum.NO.getValue());
......
package com.makeit.service.platform.alarm.alarmStrategy;
import cn.hutool.core.convert.Convert;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.makeit.dto.platform.alarm.PlatAlarmCheckDTO;
import com.makeit.dto.platform.alarm.PlatAlarmConfigOffBedDTOVO;
......@@ -23,8 +22,6 @@ import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.*;
import java.util.ArrayList;
import java.util.Date;
......@@ -61,27 +58,31 @@ public class OffBedAlarm implements IAlarm {
return;
}
PlatAlarmConfig config = alarmConfigCacheUtil.get(platDevice.getOrgId(), PlatAlarmConfigEnum.AlarmTypeEnum.OFF_BED.getValue());
log.info("离床预警配置:{},orgid:{}", JSONUtil.toJsonStr(config), platDevice.getOrgId());
offBedCheckAlarm(config, platAlarmCheckDTO, platDevice);
}
private void offBedCheckAlarm(PlatAlarmConfig config, PlatAlarmCheckDTO platAlarmCheckDTO, PlatDevice platDevice) {
if (config == null || StringUtils.isBlank(config.getRuleConfig()) || !"5".equals(config.getAlarmType())) {
log.error("离床告警配置不存在,config:{}", JSONUtil.toJsonStr(config));
// log.error("离床告警配置不存在,config:{}", JSONUtil.toJsonStr(config));
return;
}
if (CommonEnum.NO.getValue().equals(config.getStatus())) {
log.error("离床告警配置为禁用,告警配置id:" + config.getId());
// log.error("离床告警配置为禁用,告警配置id:" + config.getId());
return;
}
String ruleConfigStr = config.getRuleConfig();
if (StringUtils.isBlank(ruleConfigStr)) {
log.error("离床告警配置未配置,告警配置id:" + config.getId());
// log.error("离床告警配置未配置,告警配置id:" + config.getId());
return;
}
PlatAlarmConfigOffBedDTOVO ruleConfig = JsonUtil.toObj(ruleConfigStr, PlatAlarmConfigOffBedDTOVO.class);
if (ruleConfig == null) {
log.error("离床告警配置解析失败,config:{}", JSONUtil.toJsonStr(config));
// log.error("离床告警配置解析失败,config:{}", JSONUtil.toJsonStr(config));
return;
}
if (ruleConfig.getOffBedStart() == null || ruleConfig.getOffBedEnd() == null) {
log.error("离床告警配置时间不能为空,config:{}", JSONUtil.toJsonStr(config));
// log.error("离床告警配置时间不能为空,config:{}", JSONUtil.toJsonStr(config));
return;
}
JSONObject properties = platAlarmCheckDTO.getProperties();
......@@ -91,187 +92,205 @@ public class OffBedAlarm implements IAlarm {
String deviceId = platDevice.getId();
LocalTime startTime = ruleConfig.getOffBedStart();
LocalTime endTime = ruleConfig.getOffBedEnd();
if (startTime == null || endTime == null) {
log.error("离床告警配置时间段解析失败,config:{}", JSONUtil.toJsonStr(ruleConfig));
if (startTime == null || endTime == null || startTime.equals(endTime)) {
// log.error("离床告警配置时间段解析失败,config:{}", JSONUtil.toJsonStr(ruleConfig));
return;
}
log.info("离床预警时间范围,begin:{},end:{}", startTime, endTime);
// 00:00 -> 23:59:59999
if (endTime.getHour() == 0 && endTime.getMinute() == 0) {
ruleConfig.setOffBedEnd(LocalTime.MAX);
}
String personState = Convert.toStr(properties.get("person"));
boolean isOffBed = "0".equals(personState);
// 1-有人 0-无人
log.info("离床告警config:{}", JSONUtil.toJsonStr(properties));
AlarmRedisDTO alarmRedisDTO = RedisUtil.get(RedisConst.ALARM_DEVICE_OFF_BED_ID + deviceId);
if (!isOffBed && alarmRedisDTO != null) {
log.info("离床告警有人状态下,删除redis!");
if ("1".equals(personState)) {
log.info("deviceId:{},离床告警有人状态下,删除redis", deviceId);
RedisUtil.delete(RedisConst.ALARM_DEVICE_OFF_BED_ID + deviceId);
return;
}
// 设备无人,在范围内上报存储redis,超过离床持续时间,则预警
String messageType = platAlarmCheckDTO.getMessageType();
if (StringUtils.equalsAnyIgnoreCase(messageType, "OFFLINE", "DISCONNECT")) {
log.info("离床告警设备下线,删除redis off_bed 预警");
log.info("deviceId:{},离床告警设备下线,删除redis off_bed 预警", deviceId);
RedisUtil.delete(RedisConst.ALARM_DEVICE_OFF_BED_ID + deviceId);
}
if (isOffBed) {
// 离床推送redis
sendToRedis(alarmRedisDTO, deviceId);
if (sendToRedis(alarmRedisDTO, deviceId)) {
//第一次离床
return;
}
alarmRedisDTO = RedisUtil.get(RedisConst.ALARM_DEVICE_OFF_BED_ID + deviceId);
Long firstOffBedLong = alarmRedisDTO.getStartLong();
LocalDateTime firstOffBedTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(firstOffBedLong), ZoneOffset.of("+8"));
log.info("离床告警第一次离床时间为:" + firstOffBedTime);
if ("1".equals(alarmRedisDTO.getAlarm())) {
log.info("离床告警已发送预警过!");
log.info("deviceId:{},离床告警已发送预警过,第一次离床时间:{}", deviceId, longToTime(alarmRedisDTO.getStartLong()));
return;
}
// 是否跨天
boolean isCrossDay = startTime.isAfter(endTime);
// 是否跨天 xxx-0:00,未跨天
boolean isCrossDay = startTime.isAfter(endTime) && !endTime.equals(LocalTime.MIN);
if (isCrossDay) {
log.info("离床预警跨天处理:config:{}", config.getRuleConfig());
handleCrossDay(alarmRedisDTO, ruleConfig, platAlarmCheckDTO, config, deviceId);
} else {
log.info("离床预警未跨天处理:config:{}", config.getRuleConfig());
handleUnCrossDay(alarmRedisDTO, ruleConfig, platAlarmCheckDTO, config, deviceId);
}
}
}
/**
* 处理跨天业务
*
* @param alarmRedisDTO
* @param ruleConfig
* @param platAlarmCheckDTO
* @param config
* @param deviceId
*/
private void handleCrossDay(AlarmRedisDTO alarmRedisDTO, PlatAlarmConfigOffBedDTOVO ruleConfig,
PlatAlarmCheckDTO platAlarmCheckDTO,
PlatAlarmConfig config,
String deviceId) {
log.info("deviceId:{},cross_config:{},第一次离床时间:{}", deviceId, config.getRuleConfig(), longToTime(alarmRedisDTO.getStartLong()));
Integer duration = ruleConfig.getDuration();
LocalTime startTime = ruleConfig.getOffBedStart();
LocalTime endTime = ruleConfig.getOffBedEnd();
Long firstOffBedLong = alarmRedisDTO.getStartLong();
long currentTimeMillis = System.currentTimeMillis();
long currentTimeMillis = currentLong();
boolean isOverTime = (currentTimeMillis - firstOffBedLong) / 1000 >= duration * 60;
LocalDateTime firstOffBedTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(firstOffBedLong), ZoneOffset.of("+8"));
LocalTime firstTime = firstOffBedTime.toLocalTime();
LocalTime firstTime = longToTime(firstOffBedLong).toLocalTime();
boolean isInTime = firstTime.isAfter(startTime) || firstTime.isBefore(endTime);
LocalTime endTimeLimit = endTime.plusMinutes(-duration);
// 离床时间在范围内
if (isInTime && isOverTime) {
if (firstTime.isAfter(endTimeLimit)) {
log.info("handleCrossDay 第一次离床时间,{}+持续时间:{}将超过范围,{}", firstTime, duration, endTime);
// 离床时间为23:00-1:00 持续时间5分钟 ,第一次离床为0:55,满足条件的时间>1:00,不预警
if (firstTime.isAfter(endTimeLimit) && firstTime.isBefore(endTime)) {
log.info("deviceId:{},UnCrossDay第一次离床时间,{}+持续时间:{}将超过范围,{}", deviceId, firstTime, duration, endTime);
return;
}
platAlarmCheckDTO.setAbnormalValue(String.valueOf(currentTimeMillis - firstOffBedLong));
log.info("deviceId:{},cross离床告警离床时间在范围时间内,配置:{}", deviceId, config.getRuleConfig());
platAlarmCheckDTO.setPlatAlarmConfig(config);
log.info("cross离床告警离床时间在范围时间内,配置:{}", config.getRuleConfig());
// platAlarmCheckDTO.setAlarmRecordId(IdWorker.getIdStr(PlatAlarmRecord.class));
noticeAlarm(alarmRedisDTO, platAlarmCheckDTO, deviceId);
return;
}
LocalDateTime now = LocalDateTime.now();
LocalDateTime now = currentTime();
LocalDateTime startLocalDteTime = LocalDateTime.of(LocalDate.now(), startTime);
if (!isInTime) {
long mills = Duration.between(startLocalDteTime, now).toMillis() / 1000;
boolean noInOverTime = mills >= duration * 60;
if (noInOverTime) {
platAlarmCheckDTO.setAbnormalValue(String.valueOf(currentTimeMillis - firstOffBedLong));
log.info("deviceId:{}, cross离床告警第一次离床时间在范围前,配置:{}", deviceId, config.getRuleConfig());
platAlarmCheckDTO.setPlatAlarmConfig(config);
log.info("cross离床告警第一次离床时间在范围前,配置:{}", config.getRuleConfig());
noticeAlarm(alarmRedisDTO, platAlarmCheckDTO, deviceId);
} else {
log.info("cross离床告警,第一次离床时间在范围前,未预警,配置:{},时间持续:{},start:{}", config.getRuleConfig(), mills, startLocalDteTime);
log.info("deviceId:{},cross离床告警,第一次离床时间在范围前,未预警,配置:{},", deviceId, config.getRuleConfig());
}
} else {
log.info("handleCrossDay 未满足预警条件!fisrttime:{},config:{}", firstTime, config.getRuleConfig());
log.info("deviceId:{},Cross 未满足预警条件!first:{},config:{}", deviceId, firstTime, config.getRuleConfig());
}
}
/**
* 处理未跨天业务
*
* @param alarmRedisDTO
* @param ruleConfig
* @param platAlarmCheckDTO
* @param config
* @param deviceId
*/
private void handleUnCrossDay(AlarmRedisDTO alarmRedisDTO, PlatAlarmConfigOffBedDTOVO ruleConfig,
PlatAlarmCheckDTO platAlarmCheckDTO,
PlatAlarmConfig config,
String deviceId) {
log.info("deviceId:{},uncross_config:{},第一次离床时间:{}", deviceId, config.getRuleConfig(), longToTime(alarmRedisDTO.getStartLong()));
Integer duration = ruleConfig.getDuration();
LocalTime startTime = ruleConfig.getOffBedStart();
LocalDateTime startLocalDteTime = LocalDateTime.of(LocalDate.now(), startTime);
LocalTime endTime = ruleConfig.getOffBedEnd();
LocalDateTime endLocalDteTime = LocalDateTime.of(LocalDate.now(), endTime);
Long firstOffBedLong = alarmRedisDTO.getStartLong();
long currentTimeMillis = System.currentTimeMillis();
long currentTimeMillis = currentLong();
boolean isOverTime = (currentTimeMillis - firstOffBedLong) / 1000 >= duration * 60;
LocalDateTime firstOffBedTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(firstOffBedLong), ZoneOffset.of("+8"));
LocalTime firstTime = firstOffBedTime.toLocalTime();
if (firstTime.isAfter(endTime)) {
log.info("handleUnCrossDay第一次离床时间:{},在时间范围外 config:{}", firstTime, config.getRuleConfig());
return;
}
LocalTime firstTime = longToTime(firstOffBedLong).toLocalTime();
boolean isInTime = firstTime.isAfter(startTime) && firstTime.isBefore(endTime);
LocalTime endTimeLimit = endTime.plusMinutes(-duration);
// 离床时间在范围内
if (isInTime && isOverTime) {
if (firstTime.isAfter(endTimeLimit)) {
log.info("handleUnCrossDay第一次离床时间,{}+持续时间:{}将超过范围,{}", firstTime, duration, endTime);
log.info("deviceId:{},UnCrossDay第一次离床时间,{}+持续时间:{}将超过范围,{}", deviceId, firstTime, duration, endTime);
return;
}
platAlarmCheckDTO.setAbnormalValue(String.valueOf(currentTimeMillis - firstOffBedLong));
platAlarmCheckDTO.setPlatAlarmConfig(config);
log.info("uncross离床告警离床时间在范围时间内,配置:{}", config.getRuleConfig());
log.info("deviceId:{},uncross离床告警离床时间在范围时间内,配置:{}", deviceId, config.getRuleConfig());
noticeAlarm(alarmRedisDTO, platAlarmCheckDTO, deviceId);
return;
}
LocalDateTime now = LocalDateTime.now();
if (!isInTime && now.isAfter(startLocalDteTime) && now.isBefore(endLocalDteTime)) {
long mills = Duration.between(startLocalDteTime, now).toMillis() / 1000;
LocalTime localTime = LocalTime.now();
if (!isInTime && localTime.isAfter(startTime) && localTime.isBefore(endTime)) {
LocalDateTime dateTime = LocalDateTime.of(LocalDate.now(), startTime);
long mills = Duration.between(dateTime, currentTime()).toMillis() / 1000;
if (mills >= 86400) {
log.info("uncross离床告警第一次离床时间在范围前,跨天了:mills:{}", mills);
mills = mills - 86400;
}
if (mills <= -86400) {
log.info("uncross离床告警第一次离床时间在范围前,跨天了:mills:{}", mills);
mills = mills + 86400;
}
boolean noInOverTime = mills >= duration * 60;
if (noInOverTime) {
platAlarmCheckDTO.setAbnormalValue(String.valueOf(currentTimeMillis - firstOffBedLong));
log.info("deviceId:{},uncross离床告警第一次离床时间在范围前,配置:{},date:{},mills:{},first:{}",
deviceId, config.getRuleConfig(),dateTime,mills,firstTime);
platAlarmCheckDTO.setPlatAlarmConfig(config);
log.info("uncross离床告警第一次离床时间在范围前,配置:{}", config.getRuleConfig());
noticeAlarm(alarmRedisDTO, platAlarmCheckDTO, deviceId);
} else {
log.info("uncross离床告警第一次离床时间在范围前,未预警,配置:{},时间持续:{},start:{}", config.getRuleConfig(), mills, startLocalDteTime);
log.info("deviceId:{},uncross离床告警第一次离床时间在范围前,未预警,配置:{},间隔:{},first:{}",
deviceId, config.getRuleConfig(), mills, firstTime);
}
} else {
log.info("handleUnCrossDay 未满足预警条件!fisrttime:{},config:{}", firstTime, config.getRuleConfig());
log.info("deviceId:{},UnCrossDay 未满足预警条件!fis:{},config:{}", deviceId, firstTime, config.getRuleConfig());
}
}
private void sendToRedis(AlarmRedisDTO alarmRedisDTO, String deviceId) {
Date now = new Date();
long endLong = now.getTime();
private boolean sendToRedis(AlarmRedisDTO alarmRedisDTO, String deviceId) {
Date now = toDate();
// 第一次上报
if (alarmRedisDTO == null) {
alarmRedisDTO = new AlarmRedisDTO();
alarmRedisDTO.setAlarm(CommonEnum.NO.getValue());
alarmRedisDTO.setStart(now);
alarmRedisDTO.setStartLong(endLong);
alarmRedisDTO.setStartLong(currentLong());
RedisUtil.set(RedisConst.ALARM_DEVICE_OFF_BED_ID + deviceId, alarmRedisDTO);
log.info("离床告警 离床设备存储redis,第一次上报时间:{},开始上报时间:{},是否上报:{}",
getDateTime(alarmRedisDTO.getStartLong()), alarmRedisDTO.getStart(), alarmRedisDTO.getAlarm());
return true;
} else {
alarmRedisDTO.setStart(now);
log.info("离床告警离床更新redis,第一次上报时间:{},更新时间:{},是否上报:{}",
getDateTime(alarmRedisDTO.getStartLong()), alarmRedisDTO.getStart(), alarmRedisDTO.getAlarm());
RedisUtil.set(RedisConst.ALARM_DEVICE_OFF_BED_ID + deviceId, alarmRedisDTO);
return false;
}
}
private void noticeAlarm(AlarmRedisDTO alarmRedisDTO, PlatAlarmCheckDTO platAlarmCheckDTO, String deviceId) {
PlatAlarmConfig platAlarmConfig = platAlarmCheckDTO.getPlatAlarmConfig();
LocalDateTime firstOffBedTime = longToTime(alarmRedisDTO.getStartLong());
String remark = "第一次离床时间:" + firstOffBedTime + ",config:" + platAlarmConfig.getRuleConfig() + ",当前时间:" + currentTime();
platAlarmCheckDTO.setRemark(remark);
notice(platAlarmCheckDTO);
alarmRedisDTO.setStart(new Date());
alarmRedisDTO.setAlarm(CommonEnum.YES.getValue());
RedisUtil.set(RedisConst.ALARM_DEVICE_OFF_BED_ID + deviceId, alarmRedisDTO);
log.info("离床告警推送离床消息,第一次上报时间:{},开始上报时间:{},是否上报:{}",
getDateTime(alarmRedisDTO.getStartLong()), alarmRedisDTO.getStart(), alarmRedisDTO.getAlarm());
log.info("deviceId:{},离床告警推送离床消息,第一次上报时间:{},开始上报时间:{},是否上报:{},上报的config:{}", deviceId,
longToTime(alarmRedisDTO.getStartLong()), alarmRedisDTO.getStart(), alarmRedisDTO.getAlarm()
, platAlarmConfig.getRuleConfig());
}
@Override
......@@ -281,23 +300,19 @@ public class OffBedAlarm implements IAlarm {
List<PlatElder> platElderList = platAlarmCheckDTO.getPlatElderList();
PlatAlarmConfig config = platAlarmCheckDTO.getPlatAlarmConfig();
if (CommonEnum.NO.getValue().equals(config.getStatus())) {
log.error("离床告警配置为禁用,告警配置id:" + config.getId());
// log.error("离床告警配置为禁用,告警配置id:" + config.getId());
return;
}
if (StringUtils.isBlank(config.getRuleConfig())) {
log.error("离床告警配置未配置,告警配置id:" + config.getId());
// log.error("离床告警配置未配置,告警配置id:" + config.getId());
return;
}
if (CollectionUtils.isEmpty(platElderList)) {
log.error("离床告警配置未关联长者,设备plat_id:" + platDevice.getId());
// log.error("离床告警配置未关联长者,设备plat_id:" + platDevice.getId());
return;
}
// PlatRoom platRoom = platAlarmCheckDTO.getPlatRoom();
for (PlatElder platElder : platElderList) {
if (!platElder.getOrgId().equals(config.getOrgId())) {
log.info("长者不再配置组织内:长者:{},config:{}", platElder.getName(), config.getRuleConfig());
continue;
}
List<String> param = new ArrayList<>();
// param.add(platRoom.getName());
param.add(platElder.getName());
......@@ -305,26 +320,29 @@ public class OffBedAlarm implements IAlarm {
PlatAlarmRecord platAlarmRecord = platAlarmRecordService.convertToPlatAlarmRecord(platAlarmCheckDTO, platElder);
platAlarmRecord.setElderName(platElder.getName());
platAlarmRecord.setElderIds(platElder.getId());
platAlarmRecord.setRemark(platAlarmCheckDTO.getRemark());
platAlarmRecordService.noticeDeviceAlarm(platAlarmCheckDTO.getPlatAlarmConfig(), platAlarmRecord);
log.info("离床告警配置,发出告警,设备id:" + platDevice.getId() + ", 长者名称:" + platElder.getName()
+ "config_id:" + config.getId() + "--" + config.getRuleConfig());
}
}
private static String getDateTime(long longTime) {
return dateToString(new Date(longTime), new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
private static long currentLong() {
return currentTime().toInstant(ZoneOffset.of("+8")).toEpochMilli();
}
/**
* 日期类型转换成字符串类型
*
* @param date 日期
* @param dateFormat 日期格式
* @return 日期字符串
*/
private static String dateToString(Date date, DateFormat dateFormat) {
return dateFormat.format(date);
private static LocalDateTime currentTime() {
return LocalDateTime.now();
// return LocalDateTime.now();
}
private LocalDateTime longToTime(Long longTime) {
return LocalDateTime.ofInstant(Instant.ofEpochMilli(longTime), ZoneOffset.of("+8"));
}
private Date toDate() {
ZoneId zoneId = ZoneId.systemDefault();
ZonedDateTime zdt = currentTime().atZone(zoneId);
return Date.from(zdt.toInstant());
}
}
......@@ -2,6 +2,7 @@ package com.makeit.service.platform.alarm.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
......@@ -15,7 +16,9 @@ import com.makeit.entity.platform.auth.PlatUser;
import com.makeit.enums.CodeMessageEnum;
import com.makeit.enums.CommonEnum;
import com.makeit.enums.id.IdConst;
import com.makeit.enums.platform.alarm.PlatAlarmConfigEnum;
import com.makeit.exception.BusinessException;
import com.makeit.global.aspect.tenant.TenantIdIgnore;
import com.makeit.global.aspect.tenant.TenantIdUtil;
import com.makeit.mapper.platform.alarm.PlatAlarmConfigMapper;
import com.makeit.service.platform.alarm.PlatAlarmConfigService;
......@@ -57,6 +60,8 @@ public class PlatAlarmConfigServiceImpl extends ServiceImpl<PlatAlarmConfigMappe
private AlarmConfigCacheUtil alarmConfigUtil;
@Resource
private PlatOrgService platOrgService;
@Resource
private PlatAlarmConfigMapper configMapper;
@Override
public List<PlatAlarmConfigListVO> list(PlatAlarmConfigQueryDTO dto) {
......@@ -243,7 +248,7 @@ public class PlatAlarmConfigServiceImpl extends ServiceImpl<PlatAlarmConfigMappe
Map<String, PlatAlarmConfig> configMap = StreamUtil.toMap(existList, PlatAlarmConfig::getOrgId);
List<PlatAlarmConfig> saveList = Lists.newArrayList();
for (PlatOrg o : orgList) {
if (configMap.containsKey(o.getId())) {
if (configMap.containsKey(o.getId()) || StrUtil.isBlank(o.getTenantId()) || "0".equals(o.getTenantId())) {
continue;
}
PlatAlarmConfig alarmConfig = new PlatAlarmConfig();
......@@ -256,4 +261,11 @@ public class PlatAlarmConfigServiceImpl extends ServiceImpl<PlatAlarmConfigMappe
saveBatch(saveList);
}
}
@Override
@TenantIdIgnore
public List<PlatAlarmConfig> listOfBed(List<String> orgIds) {
return list(Wrappers.<PlatAlarmConfig>lambdaQuery().in(PlatAlarmConfig::getOrgId, orgIds).eq(PlatAlarmConfig::getAlarmType,
PlatAlarmConfigEnum.AlarmTypeEnum.OFF_BED.getValue()));
}
}
......@@ -123,7 +123,7 @@ public class PlatAlarmRecordServiceImpl extends ServiceImpl<PlatAlarmRecordMappe
Boolean isUnWechatRead = CollUtil.isNotEmpty(list) && list.stream()
.anyMatch(a -> CommonEnum.NO.getValue().equals(a.getWechatReadFlag()));
Boolean statusFlag = CollUtil.isNotEmpty(list) && list.stream()
.anyMatch(a -> CommonEnum.NO.getValue().equals(a.getStatus()));
.anyMatch(a -> CommonEnum.NO.getValue().equals(a.getReadFlag()));
Page<PlatAlarmRecord> page = page(mpPage, lambdaQueryWrapper);
List<PlatAlarmRecord> records = page.getRecords();
List<PlatAlarmRecordVO> dtos = BeanDtoVoUtils.listVo(records, PlatAlarmRecordVO.class);
......
......@@ -32,6 +32,8 @@ import java.util.List;
*/
public interface PlatDeviceService extends IService<PlatDevice> {
PageVO<PlatDeviceListVO> platPage(PageReqDTO<PlatDeviceQueryDTO> pageReqDTO);
PageVO<PlatDeviceListVO> page(PageReqDTO<PlatDeviceQueryDTO> pageReqDTO);
void edit(PlatDeviceEditDTO dto);
......@@ -95,4 +97,6 @@ public interface PlatDeviceService extends IService<PlatDevice> {
void devicePushLog(MultipartFile multipartFile, String deviceId) throws IOException;
void syncIotProperties(String deviceId, JSONObject iotProperties);
List<PlatDevice> listOffBed(String oriDeviceId);
}
......@@ -3,12 +3,14 @@ package com.makeit.service.platform.device.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
......@@ -20,7 +22,6 @@ import com.makeit.common.entity.BaseBusEntity;
import com.makeit.common.entity.BaseEntity;
import com.makeit.common.page.PageReqDTO;
import com.makeit.common.page.PageVO;
import com.makeit.common.response.ApiResponseEntity;
import com.makeit.config.ShengwangProperties;
import com.makeit.dto.platform.dataScreen.PlatDataScreenQueryDTO;
import com.makeit.dto.platform.device.*;
......@@ -39,6 +40,7 @@ import com.makeit.entity.saas.SaasPidManage;
import com.makeit.enums.CodeMessageEnum;
import com.makeit.enums.CommonEnum;
import com.makeit.enums.platform.device.PlatDeviceEnum;
import com.makeit.enums.redis.RedisConst;
import com.makeit.enums.report.DeviceNameEnum;
import com.makeit.exception.BusinessException;
import com.makeit.global.aspect.tenant.TenantIdIgnore;
......@@ -47,6 +49,7 @@ import com.makeit.module.iot.dto.UserServerInfo;
import com.makeit.module.iot.service.IotDevicePropertiesOperateService;
import com.makeit.module.iot.service.IotOrgService;
import com.makeit.module.iot.service.IotProductDeviceService;
import com.makeit.module.iot.vo.DeviceDetail;
import com.makeit.module.iot.vo.DeviceInstanceEntity;
import com.makeit.module.iot.vo.DeviceProperties;
import com.makeit.module.iot.vo.DeviceState;
......@@ -74,9 +77,9 @@ import com.makeit.utils.data.convert.JsonUtil;
import com.makeit.utils.data.convert.PageUtil;
import com.makeit.utils.data.convert.StreamUtil;
import com.makeit.utils.old.StringUtils;
import com.makeit.utils.redis.RedisUtil;
import com.makeit.utils.sql.join.JoinUtil;
import com.makeit.vo.platform.device.PlatChildDeviceListVO;
import com.makeit.vo.platform.device.PlatDeviceActiveVO;
import com.makeit.vo.platform.device.PlatDeviceListVO;
import com.makeit.vo.platform.device.PlatDeviceViewVO;
import lombok.extern.slf4j.Slf4j;
......@@ -153,6 +156,81 @@ public class PlatDeviceServiceImpl extends ServiceImpl<PlatDeviceMapper, PlatDev
* @return
*/
@Override
public PageVO<PlatDeviceListVO> platPage(PageReqDTO<PlatDeviceQueryDTO> pageReqDTO) {
PlatDeviceQueryDTO dto = pageReqDTO.getData();
Page<PlatDevice> p = PageUtil.toMpPage(pageReqDTO);
Page<PlatDeviceListVO> page = baseMapper.getDeviceIdsBySpaceIdAndElder(dto, p);
List<PlatDeviceListVO> records = page.getRecords();
if (CollectionUtils.isEmpty(records)) {
return PageVO.emptyPage();
}
List<String> spaceIdList = records.stream().flatMap(vo -> {
String spaceParentPath = vo.getSpaceParentPath();
String spp = Optional.ofNullable(spaceParentPath).orElse("");
return Stream.of(spp.split(","));
}).collect(Collectors.toList());
spaceIdList.add("-1");
List<PlatSpace> platSpaces = platSpaceService.listByIds(spaceIdList);
Map<String, String> spaceIdNameMap = platSpaces.stream().collect(Collectors.toMap(BaseEntity::getId, vo -> vo.getName(), (v1, v2) -> v1));
List<String> deviceIds = StreamUtil.map(records, PlatDeviceListVO::getId);
List<PlatRoomBedDevice> platRoomBedDevices = platRoomBedDeviceService.list(new QueryWrapper<PlatRoomBedDevice>().lambda()
.in(PlatRoomBedDevice::getDeviceId, deviceIds));
List<String> roomIds = StreamUtil.map(platRoomBedDevices, PlatRoomBedDevice::getRoomId).stream().distinct().collect(Collectors.toList());
List<String> bedIds = StreamUtil.filterMap(platRoomBedDevices, b -> b.getBedId() != null, PlatRoomBedDevice::getBedId);
List<PlatElder> roomElders = platElderService.list(new QueryWrapper<PlatElder>().lambda().in(PlatElder::getRoomId, roomIds));
List<PlatElder> bedElders = platElderService.list(new QueryWrapper<PlatElder>().lambda().in(PlatElder::getBedId, bedIds));
Map<String, List<PlatElder>> roomEldersMap = roomElders.stream().collect(Collectors.groupingBy(PlatElder::getRoomId, Collectors.toList()));
Map<String, List<PlatElder>> bedEldersMap = bedElders.stream().collect(Collectors.groupingBy(PlatElder::getBedId, Collectors.toList()));
for (PlatDeviceListVO record : records) {
String spaceParentPath = record.getSpaceParentPath();
String spaceName = "";
if (StringUtils.isNotBlank(spaceParentPath)) {
String spaceNameJoin = Stream.of(spaceParentPath.split(",")).map(vo -> spaceIdNameMap.get(vo)).collect(Collectors.joining("-"));
spaceName = spaceNameJoin + "-" + record.getSpaceName() + "-" + record.getRoomName();
} else {
if (StringUtils.isNotEmpty(record.getSpaceName())) {
spaceName = record.getSpaceName();
}
if (StringUtils.isNotEmpty(record.getRoomName())) {
spaceName += "-" + record.getRoomName();
}
}
if (StringUtils.isNotBlank(record.getBedName())) {
spaceName = spaceName + "-" + record.getBedName();
}
record.setSpaceName(spaceName);
String elderNames = "";
if (PlatDeviceEnum.CategoryEnum.HEART.getValue().equals(record.getCategory())) {
elderNames = bedEldersMap.getOrDefault(record.getBedId(), Lists.newArrayList()).stream().map(PlatElder::getName).collect(Collectors.joining(","));
} else {
elderNames = roomEldersMap.getOrDefault(record.getRoomId(), Lists.newArrayList()).stream().map(PlatElder::getName).collect(Collectors.joining(","));
}
record.setElderName(elderNames);
}
JoinUtil.join(records, platOrgService, PlatDeviceListVO::getOrgId, PlatOrg::getId, (d, o) -> {
d.setOrgName(o.getName());
});
JoinUtil.joinSplit(records, platOrgService, PlatDeviceListVO::getOrgPath, PlatOrg::getId, (d, o) -> {
d.setOrgPathName(StreamUtil.join(o, PlatOrg::getName));
});
return PageUtil.toPageVO(records, page);
}
@Override
public PageVO<PlatDeviceListVO> page(PageReqDTO<PlatDeviceQueryDTO> pageReqDTO) {
PlatDeviceQueryDTO dto = pageReqDTO.getData();
Page<PlatDevice> p = PageUtil.toMpPage(pageReqDTO);
......@@ -306,11 +384,7 @@ public class PlatDeviceServiceImpl extends ServiceImpl<PlatDeviceMapper, PlatDev
platDeviceAttrWechatDTO.setDeviceId(db.getOriDeviceId());
editDeviceProperties(platDeviceAttrWechatDTO);
}
//iotProductDeviceService.syncUpdateDeviceInfo(db.getOriDeviceId(),dto.getName(),db.getProductId());
iotProductDeviceService.syncUpdateDeviceInfo(db.getOriDeviceId(), dto.getName(), db.getProductId(), dto.getDescription());
}
@Override
......@@ -327,6 +401,16 @@ public class PlatDeviceServiceImpl extends ServiceImpl<PlatDeviceMapper, PlatDev
}
vo.setId(db.getId());
DeviceDetail detail = iotProductDeviceService.getDetail(db.getOriDeviceId());
if (detail != null) {
if (detail.getFirmwareInfo() != null) {
vo.setFirmwareVersion(detail.getFirmwareInfo().getVersion());
}
if (detail.getOnlineTime() != 0) {
vo.setLastOnlineData(LocalDateTime.ofEpochSecond(detail.getOnlineTime() / 1000, 0, ZoneOffset.ofHours(8)));
}
vo.setDescription(detail.getDescription());
}
return vo;
......@@ -425,7 +509,7 @@ public class PlatDeviceServiceImpl extends ServiceImpl<PlatDeviceMapper, PlatDev
db.setName(dto.getName());
updateById(db);
deviceCacheUtil.put(db);
iotProductDeviceService.syncUpdateDeviceInfo(db.getOriDeviceId(), dto.getName(), db.getProductId(), db.getDescription());
}
/**
......@@ -463,7 +547,7 @@ public class PlatDeviceServiceImpl extends ServiceImpl<PlatDeviceMapper, PlatDev
String id = db.getId();
PlatDeviceOther other = platDeviceOtherService.getOne(new QueryWrapper<PlatDeviceOther>().lambda()
.eq(PlatDeviceOther::getDeviceId, db.getId()));
.eq(PlatDeviceOther::getDeviceId, db.getId()).last("limit 1"));
if (other == null) {
other = new PlatDeviceOther();
}
......@@ -490,6 +574,7 @@ public class PlatDeviceServiceImpl extends ServiceImpl<PlatDeviceMapper, PlatDev
platDeviceAttrWechatDTO.setDeviceId(db.getOriDeviceId());
editDeviceProperties(platDeviceAttrWechatDTO);
}
iotProductDeviceService.syncUpdateDeviceInfo(db.getOriDeviceId(), dto.getName(), db.getProductId(), dto.getDescription());
}
......@@ -545,24 +630,28 @@ public class PlatDeviceServiceImpl extends ServiceImpl<PlatDeviceMapper, PlatDev
PlatDeviceBaseAttrDTO platDeviceBaseAttrDTO = getPlatDeviceBaseAttrDTO(deviceId);
String reqJson = JSON.toJSONString(dto);
Map<String, Object> map = getReqMap(dto, platDeviceBaseAttrDTO);
if (map.isEmpty()) {
return;
}
log.info("写入设备属性请求参数:{}", reqJson);
String result = devicePropertiesOperateService.deviceWriteAttr(deviceId, map);
if (StringUtils.isNotEmpty(result)) {
throw new RuntimeException("设备写入失败:" + result);
}
List<PlatDeviceOther> platDeviceOtherList = platDeviceOtherService.list(new QueryWrapper<PlatDeviceOther>().lambda()
.eq(PlatDeviceOther::getOriDeviceId, deviceId));
for (PlatDeviceOther platDeviceOther : platDeviceOtherList) {
platDeviceOther.setAttribute(reqJson);
platDeviceOtherService.updateById(platDeviceOther);
}
if (dto.getRadarMount() != null) {
List<PlatDevice> platDeviceList = list(new QueryWrapper<PlatDevice>().lambda().eq(PlatDevice::getOriDeviceId, deviceId));
//更新区域设置设备安装方式
platRegionSettingService.update(new UpdateWrapper<PlatRegionSetting>().lambda()
.set(PlatRegionSetting::getInstallType, dto.getRadarMount())
.in(CollectionUtils.isNotEmpty(platDeviceList),PlatRegionSetting::getDeviceId, StreamUtil.map(platDeviceList,BaseEntity::getId)));
}
// 写入设备后等iot MQTT消息回复单独更新,不直接修改数据库属性
// List<PlatDeviceOther> platDeviceOtherList = platDeviceOtherService.list(new QueryWrapper<PlatDeviceOther>().lambda()
// .eq(PlatDeviceOther::getOriDeviceId, deviceId));
// for (PlatDeviceOther platDeviceOther : platDeviceOtherList) {
// platDeviceOther.setAttribute(reqJson);
// platDeviceOtherService.updateById(platDeviceOther);
// }
// if (dto.getRadarMount() != null) {
// List<PlatDevice> platDeviceList = list(new QueryWrapper<PlatDevice>().lambda().eq(PlatDevice::getOriDeviceId, deviceId));
// //更新区域设置设备安装方式
// platRegionSettingService.update(new UpdateWrapper<PlatRegionSetting>().lambda()
// .set(PlatRegionSetting::getInstallType, dto.getRadarMount())
// .in(CollectionUtils.isNotEmpty(platDeviceList),PlatRegionSetting::getDeviceId, StreamUtil.map(platDeviceList,BaseEntity::getId)));
// }
}
private PlatDeviceBaseAttrDTO getPlatDeviceBaseAttrDTO(String deviceId) {
......@@ -575,35 +664,31 @@ public class PlatDeviceServiceImpl extends ServiceImpl<PlatDeviceMapper, PlatDev
private static Map<String, Object> getReqMap(PlatDeviceBaseAttrDTO dto, PlatDeviceBaseAttrDTO platDeviceBaseAttrDTO) {
Map<String, Object> map = Maps.newHashMap();
if (!Objects.equals(platDeviceBaseAttrDTO.getRadarMode(), dto.getRadarMode())) {
if (dto.getRadarMode() != null && !Objects.equals(platDeviceBaseAttrDTO.getRadarMode(), dto.getRadarMode())) {
map.put("radarMode", dto.getRadarMode());
}
if (!Objects.equals(platDeviceBaseAttrDTO.getRadarMount(), dto.getRadarMount())) {
if (dto.getRadarMount() != null && !Objects.equals(platDeviceBaseAttrDTO.getRadarMount(), dto.getRadarMount())) {
map.put("radarMount", dto.getRadarMount());
}
if (!Objects.equals(platDeviceBaseAttrDTO.getRadarHight(), dto.getRadarHight())) {
if (dto.getRadarHight() != null && !Objects.equals(platDeviceBaseAttrDTO.getRadarHight(), dto.getRadarHight())) {
map.put("radarHight", dto.getRadarHight());
}
if (!Objects.equals(platDeviceBaseAttrDTO.getRadarDelay(), dto.getRadarDelay())) {
map.put("radarDelay", dto.getRadarDelay() );
if (dto.getRadarDelay() != null && !Objects.equals(platDeviceBaseAttrDTO.getRadarDelay(), dto.getRadarDelay())) {
map.put("radarDelay", dto.getRadarDelay());
}
PlatDeviceBaseAttrDTO.DeviceAttrRange radarDistance = platDeviceBaseAttrDTO.getRadarDistance();
if (!Objects.equals(radarDistance, dto.getRadarDistance())) {
if (dto.getRadarDistance() != null) {
map.put("radarDistance", JSON.toJSONString(dto.getRadarDistance()));
}
if (dto.getRadarDistance() != null && !Objects.equals(radarDistance, dto.getRadarDistance())) {
map.put("radarDistance", JSON.toJSONString(dto.getRadarDistance()));
}
PlatDeviceBaseAttrDTO.DeviceAttrRange radarAngle = platDeviceBaseAttrDTO.getRadarAngle();
if (!Objects.equals(radarAngle, dto.getRadarAngle())) {
if (dto.getRadarAngle() != null) {
map.put("radarAngle", JSON.toJSONString(dto.getRadarAngle()));
}
if (dto.getRadarAngle() != null && !Objects.equals(radarAngle, dto.getRadarAngle())) {
map.put("radarAngle", JSON.toJSONString(dto.getRadarAngle()));
}
if (!Objects.equals(platDeviceBaseAttrDTO.getRadarSence(), dto.getRadarSence())) {
map.put("radarSence", dto.getRadarSence() );
if (dto.getRadarSence() != null && !Objects.equals(platDeviceBaseAttrDTO.getRadarSence(), dto.getRadarSence())) {
map.put("radarSence", dto.getRadarSence());
}
if (!Objects.equals(platDeviceBaseAttrDTO.getRadarSPL(), dto.getRadarSPL())) {
map.put("radarSPL", dto.getRadarSPL() );
if (dto.getRadarSPL() != null && !Objects.equals(platDeviceBaseAttrDTO.getRadarSPL(), dto.getRadarSPL())) {
map.put("radarSPL", dto.getRadarSPL());
}
return map;
}
......@@ -613,21 +698,34 @@ public class PlatDeviceServiceImpl extends ServiceImpl<PlatDeviceMapper, PlatDev
String deviceId = dto.getDeviceId();
UserServerInfo usrServerInfo = dto.getUsrServerInfo();
log.info("写入设备属性请求参数:{}",JSON.toJSONString(dto));
Map<String, Object> map = Maps.newHashMap();
map.put("usrServerInfo",JSON.toJSONString(usrServerInfo));
/* String result = devicePropertiesOperateService.deviceWriteAttr(deviceId, map);
if (StringUtils.isNotEmpty(result)) {
throw new RuntimeException("设备写入失败:" + result);
}*/
String value = JSON.toJSONString(usrServerInfo);
boolean needWrite = true;
List<PlatDeviceOther> platDeviceOtherList = platDeviceOtherService.list(new QueryWrapper<PlatDeviceOther>().lambda()
.eq(PlatDeviceOther::getOriDeviceId, deviceId));
if (CollectionUtils.isNotEmpty(platDeviceOtherList)) {
PlatDeviceOther platDeviceOther = platDeviceOtherList.get(0);
UserServerInfo existInfo = new UserServerInfo();
existInfo.setAddr(platDeviceOther.getProtocolAddress());
existInfo.setPort(StringUtils.isNotBlank(platDeviceOther.getProtocolPort()) ? Integer.valueOf(platDeviceOther.getProtocolPort()) : null);
existInfo.setUsername(platDeviceOther.getProtocolAccount());
existInfo.setPassword(platDeviceOther.getProtocolPassword());
String jsonString = JSON.toJSONString(existInfo);
needWrite = !value.equals(jsonString);
}
if (needWrite) {
ThreadUtil.sleep(200); // 受限于设备不支持同时写入 稍微延迟一点执行(前端先修改属性再修改网络信息)
Map<String, Object> map = Maps.newHashMap();
map.put("usrServerInfo", value);
String result = devicePropertiesOperateService.deviceWriteAttr(deviceId, map);
if (StringUtils.isNotEmpty(result)) {
throw new RuntimeException("设备写入失败:" + result);
}
}
for (PlatDeviceOther platDeviceOther : platDeviceOtherList) {
platDeviceOther.setProtocolAccount(usrServerInfo.getUsername());
platDeviceOther.setProtocolPassword(usrServerInfo.getPassword());
platDeviceOther.setProtocolAddress(usrServerInfo.getAddr());
platDeviceOther.setProtocolPort(usrServerInfo.getPort() == null ? "" : usrServerInfo.getPort().toString());
platDeviceOther.setSecureId(usrServerInfo.getSecureId());
platDeviceOther.setSecureKey(usrServerInfo.getSecureKey());
platDeviceOtherService.updateById(platDeviceOther);
}
}
......@@ -662,20 +760,23 @@ public class PlatDeviceServiceImpl extends ServiceImpl<PlatDeviceMapper, PlatDev
if (CollectionUtils.isEmpty(deviceIdList)) {
return;
}
String reqJson = JSON.toJSONString(dto);
for (String deviceId : deviceIdList) {
PlatDeviceBaseAttrDTO platDeviceBaseAttrDTO = getPlatDeviceBaseAttrDTO(deviceId);
Map<String, Object> map = getReqMap(dto,platDeviceBaseAttrDTO);
if (map.isEmpty()) {
continue;
}
String result = devicePropertiesOperateService.deviceWriteAttr(deviceId, map);
if (StringUtils.isNotEmpty(result)) {
throw new RuntimeException("修改设备属性失败:" + result);
}
List<PlatDeviceOther> otherList = platDeviceOtherService.list(new QueryWrapper<PlatDeviceOther>().lambda()
.eq(PlatDeviceOther::getOriDeviceId, deviceId));
for (PlatDeviceOther platDeviceOther : otherList) {
platDeviceOther.setAttribute(reqJson);
platDeviceOtherService.updateById(platDeviceOther);
}
// 写入设备后等iot MQTT消息回复单独更新,不直接修改数据库属性
// List<PlatDeviceOther> otherList = platDeviceOtherService.list(new QueryWrapper<PlatDeviceOther>().lambda()
// .eq(PlatDeviceOther::getOriDeviceId, deviceId));
// for (PlatDeviceOther platDeviceOther : otherList) {
// platDeviceOther.setAttribute(reqJson);
// platDeviceOtherService.updateById(platDeviceOther);
// }
}
......@@ -839,7 +940,9 @@ public class PlatDeviceServiceImpl extends ServiceImpl<PlatDeviceMapper, PlatDev
@TenantIdIgnore
public boolean updateDeviceStatus(String messageType, String deviceId, String iot_tenantId) {
try {
if (org.apache.commons.lang3.StringUtils.equalsAnyIgnoreCase(messageType, com.makeit.module.iot.enums.DeviceState.offline.getValue(), com.makeit.module.iot.enums.DeviceState.online.getValue())) {
boolean isOffLine = com.makeit.module.iot.enums.DeviceState.offline.getValue().equalsIgnoreCase(messageType);
boolean isOnLine = com.makeit.module.iot.enums.DeviceState.online.getValue().equalsIgnoreCase(messageType);
if (isOffLine || isOnLine) {
update(new UpdateWrapper<PlatDevice>().lambda()
.set(PlatDevice::getStatus, messageType.toLowerCase())
......@@ -850,9 +953,10 @@ public class PlatDeviceServiceImpl extends ServiceImpl<PlatDeviceMapper, PlatDev
List<PlatDevice> deviceList = list(deviceLambdaQueryWrapper);
if (CollectionUtils.isNotEmpty(deviceList)) {
for (PlatDevice platDevice : deviceList) {
platDevice.setStatus(messageType.toLowerCase());
if (isOffLine) {
RedisUtil.delete(RedisConst.ALARM_DEVICE_OFF_BED_ID + platDevice.getId());
}
}
deviceCacheUtil.putAll(deviceList);
}
return true;
}
......@@ -973,9 +1077,26 @@ public class PlatDeviceServiceImpl extends ServiceImpl<PlatDeviceMapper, PlatDev
@TenantIdIgnore
@Transactional(rollbackFor = Exception.class)
public void syncIotProperties(String deviceId, JSONObject iotProperties) {
PlatDeviceBaseAttrDTO iotAttr = iotProperties.toJavaObject(PlatDeviceBaseAttrDTO.class);
// 网络属性
if (iotProperties.containsKey("usrServerInfo")) {
UserServerInfo userServerInfo = iotProperties.getJSONObject("usrServerInfo").toJavaObject(UserServerInfo.class);
if (userServerInfo == null) {
return;
}
platDeviceOtherService.update(new UpdateWrapper<PlatDeviceOther>().lambda()
.set(StringUtils.isNotBlank(userServerInfo.getAddr()), PlatDeviceOther::getProtocolAddress, userServerInfo.getAddr())
.set(userServerInfo.getPort() != null, PlatDeviceOther::getProtocolPort, userServerInfo.getPort())
.set(StringUtils.isNotBlank(userServerInfo.getUsername()), PlatDeviceOther::getProtocolAccount, userServerInfo.getUsername())
.set(StringUtils.isNotBlank(userServerInfo.getPassword()), PlatDeviceOther::getProtocolPassword, userServerInfo.getPassword())
.eq(PlatDeviceOther::getOriDeviceId, deviceId));
return;
}
List<PlatDeviceOther> deviceOthers = platDeviceOtherService.list(new QueryWrapper<PlatDeviceOther>().lambda()
.eq(PlatDeviceOther::getOriDeviceId, deviceId));
if (CollectionUtils.isEmpty(deviceOthers)) {
return;
}
PlatDeviceBaseAttrDTO iotAttr = iotProperties.toJavaObject(PlatDeviceBaseAttrDTO.class);
Integer radarMount = null;
for (PlatDeviceOther deviceOther : deviceOthers) {
PlatDeviceBaseAttrDTO platDeviceBaseAttrDTO = JSON.parseObject(deviceOther.getAttribute(), PlatDeviceBaseAttrDTO.class);
......@@ -1046,4 +1167,9 @@ public class PlatDeviceServiceImpl extends ServiceImpl<PlatDeviceMapper, PlatDev
return platDeviceBaseAttrDTO;
}
@Override
@TenantIdIgnore
public List<PlatDevice> listOffBed(String oriDeviceId) {
return list(Wrappers.<PlatDevice>lambdaQuery().eq(PlatDevice::getOriDeviceId, oriDeviceId));
}
}
......@@ -3,6 +3,8 @@ package com.makeit.service.platform.elder;
import com.baomidou.mybatisplus.extension.service.IService;
import com.makeit.entity.platform.elder.PlatElderBreatheAnalysis;
import java.util.List;
/**
* <p>
* 长者每天呼吸分析 服务类
......@@ -13,5 +15,5 @@ import com.makeit.entity.platform.elder.PlatElderBreatheAnalysis;
*/
public interface PlatElderBreatheAnalysisService extends IService<PlatElderBreatheAnalysis> {
void elderHeartRespiratoryAnalysisTask();
List<PlatElderBreatheAnalysis> elderHeartRespiratoryAnalysisTask(Integer month, Integer day);
}
package com.makeit.service.platform.elder.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
......@@ -15,8 +16,7 @@ import com.makeit.entity.platform.elder.PlatElderBreatheDayStat;
import com.makeit.entity.saas.analysis.SaasDiseaseEvaluateReport;
import com.makeit.entity.saas.analysis.SaasDiseaseModel;
import com.makeit.entity.saas.analysis.SaasSleepAnalysisModel;
import com.makeit.enums.report.BreatheTypeEnum;
import com.makeit.enums.report.HeartRateTypeEnum;
import com.makeit.enums.report.ConditionTypeEnum;
import com.makeit.mapper.platform.elder.PlatElderBreatheAnalysisMapper;
import com.makeit.module.iot.service.IotProductDeviceService;
import com.makeit.module.iot.vo.DeviceOperationLogEntity;
......@@ -38,6 +38,8 @@ import com.makeit.utils.data.convert.StreamUtil;
import com.makeit.utils.time.LocalDateTimeUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
......@@ -46,6 +48,7 @@ import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
......@@ -62,6 +65,8 @@ import java.util.stream.Collectors;
@Service
public class PlatElderBreatheAnalysisServiceImpl extends ServiceImpl<PlatElderBreatheAnalysisMapper, PlatElderBreatheAnalysis> implements PlatElderBreatheAnalysisService {
private static final Logger logger = LoggerFactory.getLogger(PlatElderBreatheAnalysisServiceImpl.class);
@Autowired
private PlatElderService platElderService;
@Autowired
......@@ -85,16 +90,19 @@ public class PlatElderBreatheAnalysisServiceImpl extends ServiceImpl<PlatElderBr
@Override
@Transactional(rollbackFor = Exception.class)
public void elderHeartRespiratoryAnalysisTask() {
public List<PlatElderBreatheAnalysis> elderHeartRespiratoryAnalysisTask(Integer month,Integer day) {
// 12-06,12-18 12-07、 12-12(70分)
LocalDate nowDate = LocalDate.now();
// LocalDate nowDate = LocalDate.of(2023, month, day);
LocalDate yesDate = nowDate.minusDays(1);
LocalDateTime yesStart = LocalDateTimeUtils.getDayStart(yesDate);
LocalDateTime yesEnd = LocalDateTimeUtils.getDayEnd(yesDate);
List<PlatElder> elderList = platElderService.list(new QueryWrapper<PlatElder>().lambda()
.isNotNull(PlatElder::getBedId));
List<PlatElderBreatheAnalysis> result = new ArrayList<>();
if (CollectionUtils.isEmpty(elderList)) {
return;
return result;
}
List<String> elderIdList = StreamUtil.map(elderList, BaseEntity::getId);
......@@ -211,7 +219,7 @@ public class PlatElderBreatheAnalysisServiceImpl extends ServiceImpl<PlatElderBr
}
// 判断呼吸率阈值,记录发生时间和当前呼吸率
if (breatheThresholdMax < br) {
if (breatheThresholdMax < br && br != 255) {
if (brFast == 0) {
brFast = br;
}
......@@ -238,7 +246,7 @@ public class PlatElderBreatheAnalysisServiceImpl extends ServiceImpl<PlatElderBr
}
if (heartThresholdMax < hr) {
if (heartThresholdMax < hr && hr != 255) {
if (hrFast == 0) {
hrFast = br;
}
......@@ -387,7 +395,9 @@ public class PlatElderBreatheAnalysisServiceImpl extends ServiceImpl<PlatElderBr
// 根据疾病标准配置的规则判断满足哪个区间范围
for (DiseaseReportVO diseaseReportVO : evaluateReportList) {
List<DiseaseReportVO.Condition> conditionList = diseaseReportVO.getCondition();
if (CollUtil.isEmpty(conditionList)) {
return result;
}
boolean conditionFlag = true;
for (DiseaseReportVO.Condition condition : conditionList) {
......@@ -398,22 +408,22 @@ public class PlatElderBreatheAnalysisServiceImpl extends ServiceImpl<PlatElderBr
break;
}
} else {
if (resultRelational.equals("normal")) {
if (resultCondition.equals(ConditionTypeEnum.NORMAL.getCode())) {
conditionFlag = normalFlag && conditionFlag;
}
if (resultRelational.equals(BreatheTypeEnum.APNEA.getCode())) {
if (resultCondition.equals(ConditionTypeEnum.BREATHE_STOP.getCode())) {
conditionFlag = brStopFlag && conditionFlag;
}
if (resultRelational.equals(BreatheTypeEnum.TACHYPNEA.getCode())) {
if (resultCondition.equals(ConditionTypeEnum.BREATHE_FAST.getCode())) {
conditionFlag = brFastFlag && conditionFlag;
}
if (resultRelational.equals(BreatheTypeEnum.BRADYPNEA.getCode())) {
if (resultCondition.equals(ConditionTypeEnum.BREATHE_SLOW.getCode())) {
conditionFlag = brSlowFlag && conditionFlag;
}
if (resultRelational.equals(HeartRateTypeEnum.TACHYCARDIA.getCode())) {
if (resultCondition.equals(ConditionTypeEnum.HEART_FAST.getCode())) {
conditionFlag = hrFastFlag && conditionFlag;
}
if (resultRelational.equals(HeartRateTypeEnum.BRADYCARDIA.getCode())) {
if (resultCondition.equals(ConditionTypeEnum.HEART_SLOW.getCode())) {
conditionFlag = hrSlowFlag && conditionFlag;
}
}
......@@ -434,8 +444,12 @@ public class PlatElderBreatheAnalysisServiceImpl extends ServiceImpl<PlatElderBr
platElderBreatheAnalysis.setTenantId(platElder.getTenantId());
platElderBreatheAnalysis.setBreatheEvaluate(diseaseReport == null ? "" : diseaseReport.getEvaluate());
platElderBreatheAnalysisService.save(platElderBreatheAnalysis);
// platElderBreatheAnalysis.setRemake(String.format("normalFlag:%s,hrFastFlag:%s,brStopFlag:%s,brFastFlag:%s,brSlowFlag:%s,hrSlowFlag:%s",
// normalFlag, hrFastFlag, brStopFlag, brFastFlag, brSlowFlag, hrSlowFlag));
result.add(platElderBreatheAnalysis);
}
return result;
}
......
......@@ -258,7 +258,6 @@ public class PlatElderDayReportDayServiceImpl implements PlatElderDayReportDaySe
@Override
public List<PlatElderRealTimeHeartRespiratoryVO> heartRespiratory(PlatElderReportDTO platElderIdDTO) {
PlatDevice platDevice = platElderRealTimeService.getBreathDevice(platElderIdDTO.getElderId(), platElderIdDTO.getDeviceId());
if (platDevice == null) {
......
......@@ -9,6 +9,7 @@ import com.makeit.entity.platform.elder.*;
import com.makeit.enums.platform.alarm.PlatAlarmConfigEnum;
import com.makeit.enums.report.SleepTypeEnum;
import com.makeit.module.iot.vo.analysis.EvaluateReportVO;
import com.makeit.service.platform.device.PlatDeviceService;
import com.makeit.service.platform.elder.*;
import com.makeit.service.saas.SaasDiseaseReportService;
import com.makeit.service.saas.SaasElderReportConfigService;
......@@ -71,6 +72,8 @@ public class PlatElderDayReportWeekServiceImpl implements PlatElderDayReportWeek
private PlatElderSleepAnalysisService platElderSleepAnalysisService;
@Autowired
private PlatElderService platElderService;
@Autowired
private PlatDeviceService platDeviceService;
private LocalDateTime weekStartDateTime(LocalDateTime defaultTime) {
return weekStartDateTime(LocalDate.now().minusDays(1), defaultTime);
......@@ -408,7 +411,14 @@ public class PlatElderDayReportWeekServiceImpl implements PlatElderDayReportWeek
PlatDevice platDevice = platElderRealTimeService.getBreathDevice(platElderIdDTO.getElderId(), platElderIdDTO.getDeviceId());
if (platDevice != null) {
deviceId = platDevice.getId();
if (StringUtils.isNotEmpty(platElderIdDTO.getTenantId()) && !platDevice.getTenantId().equals(platElderIdDTO.getTenantId())) {
platDevice = platDeviceService.getOne(new QueryWrapper<PlatDevice>().lambda()
.eq(BaseBusEntity::getTenantId,platElderIdDTO.getTenantId())
.eq(PlatDevice::getOriDeviceId, platElderIdDTO.getDeviceId()).last("limit 1"));
deviceId = platDevice.getId();
} else {
deviceId = platDevice.getId();
}
//oriDeviceId = platDevice.getOriDeviceId();
}
......
......@@ -103,6 +103,11 @@ public class PlatElderRealTimeServiceImpl implements PlatElderRealTimeService {
if (StringUtils.isNotBlank(deviceId)) {
platDevice = platDeviceService.getById(deviceId);
if (platDevice == null) {
platDevice = platDeviceService.getOne(new QueryWrapper<PlatDevice>().lambda()
.eq(PlatDevice::getOriDeviceId, deviceId).last("limit 1"));
}
}
return platDevice;
......
......@@ -2,6 +2,7 @@ package com.makeit.service.platform.elder.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.makeit.common.entity.BaseBusEntity;
import com.makeit.dto.platform.elder.PlatElderReportDTO;
import com.makeit.entity.platform.elder.PlatElderReportMonth;
import com.makeit.mapper.platform.elder.PlatElderReportMonthMapper;
......@@ -94,9 +95,10 @@ public class PlatElderReportMonthServiceImpl extends ServiceImpl<PlatElderReport
List<PlatElderReportMonth> monthList = list(new QueryWrapper<PlatElderReportMonth>().lambda()
.eq(StringUtils.isNotBlank(platElderIdDTO.getElderId()), PlatElderReportMonth::getElderId, platElderIdDTO.getElderId())
.eq(StringUtils.isNotBlank(platElderIdDTO.getDeviceId()), PlatElderReportMonth::getBreatheDeviceId, platElderIdDTO.getDeviceId())
.eq(StringUtils.isNotBlank(platElderIdDTO.getDeviceId()), PlatElderReportMonth::getBreatheOriDeviceId, platElderIdDTO.getDeviceId())
.ge(PlatElderReportMonth::getDay, start)
.le(PlatElderReportMonth::getDay, end)
.eq(StringUtils.isNotEmpty(platElderIdDTO.getTenantId()), BaseBusEntity::getTenantId,platElderIdDTO.getTenantId())
.orderByAsc(PlatElderReportMonth::getDay)
);
......
......@@ -15,6 +15,7 @@ import com.makeit.entity.saas.analysis.SaasSleepAnalysisModel;
import com.makeit.entity.saas.analysis.SaasSleepEvaluateStandardReport;
import com.makeit.enums.report.ElderSleepType;
import com.makeit.enums.report.SleepTypeEnum;
import com.makeit.global.aspect.tenant.TenantIdIgnore;
import com.makeit.mapper.platform.elder.PlatElderSleepMapper;
import com.makeit.module.iot.service.IotProductDeviceService;
import com.makeit.module.iot.vo.DeviceOperationLogEntity;
......@@ -85,6 +86,7 @@ public class PlatElderSleepServiceImpl extends ServiceImpl<PlatElderSleepMapper,
@Override
@Transactional(rollbackFor = Exception.class)
@TenantIdIgnore
public void elderSleepSleepAnalysisTask() {
List<String> dayHourRangeList = getLastDayHourRange();
......@@ -305,6 +307,7 @@ public class PlatElderSleepServiceImpl extends ServiceImpl<PlatElderSleepMapper,
startSleepTime = entry.getKey();
}
sleepMinute++;
continue;
}
if (StringUtils.isEmpty(startSleepTime) && sleepMinute == 0) {
continue;
......@@ -635,8 +638,6 @@ public class PlatElderSleepServiceImpl extends ServiceImpl<PlatElderSleepMapper,
}
}
// 根据睡眠报告评估标准算出不同睡眠类型的得分
sleepTime = sleepTime - soberTime;
long deepScore = 0;
for (int i = 0; i < sleepDeepConfigList.size(); i++) {
long hour = deepTime / 60;
......@@ -706,11 +707,8 @@ public class PlatElderSleepServiceImpl extends ServiceImpl<PlatElderSleepMapper,
dayRestTime += elderSleep.getInterval();
}
}
// TODO 起床时间和入睡时间
platElderSleepService.saveBatch(elderSleepList);
EvaluateReportVO elderReport = saasElderReportConfigService.getByScore(totalScore);
// 长者一天的睡眠分析
PlatElderSleepAnalysis elderSleepAnalysis = new PlatElderSleepAnalysis();
elderSleepAnalysis.setElderId(elder.getId());
......@@ -722,7 +720,7 @@ public class PlatElderSleepServiceImpl extends ServiceImpl<PlatElderSleepMapper,
elderSleepAnalysis.setRestTime(String.valueOf(dayRestTime));
elderSleepAnalysis.setSleepResult(sleepReport.getResult());
elderSleepAnalysis.setTenantId(tenantId);
elderSleepAnalysis.setSleepEvaluate(elderReport == null ? "" : elderReport.getEvaluate());
elderSleepAnalysis.setSleepEvaluate(sleepReport.getEvaluate());
platElderSleepAnalysisService.save(elderSleepAnalysis);
}
......
......@@ -96,4 +96,6 @@ public interface PlatSpaceService extends IService<PlatSpace> {
List<PlatSpace> listChildAndOrgIds(List<String> spaceIds, List<String> orgIds);
void fixPlacePath(String spaceId);
}
......@@ -43,6 +43,7 @@ import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.multipart.MultipartFile;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.regex.Matcher;
......@@ -68,6 +69,11 @@ public class PlatSpaceServiceImpl extends ServiceImpl<PlatSpaceMapper, PlatSpace
private PlatElderService platElderService;
private void check(PlatSpaceAddDTO dto) {
if (StrUtil.isNotBlank(dto.getParentPath())
&& dto.getParentPath().split(",").length > 4) {
throw new BusinessException(CodeMessageEnum.PLATFORM_ERROR_SPACE_OVER_LEVEL);
}
LambdaQueryWrapper<PlatSpace> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(PlatSpace::getName, dto.getName());
queryWrapper.ne(StringUtil.isNotEmpty(dto.getId()), PlatSpace::getId, dto.getId());
......@@ -148,8 +154,7 @@ public class PlatSpaceServiceImpl extends ServiceImpl<PlatSpaceMapper, PlatSpace
if (parentSpace!=null && parentSpace.getParentPath()!=null && parentSpace.getParentPath().contains(dto.getId())) {
throw new BusinessException(CodeMessageEnum.PLATFORM_ERROR_SPACE_NOT_AUTH_PARENT);
}
// todo 编辑后层级大于4,不允许编辑 脏数据太多,待校验
// checkAndUpdateSonSpace(space);
checkAndUpdateSonSpace(space);
this.updateById(space);
List<String> lastSpaceIds = recursionLastSpaceIds(space.getId(), new ArrayList<>());
if (CollUtil.isEmpty(lastSpaceIds)) {
......@@ -219,8 +224,8 @@ public class PlatSpaceServiceImpl extends ServiceImpl<PlatSpaceMapper, PlatSpace
private void checkAndUpdateSonSpace(PlatSpace space) {
String parentPath = space.getParentPath();
int level = StrUtil.isBlank(parentPath) ? 0 : parentPath.split(",").length;
if (level > 3) {
int level = StrUtil.isBlank(parentPath) ? 1 : parentPath.split(",").length + 1;
if (level > 4) {
throw new BusinessException(CodeMessageEnum.PLATFORM_ERROR_SPACE_OVER_LEVEL);
}
String spaceId = space.getId();
......@@ -228,19 +233,19 @@ public class PlatSpaceServiceImpl extends ServiceImpl<PlatSpaceMapper, PlatSpace
.apply(StringUtils.isNotBlank(spaceId), "find_in_set('" + spaceId + "',parent_path)"));
int sonLevel = 0;
if (CollUtil.isNotEmpty(platSpaceList)) {
final int[] maxLength = {1};
AtomicInteger maxLength = new AtomicInteger(1);
platSpaceList.forEach(s -> {
if (StrUtil.isBlank(s.getParentPath())) {
return;
}
String[] parentSpaceIds = s.getParentPath().split(",");
if (parentSpaceIds.length > maxLength[0]) {
maxLength[0] = parentSpaceIds.length;
int maxSpacePath = getMaxSpacePath(s.getParentPath(), spaceId);
if (maxSpacePath > maxLength.get()) {
maxLength.set(maxSpacePath);
}
});
sonLevel = maxLength[0];
sonLevel = maxLength.get();
}
if (level + sonLevel > 3) {
if (level + sonLevel > 4) {
throw new BusinessException(CodeMessageEnum.PLATFORM_ERROR_SPACE_OVER_LEVEL);
}
// 更新下级空间的parentPath
......@@ -261,6 +266,12 @@ public class PlatSpaceServiceImpl extends ServiceImpl<PlatSpaceMapper, PlatSpace
}
private Integer getMaxSpacePath(String path, String splitSpace) {
List<String> pathList = Arrays.asList(path.split(","));
return pathList.size() - pathList.indexOf(splitSpace);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void del(String id) {
......@@ -1086,7 +1097,47 @@ public class PlatSpaceServiceImpl extends ServiceImpl<PlatSpaceMapper, PlatSpace
return data;
}
@Override
public void fixPlacePath(String spaceId) {
PlatSpace space = getById(spaceId);
if (space == null || StrUtil.isNotBlank(space.getParentId())) {
return;
}
List<PlatSpace> allList = new ArrayList<>();
recursionSetParentPath(spaceId, space.getParentPath(), allList);
if (CollUtil.isNotEmpty(allList)) {
updateBatchById(allList);
}
// fixAllSpacePath();
}
private void fixAllSpacePath() {
List<PlatSpace> firstSpaceList = list(Wrappers.<PlatSpace>lambdaQuery().isNull(PlatSpace::getParentPath)
.isNull(PlatSpace::getParentId));
if (CollUtil.isEmpty(firstSpaceList)) {
return;
}
firstSpaceList.forEach(f -> {
List<PlatSpace> allList = new ArrayList<>();
recursionSetParentPath(f.getId(), f.getParentPath(), allList);
if (CollUtil.isNotEmpty(allList)) {
updateBatchById(allList);
}
});
}
private void recursionSetParentPath(String spaceId, String parentPath, List<PlatSpace> allList) {
List<PlatSpace> firstSonList = list(Wrappers.<PlatSpace>lambdaQuery().eq(PlatSpace::getParentId, spaceId));
if (CollUtil.isEmpty(firstSonList)) {
return;
}
firstSonList.forEach(s -> {
s.setParentPath(StrUtil.isNotBlank(parentPath) ? parentPath + "," + s.getParentId() : spaceId);
allList.add(s);
recursionSetParentPath(s.getId(), s.getParentPath(), allList);
});
}
}
......@@ -24,4 +24,7 @@ public interface PlatLogoConfigService extends IService<PlatLogoConfig> {
* @return
*/
PlatLogoConfigDTOVO view(PlatLogoConfigQueryDTO dto);
void updateByTenantId(String tenantId, String code);
}
package com.makeit.service.platform.sys.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.makeit.dto.platform.sys.PlatLogoConfigDTO;
import com.makeit.dto.platform.sys.PlatLogoConfigDTOVO;
......@@ -66,4 +67,13 @@ public class PlatLogoConfigServiceImpl extends ServiceImpl<PlatLogoConfigMapper,
return data;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateByTenantId(String tenantId, String code) {
LambdaUpdateWrapper<PlatLogoConfig> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.set(PlatLogoConfig::getCode, code).eq(PlatLogoConfig::getTenantId, tenantId);
update(updateWrapper);
}
}
package com.makeit.service.saas.impl;
import cn.binarywang.wx.miniapp.api.WxMaService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
......@@ -9,7 +8,6 @@ import com.makeit.common.entity.BaseBusEntity;
import com.makeit.common.entity.BaseEntity;
import com.makeit.common.page.PageReqDTO;
import com.makeit.common.page.PageVO;
import com.makeit.config.WxMaConfiguration;
import com.makeit.dto.platform.sys.PlatLogoConfigDTO;
import com.makeit.entity.platform.auth.PlatOrg;
import com.makeit.entity.platform.auth.PlatUser;
......@@ -321,6 +319,8 @@ public class PlatTenantServiceImpl extends ServiceImpl<PlatTenantMapper, PlatTen
//更新组织表
platOrgService.edit(platOrg);
platLogoConfigService.updateByTenantId(tntTenant.getId(), dto.getCode());
//分配菜单 todo 慢
assignMenuList(tntTenant.getId(), dto.getMenuIdList());
......
......@@ -51,7 +51,7 @@ public class PlatElderReportTask {
@TenantIdIgnore
public void elderHeartRespiratoryAnalysisTask() {
log.info("开始定时分析长者呼吸心率");
platElderBreatheAnalysisService.elderHeartRespiratoryAnalysisTask();
platElderBreatheAnalysisService.elderHeartRespiratoryAnalysisTask(null,null);
log.info("定时分析长者呼吸心率结束");
}
......
package com.makeit.utils;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.makeit.entity.platform.device.PlatDevice;
import com.makeit.entity.saas.PlatTenant;
......@@ -57,6 +58,15 @@ public class DeviceCacheUtil implements ApplicationRunner {
}
return RedisUtil.get(RedisConst.PLAT_IOT_DEVICE_PREFIX + oriDeviceIdAndIotOrgId);
}
public List<PlatDevice> getByDeviceId(String oriDeviceId) {
List<PlatDevice> platDevice = RedisUtil.getLike(RedisConst.PLAT_IOT_DEVICE_PREFIX + oriDeviceId);
if (CollUtil.isEmpty(platDevice)) {
getAll();
}
return RedisUtil.getLike(RedisConst.PLAT_IOT_DEVICE_PREFIX + oriDeviceId);
}
public void putAll(Collection<PlatDevice> platDeviceList) {
platDeviceList.forEach(vo -> {
put(vo);
......
......@@ -90,9 +90,16 @@ public class PlatDeviceListVO extends BaseTenantDTO {
private String spaceName;
private String roomId;
private String roomName;
private String bedId;
private String bedName;
private String elderName;
@ApiModelProperty(value = "许可证")
private String deviceLicense;
......
......@@ -21,4 +21,6 @@
and pehi.respiratory_exception_time != '' and pehi.respiratory_rate != '')
)
</select>
</mapper>
......@@ -60,6 +60,71 @@
order by pd.update_date desc,pd.id desc
</select>
<select id="getDeviceIdsBySpaceIdAndElder" resultType="com.makeit.vo.platform.device.PlatDeviceListVO">
select
pd.*,
ps.parent_path as spaceParentPath,
ps.name as spaceName,
pr.name as roomName,
pb.name as bedName,
pr.id as roomId,
pb.id as bedId
from plat_device pd
left join plat_room_bed_device prbd on (pd.id = prbd.device_id and prbd.del_flag = '0')
left join plat_room pr on (pr.id = prbd.room_id and pr.del_flag = '0' )
left join plat_bed pb on ( pb.id = prbd.bed_id and pb.del_flag = '0')
left join plat_space ps on (ps.id = pr.space_id and ps.del_flag = '0')
left join plat_elder pe on (pe.room_id = pr.id and pe.del_flag = '0')
<where>
pd.del_flag = '0'
<if test="param.spaceId != null and param.spaceId != ''">
and ( FIND_IN_SET(#{param.spaceId},ps.parent_path) or ps.id = #{param.spaceId})
</if>
<if test="param.oriDeviceId != null and param.oriDeviceId != ''">
and pd.ori_device_id like concat('%',#{param.oriDeviceId},'%')
</if>
<if test="param.name != null and param.name != ''">
and pd.name like concat('%',#{param.name},'%')
</if>
<if test="param.status != null and param.status != '' ">
and pd.status = #{param.status}
</if>
<if test="param.productName != null and param.productName != '' ">
and pd.product_name like concat('%',#{param.productName},'%')
</if>
<if test="param.productId != null and param.productId != '' ">
and pd.product_id = #{param.productId}
</if>
<if test="param.orgId != null and param.orgId != '' ">
and pd.org_id = #{param.orgId}
</if>
<if test="param.tenantId != null and param.tenantId != ''">
and pd.tenant_id = #{param.tenantId}
</if>
<if test="param.active !=null and param.active == 1">
and pd.device_license is not null
</if>
<if test="param.active !=null and param.active == 0">
and pd.device_license is null
</if>
<if test="param.elderId !=null and param.elderId != ''">
and (pe.id = #{param.elderId} and
((pd.category != '0' and prbd.bed_id is null and prbd.room_id = pe.room_id) -- 空间、跌倒 关联房间
or
(pd.category = '0' and prbd.bed_id is not null and prbd.bed_id = pe.bed_id))) -- 呼吸 关联床位
</if>
<if test="param.orgIds != null and param.orgIds.size() > 0 ">
AND pd.org_id in
<foreach collection="param.orgIds" item="item" separator="," open="(" close=")" index="">
#{item}
</foreach>
</if>
</where>
group by pd.id
order by pd.update_date desc,pd.id desc
</select>
<select id="getDevices" resultType="com.makeit.vo.platform.device.PlatDeviceListVO">
select
distinct
......
package com.makeit.mqtt;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.makeit.common.entity.BaseEntity;
import com.makeit.dto.platform.alarm.PlatAlarmCheckDTO;
import com.makeit.entity.platform.alarm.PlatAlarmConfig;
import com.makeit.entity.platform.device.PlatDevice;
import com.makeit.entity.saas.PlatTenant;
import com.makeit.entity.saas.analysis.SaasSleepAnalysisModel;
import com.makeit.enums.platform.alarm.PlatAlarmConfigEnum;
import com.makeit.enums.redis.RedisConst;
import com.makeit.external.strategy.OpenApiBaseStrategy;
import com.makeit.external.strategy.OpenApiBaseStrategyFactory;
import com.makeit.global.aspect.tenant.TenantIdIgnore;
import com.makeit.module.iot.enums.DeviceState;
import com.makeit.module.iot.vo.DeviceInfo;
......@@ -15,12 +23,12 @@ import com.makeit.module.iot.vo.HeaderInfo;
import com.makeit.service.platform.alarm.PlatAlarmConfigService;
import com.makeit.service.platform.alarm.alarmStrategy.IAlarm;
import com.makeit.service.platform.device.PlatDeviceService;
import com.makeit.service.saas.PlatTenantService;
import com.makeit.service.saas.SaasSleepAnalysisModelService;
import com.makeit.utils.AlarmConfigCacheUtil;
import com.makeit.utils.DeviceCacheUtil;
import com.makeit.utils.redis.RedisUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
......@@ -31,7 +39,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
import javax.annotation.Resource;
import java.math.BigDecimal;
......@@ -64,6 +71,8 @@ public class PushCallback implements MqttCallback {
public static final String WRITE_PROPERTY_REPLY = "WRITE_PROPERTY_REPLY";
public static final String OPEN_API_KEY_COUNT = "open:api:key:count";
@Autowired
private MqttConfig mqttConfig;
......@@ -84,7 +93,10 @@ public class PushCallback implements MqttCallback {
private SaasSleepAnalysisModelService saasSleepAnalysisModelService;
@Resource
private PlatAlarmConfigService alarmConfigService;
@Autowired
private OpenApiBaseStrategyFactory openApiBaseStrategyFactory;
@Autowired
private PlatTenantService platTenantService;
@Override
public void connectionLost(Throwable cause) {
......@@ -99,12 +111,10 @@ public class PushCallback implements MqttCallback {
// 收到消息并设置返回字符串格式
String payload = new String(message.getPayload(), "UTF-8");
// logger.info("接收消息主题:{}, 接收消息QoS:{}", topic, message.getQos());
logger.info("接收消息内容:payload格式:{}", payload);
// 解析数据
DeviceInfo device = JSON.parseObject(payload, DeviceInfo.class);
// todo
syncProperties(device);
......@@ -184,7 +194,7 @@ public class PushCallback implements MqttCallback {
String deviceId = device.getDeviceId();
String messageType = device.getMessageType();
//更新设备状态
boolean statusFlag = platDeviceService.updateDeviceStatus(messageType, deviceId, "");
platDeviceService.updateDeviceStatus(messageType, deviceId, "");
if (org.apache.commons.lang3.StringUtils.equalsAnyIgnoreCase(messageType, DeviceState.online.getValue())) {
return;
}
......@@ -193,6 +203,9 @@ public class PushCallback implements MqttCallback {
String iot_tenantId = binding.getId();
JSONObject properties = device.getProperties();
// 设备上报到第三方,一分钟一次
reportBrData(device, iot_tenantId);
//iot设备id
PlatDevice platDevice = deviceCacheUtil.get(deviceId + ":" + iot_tenantId);
if (platDevice == null) {
......@@ -205,9 +218,14 @@ public class PushCallback implements MqttCallback {
logger.error("该设备没有告警配置,设备iot-id,iot_tenantId:" + deviceId+","+iot_tenantId);
return;
}
handleOffBed(platDevice,properties,messageType);
for (PlatAlarmConfig config : deviceAlarmConfigList) {
String alarmType = config.getAlarmType();
if (PlatAlarmConfigEnum.AlarmTypeEnum.OFF_BED.getValue().equals(alarmType)) {
continue;
}
for (IAlarm alarm : alarmList) {
if (alarm.support(alarmType)) {
//防止呼吸心率的数据交叉
......@@ -224,6 +242,7 @@ public class PushCallback implements MqttCallback {
}
}
}
}catch (Exception e){
logger.error("告警异常pushCallback:",e);
}
......@@ -232,6 +251,75 @@ public class PushCallback implements MqttCallback {
}
/**
* 离床预警
* @param platDevice
* @param properties
* @param messageType
*/
private void handleOffBed(PlatDevice platDevice, JSONObject properties, String messageType) {
List<PlatDevice> platDeviceList = deviceCacheUtil.getByDeviceId(platDevice.getOriDeviceId());
if (CollUtil.isEmpty(platDeviceList)) {
return;
}
String alarmType = PlatAlarmConfigEnum.AlarmTypeEnum.OFF_BED.getValue();
List<String> type = Lists.newArrayList("OFFLINE", "DISCONNECT");
platDeviceList.forEach(device -> {
if (StrUtil.isBlank(messageType) || type.contains(messageType)
|| DeviceState.offline.getValue().equals(device.getStatus())) {
logger.warn("离线清除离床预警缓存!");
RedisUtil.delete(RedisConst.ALARM_DEVICE_OFF_BED_ID + device.getId());
}
for (IAlarm alarm : alarmList) {
if (alarm.support(alarmType)) {
PlatAlarmConfig config = alarmConfigCacheUtil.get(device.getOrgId(), alarmType);
if (config == null) {
continue;
}
//防止呼吸心率的数据交叉
PlatAlarmCheckDTO platAlarmCheckDTO = new PlatAlarmCheckDTO();
//告警配置
platAlarmCheckDTO.setPlatAlarmConfig(config);
//设备信息
platAlarmCheckDTO.setPlatDevice(device);
//iot上报数据
platAlarmCheckDTO.setProperties(properties);
//设备状态
platAlarmCheckDTO.setMessageType(messageType);
alarm.checkConfig(platAlarmCheckDTO);
}
}
});
}
private void reportBrData(DeviceInfo device,String iot_tenantId) {
HeaderInfo headers = device.getHeaders();
String deviceId = device.getDeviceId();
JSONObject properties = device.getProperties();
if (REPORT_PROPERTY.equals(device.getMessageType()) && headers.getProductName().contains("呼吸")) {
Long increment = redisTemplate.opsForValue().increment(OPEN_API_KEY_COUNT + deviceId + ":" + iot_tenantId,1);
if (increment != null && increment == 60) {
redisTemplate.delete(OPEN_API_KEY_COUNT + deviceId + ":" + iot_tenantId);
PlatTenant platTenant = platTenantService.getOne(new QueryWrapper<PlatTenant>()
.lambda().eq(PlatTenant::getIotOrgId,iot_tenantId));
if (platTenant != null) {
OpenApiBaseStrategy strategyFactoryHandler = openApiBaseStrategyFactory.getHandler(platTenant.getCode());
if (strategyFactoryHandler != null) {
try {
strategyFactoryHandler.report(platTenant, deviceId, properties);
} catch (Exception e) {
logger.error("调用呼吸设备上报数据接口失败:{}",e.getMessage(),e);
}
}
}
}
}
}
private void cacheSpaceFallDeviceData(String deviceSpaceTempData, DeviceInfo device, long currentSecond) {
long maxSize = 10L;
String key = deviceSpaceTempData + device.getDeviceId();
......
......@@ -37,7 +37,7 @@
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${logback.logdir}/${logback.appname}/logging/logging.%d{yyyy-MM-dd}.%i.log
</FileNamePattern>
<maxHistory>30</maxHistory>
<maxHistory>10</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>20MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
......
package com.makeit.iotapi;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.makeit.dto.platform.alarm.PlatAlarmCheckDTO;
import com.makeit.entity.platform.device.PlatDevice;
import com.makeit.module.admin.vo.plat.PlatTenantVO;
import com.makeit.module.iot.service.IotOrgService;
import com.makeit.module.iot.service.IotProductDeviceService;
import com.makeit.module.iot.service.IotTokenService;
import com.makeit.service.platform.alarm.alarmStrategy.OffBedAlarm;
import com.makeit.utils.redis.RedisUtil;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
@SpringBootTest
public class IotDeviceInfoContentFall {
......@@ -17,6 +25,8 @@ public class IotDeviceInfoContentFall {
private IotOrgService iotOrgService;
@Autowired
private IotProductDeviceService iotProductDeviceService;
@Autowired
private OffBedAlarm offBedAlarm;
@Test
......@@ -76,4 +86,32 @@ public class IotDeviceInfoContentFall {
void updateIotOrgInfo() {
iotOrgService.updateIotOrgInfo("1698964909267415040", "lxl2234");
}
@Test
void offBedAlarm() {
PlatAlarmCheckDTO platAlarmCheckDTO = new PlatAlarmCheckDTO();
PlatDevice platDevice = new PlatDevice();
platDevice.setOrgId("1712384736845950978");
platDevice.setId("1732609639364812811");
platAlarmCheckDTO.setPlatDevice(platDevice);
JSONObject properties = JSON.parseObject("{\n" +
" \"person\": 0,\n" +
" \"personState\": 0,\n" +
" \"distance\": 50,\n" +
" \"hr\": 80,\n" +
" \"br\": 20,\n" +
" \"bodymove\": 50,\n}");
platAlarmCheckDTO.setProperties(properties);
offBedAlarm.checkConfig(platAlarmCheckDTO);
}
@Test
void getRedis() {
// iot-plafform:plat:iot:device:1712376790484275200:1701420402262994944
// iot-plafform:plat:iot:device:1712377046877884416:1703950733042053120
List<PlatDevice> list = RedisUtil.getLike("plat:iot:device:" + "1712377046877884416");
System.out.println(list);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment