Commit bd12c285 by 罗志长

Merge branch 'dev'

parents 39dc5c78 14be8b10
......@@ -109,11 +109,11 @@ public enum CodeMessageEnum {
PLATFORM_ERROR_SPACE_OVER_LEVEL(500, "PLATFORM.ERROR.SPACE.OVER.LEVEL"),
PLATFORM_ERROR_SPACE_USER_NOT_ADD(500, "PLATFORM.ERROR.SPACE.USER.NOT.ADD"),
PLATFORM_ERROR_SPACE_ROOM_NOT_ADD(500, "PLATFORM.ERROR.SPACE.ROOM.NOT.ADD"),
PLATFORM_ERROR_ROOM_EXIT_BAD(500, "PLATFORM.ERROR.ROOM.EXIT.BED"),
PLATFORM_ERROR_ROOM_BAD_NUMBER_NOT_AUTH(500, "PLATFORM.ERROR.ROOM.BED.NUMBER.NOT.AUTH"),
PLATFORM_ERROR_ROOM_NAME_EXIT(500, "PLATFORM.ERROR.ROOM.NAME.EXIT"),
PLATFORM_ERROR_BAD_NAME_EXIT(500, "PLATFORM.ERROR.BED.NAME.EXIT"),
PLATFORM_ERROR_BAD_NOT_DEL(500, "PLATFORM.ERROR.BED.NOT.DEL"),
PLATFORM_ERROR_ROOM_EXIT_BAD(555, "PLATFORM.ERROR.ROOM.EXIT.BED"),
PLATFORM_ERROR_ROOM_BAD_NUMBER_NOT_AUTH(555, "PLATFORM.ERROR.ROOM.BED.NUMBER.NOT.AUTH"),
PLATFORM_ERROR_ROOM_NAME_EXIT(555, "PLATFORM.ERROR.ROOM.NAME.EXIT"),
PLATFORM_ERROR_BAD_NAME_EXIT(555, "PLATFORM.ERROR.BED.NAME.EXIT"),
PLATFORM_ERROR_BAD_NOT_DEL(555, "PLATFORM.ERROR.BED.NOT.DEL"),
PLATFORM_ERROR_BED_NOT_BIND_ELDER(500,"PLATFORM.ERROR.BED.NOT.BIND.ELDER"),
PLATFORM_ERROR_ROOM_OTHER_USED_NOT_DEL(500, "PLATFORM.ERROR.ROOM.OTHER.USED.NOT.DEL"),
PLATFORM_ERROR_BED_BIND_DEVICE_NOT_AUTH(500, "PLATFORM.ERROR.BED.BIND.DEVICE.NOT.AUTH"),
......
......@@ -101,6 +101,8 @@ public class RedisConst {
public static final String ALARM_CONFIG_ORG_ID = "alarm:config:org:id:";
public static final String PLAT_IOT_DEVICE_PREFIX = "plat:iot:device:";
public static final String PLAT_OWN_IOT_DEVICE_ID = "plat:own:iot:device:id:";
public static final String ELDER_DAY_DURATION_PREFIX = "plat:day:duration:device:";
public static final String LOCK_ALARM = "lock:alarm:device:id:";
......
......@@ -285,7 +285,7 @@ public class GlobalExceptionHandler {
logger.error("业务异常{}\n{}\n{}", ExceptionResponseUtil.prefix(b), LocaleUtil.getMessage(b.getMessage()), ExceptionPrintUtil.getStackTraceByPn(b, PackageConst.TOP));
return ApiResponseUtils.fail(b.getCode(), ExceptionResponseUtil.prefix(b) + LocaleUtil.getMessage(b.getMessage()), ExceptionResponseUtil.body(b));
return ApiResponseUtils.fail(b.getCode(), LocaleUtil.getMessage(b.getMessage()), ExceptionResponseUtil.body(b));
}
// private ApiResponseEntity<Object> getApiResponse(GlobalException b, String message) {
......
......@@ -80,6 +80,15 @@ public class RedisUtil {
return lock;
}
public static boolean tryLock(String key, long waitTime, long leaseTime, TimeUnit unit) {
RLock lock = client.getLock(getProjectName() + RedisUtil.LOCK + key);
try {
return lock.tryLock(waitTime, leaseTime, unit);
} catch (InterruptedException e) {
return false;
}
}
/**
* 关闭锁
*/
......@@ -87,6 +96,13 @@ public class RedisUtil {
lock.unlock();
}
public static void unlock(String key) {
RLock lock = client.getLock(getProjectName() + RedisUtil.LOCK + key);
if (lock.isHeldByCurrentThread()) {
unlock(lock);
}
}
public static void lock(String key, long expire, Runnable runnable) {
RLock lock = lock(key, expire);
try {
......
package com.makeit.module.controller.wechat.device;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.makeit.common.dto.BaseIdDTO;
import com.makeit.common.page.PageReqDTO;
......@@ -14,6 +15,7 @@ import com.makeit.dto.wechat.device.PlatDeviceNetAttrWechatDTO;
import com.makeit.dto.wechat.device.PlatDeviceSetupDTO;
import com.makeit.entity.platform.auth.PlatOrg;
import com.makeit.entity.platform.auth.PlatRole;
import com.makeit.entity.platform.device.PlatDevice;
import com.makeit.enums.HeaderConst;
import com.makeit.global.annotation.AuthIgnore;
import com.makeit.module.iot.vo.DeviceProperties;
......@@ -29,10 +31,7 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
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;
import java.util.stream.Collectors;
......@@ -80,6 +79,15 @@ public class PlatDeviceWechatController {
return ApiResponseUtils.success(platDeviceService.viewByDeviceId(baseIdDTO.getId()));
}
@ApiOperation("配网前校验")
@PostMapping("setUpCheck")
public ApiResponseEntity<?> setUpCheck(@RequestBody BaseIdDTO baseIdDTO) {
PlatDevice platDevice = platDeviceService.getOne(new QueryWrapper<PlatDevice>().lambda()
.eq(PlatDevice::getOriDeviceId, baseIdDTO.getId())
.last("limit 1"));
return ApiResponseUtils.success(platDevice != null);
}
@ApiOperation("配网")
@PostMapping("setUp")
public ApiResponseEntity<?> setup(@Validated @RequestBody PlatDeviceSetupDTO dto) {
......
......@@ -22,6 +22,7 @@ import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
@Service
......@@ -42,6 +43,9 @@ public class HuiNengStrategy implements OpenApiBaseStrategy {
if (platDevice == null) {
return;
}
if (!isSupportAlarm(platTenant, platDevice)) {
return;
}
if (StringUtils.isEmpty(platTenant.getUrl())) {
log.info("当前租户为配置openapi地址");
return;
......@@ -97,6 +101,15 @@ public class HuiNengStrategy implements OpenApiBaseStrategy {
log.info("接口:{},返回信息:{}", url, JSON.toJSONString(responseMessage));
}
private boolean isSupportAlarm(PlatTenant platTenant, PlatDevice platDevice) {
String reportOrgIds = platTenant.getReportOrgIds();
if (StringUtils.isBlank(reportOrgIds)) {
return false;
}
List<String> orgIds = Arrays.asList(StringUtils.split(reportOrgIds, ","));
return orgIds.contains(platDevice.getOrgId());
}
@Override
@TenantIdIgnore
public void alarm(PlatTenant platTenant, String deviceId, JSONObject jsonObject) {
......
......@@ -135,7 +135,7 @@ public class FallAlarm implements IAlarm {
PlatDevice platDevice = platAlarmCheckDTO.getPlatDevice();
PlatAlarmConfig config = alarmConfigCacheUtil.get(platDevice.getOrgId(), PlatAlarmConfigEnum.AlarmTypeEnum.BEHAVIOR.getValue());
if (config == null ||StringUtils.isBlank(config.getRuleConfig())) {
log.error("行为告警配置未配置,告警配置id:" + config.getId());
log.error("行为告警配置未配置,orgId:" + platDevice.getOrgId());
return;
}
String ruleConfigStr = config.getRuleConfig();
......
......@@ -239,7 +239,7 @@ public class PlatElderBreatheAnalysisServiceImpl extends ServiceImpl<PlatElderBr
existBrFast.set(false);
existBrStop.set(false);
existBrSlow.set(false);
log.info("呼吸正常:{},min:{},max:{},的时间:{}", br, breatheThresholdMin, breatheThresholdMax, longToTime(timestamp));
// log.info("呼吸正常:{},min:{},max:{},的时间:{}", br, breatheThresholdMin, breatheThresholdMax, longToTime(timestamp));
}
// 心率过快
......@@ -279,7 +279,7 @@ public class PlatElderBreatheAnalysisServiceImpl extends ServiceImpl<PlatElderBr
existHrSlow.set(false);
hrFastSecond.set(0);
existHrFast.set(false);
log.info("心率正常:{},min:{},max:{},的时间:{}", hr, heartThresholdMin, heartThresholdMax, longToTime(timestamp));
// log.info("心率正常:{},min:{},max:{},的时间:{}", hr, heartThresholdMin, heartThresholdMax, longToTime(timestamp));
}
});
......
......@@ -265,7 +265,7 @@ public class PlatTenantServiceImpl extends ServiceImpl<PlatTenantMapper, PlatTen
tntTenant.setAppid(wxConfig.getAppId());
}
if (StringUtils.isEmpty(tntTenant.getSecret())) {
tntTenant.setSecret(wxConfig.getMpSecret());
tntTenant.setSecret(wxConfig.getAppSecret());
}
//新租户同步到iot
......
package com.makeit.task;
import com.makeit.utils.DayDurationUtil;
import com.makeit.utils.redis.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
@Component
@Slf4j
@ConditionalOnProperty(value = {"iot.sync.enable"}, havingValue = "true")
......@@ -17,6 +20,18 @@ public class DayDurationTask {
@Scheduled(cron = "0 10 * * * ?")
public void updateDayDuration() {
boolean isSuccess = false;
String key = "update:day:duration";
try {
isSuccess = RedisUtil.tryLock(key, 0, 3, TimeUnit.SECONDS);
if (isSuccess) {
dayDurationUtil.getAll();
}
} finally {
if (isSuccess) {
RedisUtil.unlock(key);
}
}
}
}
package com.makeit.task;
import com.makeit.service.platform.device.PlatDeviceService;
import com.makeit.utils.redis.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
@Component
@Slf4j
@ConditionalOnProperty(value = {"iot.sync.enable"}, havingValue = "true")
......@@ -17,14 +20,25 @@ public class IotSyncTask {
/**
* 一小时同步一次
* 一分钟同步一次
* 启用状态的租户才同步
* 新增和更新平台端设备表
*/
@Scheduled(cron = "0 0/1 * * * ?")
public void syncEquipmentInfo() {
boolean isSuccess = false;
String key = "sync:equipment:info";
try {
isSuccess = RedisUtil.tryLock(key, 0, 3, TimeUnit.SECONDS);
if (isSuccess) {
platDeviceService.savePlatDevice();
}
} finally {
if (isSuccess) {
RedisUtil.unlock(key);
}
}
}
}
......@@ -2,12 +2,15 @@ package com.makeit.task;
import com.makeit.global.aspect.tenant.TenantIdIgnore;
import com.makeit.service.platform.elder.*;
import com.makeit.utils.redis.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
@Component
@Slf4j
@ConditionalOnProperty(value = {"iot.sync.enable"}, havingValue = "true")
......@@ -29,18 +32,40 @@ public class PlatElderReportTask {
@Scheduled(cron = "0 0 1 * * ?")
@TenantIdIgnore
public void heartRespiratoryTask() {
boolean isSuccess = false;
String key = "task:heart:respiratory";
try {
isSuccess = RedisUtil.tryLock(key, 0, 3, TimeUnit.SECONDS);
if (isSuccess) {
log.info("开始生成长者每日呼吸,异常情况");
platElderBreatheDayStatService.heartRespiratoryTask();
log.info("生成长者每日呼吸,异常情况结束");
}
} finally {
if (isSuccess) {
RedisUtil.unlock(key);
}
}
}
@Scheduled(cron = "0 30 1 * * ?")
@TenantIdIgnore
public void coordinateRecordTask() {
boolean isSuccess = false;
String key = "task:coordinate:record";
try {
isSuccess = RedisUtil.tryLock(key, 0, 3, TimeUnit.SECONDS);
if (isSuccess) {
log.info("开始生成长者每日实时定位");
platElderCoordinateRecordService.coordinateRecordTask();
log.info("生成长者每日实时定位结束");
}
} finally {
if (isSuccess) {
RedisUtil.unlock(key);
}
}
}
/**
......@@ -49,10 +74,21 @@ public class PlatElderReportTask {
@Scheduled(cron = "0 0 2 * * ?")
@TenantIdIgnore
public void elderHeartRespiratoryAnalysisTask() {
boolean isSuccess = false;
String key = "task:elder:heart:respiratory:analysis";
try {
isSuccess = RedisUtil.tryLock(key, 0, 3, TimeUnit.SECONDS);
if (isSuccess) {
log.info("开始定时分析长者呼吸心率");
platElderBreatheAnalysisService.elderHeartRespiratoryAnalysisTask(null,null);
log.info("定时分析长者呼吸心率结束");
}
} finally {
if (isSuccess) {
RedisUtil.unlock(key);
}
}
}
/**
* 生成长者呼吸心率
......@@ -60,10 +96,21 @@ public class PlatElderReportTask {
@Scheduled(cron = "0 30 2 * * ?")
@TenantIdIgnore
public void breatheHeartRateRecordTask() {
boolean isSuccess = false;
String key = "task:breathe:heart:rate:record";
try {
isSuccess = RedisUtil.tryLock(key, 0, 3, TimeUnit.SECONDS);
if (isSuccess) {
log.info("开始生成长者呼吸心率");
platElderBreatheHeartRateRecordService.breatheHeartRateRecordTask();
log.info("生成长者呼吸心率结束");
}
} finally {
if (isSuccess) {
RedisUtil.unlock(key);
}
}
}
/**
* 长者睡眠分析
......@@ -71,8 +118,19 @@ public class PlatElderReportTask {
@Scheduled(cron = "0 0 8 * * ?")
@TenantIdIgnore
public void elderSleepSleepAnalysisTask() {
boolean isSuccess = false;
String key = "task:elder:sleep:analysis";
try {
isSuccess = RedisUtil.tryLock(key, 0, 3, TimeUnit.SECONDS);
if (isSuccess) {
log.info("开始定时分析长者睡眠质量");
platElderSleepService.elderSleepSleepAnalysisTask(null,null);
log.info("定时分析长者睡眠质量结束");
}
} finally {
if (isSuccess) {
RedisUtil.unlock(key);
}
}
}
}
......@@ -43,11 +43,16 @@ public class DeviceCacheUtil implements ApplicationRunner {
PlatTenant platTenant = platTenantService.getById(platDevice.getTenantId());
if(StringUtils.equals(platDevice.getStatus(),DeviceState.online.getValue())) {
RedisUtil.set(RedisConst.PLAT_IOT_DEVICE_PREFIX + platDevice.getOriDeviceId()+":"+platTenant.getIotOrgId(), platDevice);
RedisUtil.set(RedisConst.PLAT_OWN_IOT_DEVICE_ID + platDevice.getOriDeviceId(), platDevice);
}else {
String key = RedisConst.PLAT_IOT_DEVICE_PREFIX + platDevice.getOriDeviceId()+":"+platTenant.getIotOrgId();
if(RedisUtil.exist(key)){
RedisUtil.delete(RedisConst.PLAT_IOT_DEVICE_PREFIX + platDevice.getOriDeviceId()+":"+platTenant.getIotOrgId());
}
String key1 = RedisConst.PLAT_OWN_IOT_DEVICE_ID + platDevice.getOriDeviceId();
if(RedisUtil.exist(key1)){
RedisUtil.delete(key1);
}
}
}
......
......@@ -54,10 +54,12 @@ public class MqttPushClient {
client.setCallback(pushCallback);
client.connect(options);
} catch (Exception e) {
logger.error("mqtt连接失败", e);
e.printStackTrace();
}
}
} catch (Exception e) {
logger.error("mqtt连接失败", e);
e.printStackTrace();
}
}
......
......@@ -43,7 +43,6 @@ import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
......@@ -104,6 +103,7 @@ public class PushCallback implements MqttCallbackExtended {
}
@Override
@Async
public void messageArrived(String topic, MqttMessage message) {
try {
// 收到消息并设置返回字符串格式
......@@ -114,6 +114,12 @@ public class PushCallback implements MqttCallbackExtended {
// 解析数据
DeviceInfo device = JSON.parseObject(payload, DeviceInfo.class);
// 独立部署的服务过滤出平台自己的设备消息
String key = RedisConst.PLAT_OWN_IOT_DEVICE_ID + device.getDeviceId();
if (!RedisUtil.exist(key)) {
return;
}
syncProperties(device);
checkAlarm(device);
......@@ -161,10 +167,8 @@ public class PushCallback implements MqttCallbackExtended {
if (!"0".equals(success)) {
return;
}
CompletableFuture.runAsync(() -> {
platDeviceService.syncIotProperties(device.getDeviceId(), properties);
RedisUtil.delete(redisKey);
}); // 要加线程池
}
}
......@@ -174,7 +178,6 @@ public class PushCallback implements MqttCallbackExtended {
* @param device
*/
@TenantIdIgnore
@Async
public void checkAlarm(DeviceInfo device) {
HeaderInfo headers = device.getHeaders();
List<HeaderInfo.Bind> bindings = headers.getBindings();
......
......@@ -39,7 +39,7 @@
</FileNamePattern>
<maxHistory>10</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>20MB</maxFileSize>
<maxFileSize>2048MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
......
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