Commit 2cea5a750b4edcf0723c2a0302ab8b1e3dbad734

Authored by xp.Huang
2 parents 9a77f32a a8c85826

Merge branch 'ljl20220125' into 'master'

feat: 设备告警

See merge request huang/thingsboard3.3.2!41
@@ -10,6 +10,7 @@ import org.apache.commons.lang3.StringUtils; @@ -10,6 +10,7 @@ import org.apache.commons.lang3.StringUtils;
10 import org.springframework.stereotype.Service; 10 import org.springframework.stereotype.Service;
11 import org.springframework.transaction.annotation.Transactional; 11 import org.springframework.transaction.annotation.Transactional;
12 import org.thingsboard.server.common.data.DeviceProfile; 12 import org.thingsboard.server.common.data.DeviceProfile;
  13 +import org.thingsboard.server.common.data.id.DeviceId;
13 import org.thingsboard.server.common.data.id.EntityId; 14 import org.thingsboard.server.common.data.id.EntityId;
14 import org.thingsboard.server.common.data.id.TenantId; 15 import org.thingsboard.server.common.data.id.TenantId;
15 import org.thingsboard.server.common.data.security.DeviceCredentials; 16 import org.thingsboard.server.common.data.security.DeviceCredentials;
@@ -39,281 +40,286 @@ import java.util.stream.Collectors; @@ -39,281 +40,286 @@ import java.util.stream.Collectors;
39 @RequiredArgsConstructor 40 @RequiredArgsConstructor
40 @Slf4j 41 @Slf4j
41 public class YtDeviceServiceImpl extends AbstractBaseService<DeviceMapper, YtDevice> 42 public class YtDeviceServiceImpl extends AbstractBaseService<DeviceMapper, YtDevice>
42 - implements YtDeviceService { 43 + implements YtDeviceService {
43 44
44 - private final DeviceProfileDao deviceProfileDao;  
45 - private final DeviceCredentialsDao deviceCredentialsDao; 45 + private final DeviceProfileDao deviceProfileDao;
  46 + private final DeviceCredentialsDao deviceCredentialsDao;
46 47
47 - private final OrganizationMapper ytOrganizationMapper; 48 + private final OrganizationMapper ytOrganizationMapper;
48 49
49 - @Override  
50 - @Transactional  
51 - public DeviceDTO insertOrUpdate(String tenantId, DeviceDTO deviceDTO) { 50 + @Override
  51 + @Transactional
  52 + public DeviceDTO insertOrUpdate(String tenantId, DeviceDTO deviceDTO) {
52 53
53 - if (StringUtils.isBlank(deviceDTO.getId())) {  
54 - return insert(deviceDTO);  
55 - } else {  
56 - return update(tenantId, deviceDTO); 54 + if (StringUtils.isBlank(deviceDTO.getId())) {
  55 + return insert(deviceDTO);
  56 + } else {
  57 + return update(tenantId, deviceDTO);
  58 + }
57 } 59 }
58 - }  
59 60
60 - private DeviceDTO update(String tenantId, DeviceDTO deviceDTO) { 61 + private DeviceDTO update(String tenantId, DeviceDTO deviceDTO) {
61 62
62 - validateUpdate(deviceDTO); 63 + validateUpdate(deviceDTO);
63 64
64 - YtDevice device = new YtDevice();  
65 - deviceDTO.copyToEntity(  
66 - device,  
67 - ModelConstants.TablePropertyMapping.ACTIVE_TIME,  
68 - ModelConstants.TablePropertyMapping.DEVICE_STATE,  
69 - ModelConstants.TablePropertyMapping.TB_DEVICE_ID,  
70 - ModelConstants.TablePropertyMapping.TENANT_CODE,  
71 - ModelConstants.TablePropertyMapping.CREATOR,  
72 - ModelConstants.TablePropertyMapping.UPDATER,  
73 - ModelConstants.TablePropertyMapping.CREATE_TIME,  
74 - ModelConstants.TablePropertyMapping.UPDATE,  
75 - ModelConstants.TablePropertyMapping.UPDATE_TIME);  
76 - baseMapper.updateById(device);  
77 - return device.getDTO(DeviceDTO.class);  
78 - }  
79 -  
80 - private void validateUpdate(DeviceDTO deviceDTO) {  
81 - if (StringUtils.isAllBlank(deviceDTO.getName())) {  
82 - throw new YtDataValidationException("device name must be specific"); 65 + YtDevice device = new YtDevice();
  66 + deviceDTO.copyToEntity(
  67 + device,
  68 + ModelConstants.TablePropertyMapping.ACTIVE_TIME,
  69 + ModelConstants.TablePropertyMapping.DEVICE_STATE,
  70 + ModelConstants.TablePropertyMapping.TB_DEVICE_ID,
  71 + ModelConstants.TablePropertyMapping.TENANT_CODE,
  72 + ModelConstants.TablePropertyMapping.CREATOR,
  73 + ModelConstants.TablePropertyMapping.UPDATER,
  74 + ModelConstants.TablePropertyMapping.CREATE_TIME,
  75 + ModelConstants.TablePropertyMapping.UPDATE,
  76 + ModelConstants.TablePropertyMapping.UPDATE_TIME);
  77 + baseMapper.updateById(device);
  78 + return device.getDTO(DeviceDTO.class);
83 } 79 }
84 - }  
85 80
86 - private boolean detectDeviceChange(DeviceDTO deviceDTO, YtDevice device) {  
87 - boolean changed =  
88 - !deviceDTO.getName().equalsIgnoreCase(device.getName())  
89 - || !deviceDTO.getProfileId().equalsIgnoreCase(device.getProfileId());  
90 - if (changed) {  
91 - return true;  
92 - }  
93 - boolean dtoGateway =  
94 - Optional.ofNullable(deviceDTO.getDeviceType())  
95 - .map(deviceType -> deviceType.equals(DeviceTypeEnum.GATEWAY))  
96 - .orElse(false);  
97 - boolean entityGateway =  
98 - Optional.ofNullable(device.getDeviceType())  
99 - .map(deviceType -> deviceType.equals(DeviceTypeEnum.GATEWAY))  
100 - .orElse(false);  
101 - if (entityGateway != dtoGateway) {  
102 - changed = true;  
103 - }  
104 - if (changed) {  
105 - return true;  
106 - }  
107 - String dtoDesc =  
108 - Optional.ofNullable(deviceDTO.getDeviceInfo())  
109 - .map(deviceInfo -> deviceInfo.get("description"))  
110 - .map(JsonNode::asText)  
111 - .orElse("");  
112 - String dtoLabel = deviceDTO.getLabel() == null ? "" : deviceDTO.getLabel();  
113 - String entityDesc =  
114 - Optional.ofNullable(device.getDeviceInfo())  
115 - .map(deviceInfo -> deviceInfo.get("description"))  
116 - .map(JsonNode::asText)  
117 - .orElse("");  
118 - String entityLabel = device.getLabel() == null ? "" : device.getLabel();  
119 - if (!dtoDesc.equals(entityDesc) || !dtoLabel.equals(entityLabel)) {  
120 - changed = true; 81 + private void validateUpdate(DeviceDTO deviceDTO) {
  82 + if (StringUtils.isAllBlank(deviceDTO.getName())) {
  83 + throw new YtDataValidationException("device name must be specific");
  84 + }
121 } 85 }
122 - return changed;  
123 - }  
124 86
125 - @Override  
126 - public boolean validateFormdata(String currentTenantId, DeviceDTO deviceDTO) {  
127 - boolean insert = StringUtils.isBlank(deviceDTO.getId());  
128 - String deviceTenantId = deviceDTO.getTenantId();  
129 - if (StringUtils.isBlank(deviceDTO.getName())) {  
130 - throw new YtDataValidationException("device name cannot be blank");  
131 - }  
132 - // validate IOT DB  
133 - if (StringUtils.isBlank(deviceDTO.getProfileId())) {  
134 - throw new YtDataValidationException("device profile cannot be blank"); 87 + private boolean detectDeviceChange(DeviceDTO deviceDTO, YtDevice device) {
  88 + boolean changed =
  89 + !deviceDTO.getName().equalsIgnoreCase(device.getName())
  90 + || !deviceDTO.getProfileId().equalsIgnoreCase(device.getProfileId());
  91 + if (changed) {
  92 + return true;
  93 + }
  94 + boolean dtoGateway =
  95 + Optional.ofNullable(deviceDTO.getDeviceType())
  96 + .map(deviceType -> deviceType.equals(DeviceTypeEnum.GATEWAY))
  97 + .orElse(false);
  98 + boolean entityGateway =
  99 + Optional.ofNullable(device.getDeviceType())
  100 + .map(deviceType -> deviceType.equals(DeviceTypeEnum.GATEWAY))
  101 + .orElse(false);
  102 + if (entityGateway != dtoGateway) {
  103 + changed = true;
  104 + }
  105 + if (changed) {
  106 + return true;
  107 + }
  108 + String dtoDesc =
  109 + Optional.ofNullable(deviceDTO.getDeviceInfo())
  110 + .map(deviceInfo -> deviceInfo.get("description"))
  111 + .map(JsonNode::asText)
  112 + .orElse("");
  113 + String dtoLabel = deviceDTO.getLabel() == null ? "" : deviceDTO.getLabel();
  114 + String entityDesc =
  115 + Optional.ofNullable(device.getDeviceInfo())
  116 + .map(deviceInfo -> deviceInfo.get("description"))
  117 + .map(JsonNode::asText)
  118 + .orElse("");
  119 + String entityLabel = device.getLabel() == null ? "" : device.getLabel();
  120 + if (!dtoDesc.equals(entityDesc) || !dtoLabel.equals(entityLabel)) {
  121 + changed = true;
  122 + }
  123 + return changed;
135 } 124 }
136 125
137 - // 验证设备名称是否已经存在 如果此处直接使用deviceDTO 将有误  
138 - if (insert) {  
139 - DeviceDTO check = new DeviceDTO();  
140 - check.setName(deviceDTO.getName());  
141 - if (findTbDeviceId(deviceTenantId, check).size() > 0) {  
142 - throw new YtDataValidationException(ErrorMessage.NAME_ALREADY_EXISTS.getMessage());  
143 - } 126 + @Override
  127 + public boolean validateFormdata(String currentTenantId, DeviceDTO deviceDTO) {
  128 + boolean insert = StringUtils.isBlank(deviceDTO.getId());
  129 + String deviceTenantId = deviceDTO.getTenantId();
  130 + if (StringUtils.isBlank(deviceDTO.getName())) {
  131 + throw new YtDataValidationException("device name cannot be blank");
  132 + }
  133 + // validate IOT DB
  134 + if (StringUtils.isBlank(deviceDTO.getProfileId())) {
  135 + throw new YtDataValidationException("device profile cannot be blank");
  136 + }
144 137
145 - deviceTenantId = currentTenantId;  
146 - deviceDTO.setTenantId(currentTenantId);  
147 - } else {  
148 - deviceTenantId = deviceDTO.getTenantId();  
149 - YtDevice device = baseMapper.selectById(deviceDTO.getId());  
150 - if (device == null) {  
151 - throw new YtDataValidationException("设备不存在!");  
152 - }  
153 - if (!device.getTenantId().equals(currentTenantId)) {  
154 - throw new YtDataValidationException(ErrorMessage.TENANT_MISMATCHING.getMessage());  
155 - }  
156 - }  
157 - // 验证数据profileId的正确性  
158 - TenantId id = new TenantId(UUID.fromString(deviceTenantId));  
159 - DeviceProfile deviceProfile =  
160 - deviceProfileDao.findById(id, UUID.fromString(deviceDTO.getProfileId()));  
161 - Organization organization = ytOrganizationMapper.selectById(deviceDTO.getOrganizationId());  
162 - if (null == deviceProfile || null == organization) {  
163 - throw new YtDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());  
164 - } else if (!organization.getTenantId().equals(deviceTenantId)) {  
165 - throw new YtDataValidationException(ErrorMessage.TENANT_MISMATCHING.getMessage()); 138 + // 验证设备名称是否已经存在 如果此处直接使用deviceDTO 将有误
  139 + if (insert) {
  140 + DeviceDTO check = new DeviceDTO();
  141 + check.setName(deviceDTO.getName());
  142 + if (findTbDeviceId(deviceTenantId, check).size() > 0) {
  143 + throw new YtDataValidationException(ErrorMessage.NAME_ALREADY_EXISTS.getMessage());
  144 + }
  145 +
  146 + deviceTenantId = currentTenantId;
  147 + deviceDTO.setTenantId(currentTenantId);
  148 + } else {
  149 + deviceTenantId = deviceDTO.getTenantId();
  150 + YtDevice device = baseMapper.selectById(deviceDTO.getId());
  151 + if (device == null) {
  152 + throw new YtDataValidationException("设备不存在!");
  153 + }
  154 + if (!device.getTenantId().equals(currentTenantId)) {
  155 + throw new YtDataValidationException(ErrorMessage.TENANT_MISMATCHING.getMessage());
  156 + }
  157 + }
  158 + // 验证数据profileId的正确性
  159 + TenantId id = new TenantId(UUID.fromString(deviceTenantId));
  160 + DeviceProfile deviceProfile =
  161 + deviceProfileDao.findById(id, UUID.fromString(deviceDTO.getProfileId()));
  162 + Organization organization = ytOrganizationMapper.selectById(deviceDTO.getOrganizationId());
  163 + if (null == deviceProfile || null == organization) {
  164 + throw new YtDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
  165 + } else if (!organization.getTenantId().equals(deviceTenantId)) {
  166 + throw new YtDataValidationException(ErrorMessage.TENANT_MISMATCHING.getMessage());
  167 + }
  168 + return true;
166 } 169 }
167 - return true;  
168 - }  
169 170
170 - private DeviceDTO insert(DeviceDTO deviceDTO) { 171 + private DeviceDTO insert(DeviceDTO deviceDTO) {
171 172
172 - YtDevice device = new YtDevice();  
173 - deviceDTO.copyToEntity(  
174 - device,  
175 - ModelConstants.TablePropertyMapping.ACTIVE_TIME,  
176 - ModelConstants.TablePropertyMapping.DEVICE_STATE,  
177 - ModelConstants.TablePropertyMapping.CREATOR,  
178 - ModelConstants.TablePropertyMapping.UPDATER,  
179 - ModelConstants.TablePropertyMapping.CREATE_TIME,  
180 - ModelConstants.TablePropertyMapping.UPDATE,  
181 - ModelConstants.TablePropertyMapping.UPDATE_TIME); 173 + YtDevice device = new YtDevice();
  174 + deviceDTO.copyToEntity(
  175 + device,
  176 + ModelConstants.TablePropertyMapping.ACTIVE_TIME,
  177 + ModelConstants.TablePropertyMapping.DEVICE_STATE,
  178 + ModelConstants.TablePropertyMapping.CREATOR,
  179 + ModelConstants.TablePropertyMapping.UPDATER,
  180 + ModelConstants.TablePropertyMapping.CREATE_TIME,
  181 + ModelConstants.TablePropertyMapping.UPDATE,
  182 + ModelConstants.TablePropertyMapping.UPDATE_TIME);
182 183
183 - device.setAlarmStatus(0);  
184 - DeviceState deviceState;  
185 - if (null != deviceDTO.getDeviceState()) {  
186 - deviceState = deviceDTO.getDeviceState();  
187 - } else {  
188 - deviceState = DeviceState.INACTIVE; 184 + device.setAlarmStatus(0);
  185 + DeviceState deviceState;
  186 + if (null != deviceDTO.getDeviceState()) {
  187 + deviceState = deviceDTO.getDeviceState();
  188 + } else {
  189 + deviceState = DeviceState.INACTIVE;
  190 + }
  191 + device.setDeviceState(deviceState);
  192 + baseMapper.insert(device);
  193 + return device.getDTO(DeviceDTO.class);
189 } 194 }
190 - device.setDeviceState(deviceState);  
191 - baseMapper.insert(device);  
192 - return device.getDTO(DeviceDTO.class);  
193 - }  
194 -  
195 - @Override  
196 - public List<String> findTbDeviceId(String tenantId, Set<String> ids) {  
197 - LambdaQueryWrapper<YtDevice> queryWrapper =  
198 - new QueryWrapper<YtDevice>()  
199 - .lambda()  
200 - .eq(YtDevice::getTenantId, tenantId)  
201 - .in(YtDevice::getId, ids);  
202 195
203 - List<String> tbDeviceIds =  
204 - baseMapper.selectList(queryWrapper).stream()  
205 - .map(YtDevice::getTbDeviceId)  
206 - .collect(Collectors.toList());  
207 - return tbDeviceIds;  
208 - } 196 + @Override
  197 + public List<String> findTbDeviceId(String tenantId, Set<String> ids) {
  198 + LambdaQueryWrapper<YtDevice> queryWrapper =
  199 + new QueryWrapper<YtDevice>()
  200 + .lambda()
  201 + .eq(YtDevice::getTenantId, tenantId)
  202 + .in(YtDevice::getId, ids);
209 203
210 - @Override  
211 - public List<DeviceDTO> findDevicesByDeviceTypeAndOrganizationId(  
212 - DeviceTypeEnum deviceType, String organizationId) {  
213 - return ReflectUtils.sourceToTarget(  
214 - baseMapper.selectList(  
215 - new LambdaQueryWrapper<YtDevice>()  
216 - .eq(YtDevice::getDeviceType, deviceType)  
217 - .eq(YtDevice::getOrganizationId, organizationId)),  
218 - DeviceDTO.class);  
219 - } 204 + List<String> tbDeviceIds =
  205 + baseMapper.selectList(queryWrapper).stream()
  206 + .map(YtDevice::getTbDeviceId)
  207 + .collect(Collectors.toList());
  208 + return tbDeviceIds;
  209 + }
220 210
221 - @Override  
222 - public DeviceDTO checkDeviceByTenantIdAndDeviceId(String tenantId, String deviceId) {  
223 - if (StringUtils.isEmpty(tenantId) || StringUtils.isEmpty(deviceId)) {  
224 - throw new YtDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage()); 211 + @Override
  212 + public List<DeviceDTO> findDevicesByDeviceTypeAndOrganizationId(
  213 + DeviceTypeEnum deviceType, String organizationId) {
  214 + return ReflectUtils.sourceToTarget(
  215 + baseMapper.selectList(
  216 + new LambdaQueryWrapper<YtDevice>()
  217 + .eq(YtDevice::getDeviceType, deviceType)
  218 + .eq(YtDevice::getOrganizationId, organizationId)),
  219 + DeviceDTO.class);
225 } 220 }
226 - return baseMapper  
227 - .selectOne(  
228 - new LambdaQueryWrapper<YtDevice>()  
229 - .eq(YtDevice::getTenantId, tenantId)  
230 - .eq(YtDevice::getId, deviceId))  
231 - .getDTO(DeviceDTO.class);  
232 - }  
233 221
234 - @Override  
235 - public List<DeviceDTO> findGateWayDeviceByTbDeviceId(String tenantId, String tbDeviceId) {  
236 - checkDeviceByTenantIdAndId(tenantId, tbDeviceId, true);  
237 - return baseMapper.findGateWayDeviceByTbDeviceId(tbDeviceId);  
238 - } 222 + @Override
  223 + public DeviceDTO checkDeviceByTenantIdAndDeviceId(String tenantId, String deviceId) {
  224 + if (StringUtils.isEmpty(tenantId) || StringUtils.isEmpty(deviceId)) {
  225 + throw new YtDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
  226 + }
  227 + return baseMapper
  228 + .selectOne(
  229 + new LambdaQueryWrapper<YtDevice>()
  230 + .eq(YtDevice::getTenantId, tenantId)
  231 + .eq(YtDevice::getId, deviceId))
  232 + .getDTO(DeviceDTO.class);
  233 + }
239 234
240 - @Override  
241 - public DeviceDTO checkDeviceByTenantIdAndId(  
242 - String tenantId, String deviceId, boolean isTbDeviceId) {  
243 - if (StringUtils.isEmpty(deviceId) || StringUtils.isEmpty(tenantId)) {  
244 - throw new YtDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage()); 235 + @Override
  236 + public List<DeviceDTO> findGateWayDeviceByTbDeviceId(String tenantId, String tbDeviceId) {
  237 + checkDeviceByTenantIdAndId(tenantId, tbDeviceId, true);
  238 + return baseMapper.findGateWayDeviceByTbDeviceId(tbDeviceId);
245 } 239 }
246 - YtDevice device =  
247 - baseMapper.selectOne(  
248 - new LambdaQueryWrapper<YtDevice>()  
249 - .eq(YtDevice::getTenantId, tenantId)  
250 - .eq(isTbDeviceId, YtDevice::getTbDeviceId, deviceId)  
251 - .eq(!isTbDeviceId, YtDevice::getId, deviceId));  
252 - DeviceDTO deviceDTO = null != device ? device.getDTO(DeviceDTO.class) : null;  
253 - if (null == deviceDTO) {  
254 - throw new YtDataValidationException(ErrorMessage.DEVICE_NOT_EXISTENCE_IN_TENANT.getMessage()); 240 +
  241 + @Override
  242 + public DeviceDTO checkDeviceByTenantIdAndId(
  243 + String tenantId, String deviceId, boolean isTbDeviceId) {
  244 + if (StringUtils.isEmpty(deviceId) || StringUtils.isEmpty(tenantId)) {
  245 + throw new YtDataValidationException(ErrorMessage.INVALID_PARAMETER.getMessage());
  246 + }
  247 + YtDevice device =
  248 + baseMapper.selectOne(
  249 + new LambdaQueryWrapper<YtDevice>()
  250 + .eq(YtDevice::getTenantId, tenantId)
  251 + .eq(isTbDeviceId, YtDevice::getTbDeviceId, deviceId)
  252 + .eq(!isTbDeviceId, YtDevice::getId, deviceId));
  253 + DeviceDTO deviceDTO = null != device ? device.getDTO(DeviceDTO.class) : null;
  254 + if (null == deviceDTO) {
  255 + throw new YtDataValidationException(ErrorMessage.DEVICE_NOT_EXISTENCE_IN_TENANT.getMessage());
  256 + }
  257 + return deviceDTO;
255 } 258 }
256 - return deviceDTO;  
257 - }  
258 259
259 - @Override  
260 - @Transactional  
261 - public void deleteDevices(String tenantId, Set<String> ids) {  
262 - LambdaQueryWrapper<YtDevice> queryWrapper =  
263 - new QueryWrapper<YtDevice>()  
264 - .lambda()  
265 - .eq(YtDevice::getTenantId, tenantId)  
266 - .in(YtDevice::getId, ids); 260 + @Override
  261 + @Transactional
  262 + public void deleteDevices(String tenantId, Set<String> ids) {
  263 + LambdaQueryWrapper<YtDevice> queryWrapper =
  264 + new QueryWrapper<YtDevice>()
  265 + .lambda()
  266 + .eq(YtDevice::getTenantId, tenantId)
  267 + .in(YtDevice::getId, ids);
  268 +
  269 + baseMapper.delete(queryWrapper);
  270 + }
267 271
268 - baseMapper.delete(queryWrapper);  
269 - } 272 + @Override
  273 + public Optional<DeviceDTO> getDevice(String tenantId, String id) {
  274 + return Optional.ofNullable(baseMapper.selectDetail(tenantId, id));
  275 + }
270 276
271 - @Override  
272 - public Optional<DeviceDTO> getDevice(String tenantId, String id) {  
273 - return Optional.ofNullable(baseMapper.selectDetail(tenantId, id));  
274 - } 277 + @Override
  278 + public YtPageData<DeviceDTO> page(String tenantId, Map<String, Object> queryMap) {
  279 + queryMap.put("tenantId", tenantId);
  280 + String organizationId = (String) queryMap.get("organizationId");
  281 + if (!StringUtils.isEmpty(organizationId)) {
  282 + List<String> organizationIds = new ArrayList<>();
  283 + organizationIds.add(organizationId);
  284 + // 查询该组织的所有子类
  285 + List<OrganizationDTO> organizationDTOS =
  286 + ytOrganizationMapper.findOrganizationTreeList(tenantId, organizationIds);
  287 + List<String> queryOrganizationIds = new ArrayList<>();
  288 + organizationDTOS.forEach(
  289 + item -> {
  290 + queryOrganizationIds.add(item.getId());
  291 + });
  292 + queryMap.put("organizationIds", queryOrganizationIds);
  293 + }
  294 + IPage<YtDevice> page = getPage(queryMap, FastIotConstants.DefaultOrder.CREATE_TIME, false);
  295 + IPage<DeviceDTO> deviceIPage = baseMapper.getDevicePage(page, queryMap);
  296 + List<DeviceDTO> records = deviceIPage.getRecords();
  297 + records.forEach(
  298 + deviceDTO -> {
  299 + if (null != deviceDTO.getCustomerId()
  300 + && deviceDTO.getCustomerId().equals(EntityId.NULL_UUID.toString())) {
  301 + deviceDTO.setCustomerId(null);
  302 + }
  303 + });
  304 + return new YtPageData<>(records, deviceIPage.getTotal());
  305 + }
275 306
276 - @Override  
277 - public YtPageData<DeviceDTO> page(String tenantId, Map<String, Object> queryMap) {  
278 - queryMap.put("tenantId", tenantId);  
279 - String organizationId = (String) queryMap.get("organizationId");  
280 - if (!StringUtils.isEmpty(organizationId)) {  
281 - List<String> organizationIds = new ArrayList<>();  
282 - organizationIds.add(organizationId);  
283 - // 查询该组织的所有子类  
284 - List<OrganizationDTO> organizationDTOS =  
285 - ytOrganizationMapper.findOrganizationTreeList(tenantId, organizationIds);  
286 - List<String> queryOrganizationIds = new ArrayList<>();  
287 - organizationDTOS.forEach(  
288 - item -> {  
289 - queryOrganizationIds.add(item.getId());  
290 - });  
291 - queryMap.put("organizationIds", queryOrganizationIds); 307 + @Override
  308 + public List<DeviceDTO> findTbDeviceId(String tenantId, DeviceDTO deviceDTO) {
  309 + List<YtDevice> deviceList =
  310 + baseMapper.selectList(
  311 + new QueryWrapper<YtDevice>()
  312 + .lambda()
  313 + .eq(true, YtDevice::getTenantId, tenantId)
  314 + .eq(
  315 + StringUtils.isNotBlank(deviceDTO.getName()),
  316 + YtDevice::getName,
  317 + deviceDTO.getName()));
  318 + return ReflectUtils.sourceToTarget(deviceList, DeviceDTO.class);
292 } 319 }
293 - IPage<YtDevice> page = getPage(queryMap, FastIotConstants.DefaultOrder.CREATE_TIME, false);  
294 - IPage<DeviceDTO> deviceIPage = baseMapper.getDevicePage(page, queryMap);  
295 - List<DeviceDTO> records = deviceIPage.getRecords();  
296 - records.forEach(  
297 - deviceDTO -> {  
298 - if (null != deviceDTO.getCustomerId()  
299 - && deviceDTO.getCustomerId().equals(EntityId.NULL_UUID.toString())) {  
300 - deviceDTO.setCustomerId(null);  
301 - }  
302 - });  
303 - return new YtPageData<>(records, deviceIPage.getTotal());  
304 - }  
305 320
306 - @Override  
307 - public List<DeviceDTO> findTbDeviceId(String tenantId, DeviceDTO deviceDTO) {  
308 - List<YtDevice> deviceList =  
309 - baseMapper.selectList(  
310 - new QueryWrapper<YtDevice>()  
311 - .lambda()  
312 - .eq(true, YtDevice::getTenantId, tenantId)  
313 - .eq(  
314 - StringUtils.isNotBlank(deviceDTO.getName()),  
315 - YtDevice::getName,  
316 - deviceDTO.getName()));  
317 - return ReflectUtils.sourceToTarget(deviceList, DeviceDTO.class);  
318 - } 321 + @Override
  322 + public boolean freshAlarmStatus(EntityId tbDeviceId, Integer created) {
  323 + return baseMapper.freshAlarmStatus(tbDeviceId.getId().toString(), created);
  324 + }
319 } 325 }
@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage; @@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
5 import org.apache.ibatis.annotations.Mapper; 5 import org.apache.ibatis.annotations.Mapper;
6 import org.apache.ibatis.annotations.Param; 6 import org.apache.ibatis.annotations.Param;
7 import org.thingsboard.server.common.data.Device; 7 import org.thingsboard.server.common.data.Device;
  8 +import org.thingsboard.server.common.data.id.DeviceId;
8 import org.thingsboard.server.common.data.yunteng.dto.DeviceDTO; 9 import org.thingsboard.server.common.data.yunteng.dto.DeviceDTO;
9 import org.thingsboard.server.dao.yunteng.entities.YtDevice; 10 import org.thingsboard.server.dao.yunteng.entities.YtDevice;
10 11
@@ -33,4 +34,13 @@ public interface DeviceMapper extends BaseMapper<YtDevice> { @@ -33,4 +34,13 @@ public interface DeviceMapper extends BaseMapper<YtDevice> {
33 * @return 网关设备信息 34 * @return 网关设备信息
34 */ 35 */
35 List<DeviceDTO> findGateWayDeviceByTbDeviceId(@Param("tbDeviceId") String tbDeviceId); 36 List<DeviceDTO> findGateWayDeviceByTbDeviceId(@Param("tbDeviceId") String tbDeviceId);
  37 +
  38 + /**
  39 + * 更新设备告警状态
  40 + *
  41 + * @param tbDeviceId TB设备主键
  42 + * @param created 告警状态:0正常,1告警
  43 + * @return
  44 + */
  45 + boolean freshAlarmStatus(@Param("tbDeviceId") String tbDeviceId,@Param("created") Integer created);
36 } 46 }
1 package org.thingsboard.server.dao.yunteng.service; 1 package org.thingsboard.server.dao.yunteng.service;
2 2
  3 +import org.thingsboard.server.common.data.id.DeviceId;
  4 +import org.thingsboard.server.common.data.id.EntityId;
3 import org.thingsboard.server.common.data.yunteng.dto.DeviceDTO; 5 import org.thingsboard.server.common.data.yunteng.dto.DeviceDTO;
4 import org.thingsboard.server.common.data.yunteng.enums.DeviceTypeEnum; 6 import org.thingsboard.server.common.data.yunteng.enums.DeviceTypeEnum;
5 import org.thingsboard.server.common.data.yunteng.utils.tools.YtPageData; 7 import org.thingsboard.server.common.data.yunteng.utils.tools.YtPageData;
@@ -10,57 +12,74 @@ import java.util.Optional; @@ -10,57 +12,74 @@ import java.util.Optional;
10 import java.util.Set; 12 import java.util.Set;
11 13
12 public interface YtDeviceService { 14 public interface YtDeviceService {
13 - DeviceDTO insertOrUpdate(String tenantId,DeviceDTO deviceDTO); 15 + DeviceDTO insertOrUpdate(String tenantId, DeviceDTO deviceDTO);
14 16
15 - void deleteDevices(String tenantId,Set<String> ids); 17 + void deleteDevices(String tenantId, Set<String> ids);
16 18
17 - Optional<DeviceDTO> getDevice(String tenantId,String id); 19 + Optional<DeviceDTO> getDevice(String tenantId, String id);
18 20
19 - YtPageData<DeviceDTO> page(String tenantId, Map<String, Object> queryMap); 21 + YtPageData<DeviceDTO> page(String tenantId, Map<String, Object> queryMap);
20 22
21 - /**  
22 - * 验证表单数据有效性  
23 - * @param ytDevice  
24 - */  
25 - boolean validateFormdata(String currentTenantId,DeviceDTO ytDevice);  
26 - /**  
27 - * 查询所有的设备信息  
28 - * @param deviceDTO 过滤参数  
29 - * @return List<DeviceDTO>  
30 - */  
31 - List<DeviceDTO> findTbDeviceId(String tenantId, DeviceDTO deviceDTO); 23 + /**
  24 + * 验证表单数据有效性
  25 + *
  26 + * @param ytDevice
  27 + */
  28 + boolean validateFormdata(String currentTenantId, DeviceDTO ytDevice);
32 29
33 - List<String> findTbDeviceId(String tenantId, Set<String> ids);  
34 - /**  
35 - * 通过设备类型和组织ID查询所有的设备  
36 - * @param deviceType 设备类型  
37 - * @param organizationId 组织ID  
38 - * @return 设备列表  
39 - */  
40 - List<DeviceDTO> findDevicesByDeviceTypeAndOrganizationId(DeviceTypeEnum deviceType,String organizationId); 30 + /**
  31 + * 查询所有的设备信息
  32 + *
  33 + * @param deviceDTO 过滤参数
  34 + * @return List<DeviceDTO>
  35 + */
  36 + List<DeviceDTO> findTbDeviceId(String tenantId, DeviceDTO deviceDTO);
41 37
42 - /**  
43 - * 通过设备ID和租户ID判断该设备是否存在  
44 - * @param tenantId 租户ID  
45 - * @param deviceId 设备ID  
46 - * @return 设备  
47 - */  
48 - DeviceDTO checkDeviceByTenantIdAndDeviceId(String tenantId,String deviceId); 38 + List<String> findTbDeviceId(String tenantId, Set<String> ids);
49 39
50 - /**  
51 - * 通过网关子设备的TB设备ID查询网关设备信息  
52 - * @param tbDeviceId 网关子设备的TB设备ID  
53 - * @param tenantId 租户ID  
54 - * @return 网关设备信息  
55 - */  
56 - List<DeviceDTO> findGateWayDeviceByTbDeviceId(String tenantId,String tbDeviceId); 40 + /**
  41 + * 通过设备类型和组织ID查询所有的设备
  42 + *
  43 + * @param deviceType 设备类型
  44 + * @param organizationId 组织ID
  45 + * @return 设备列表
  46 + */
  47 + List<DeviceDTO> findDevicesByDeviceTypeAndOrganizationId(DeviceTypeEnum deviceType, String organizationId);
57 48
58 - /**  
59 - * 通过设备ID和租户ID检查设备是否存在  
60 - * @param tenantId 租户ID  
61 - * @param deviceId 设备ID  
62 - * @param isTbDeviceId 是TB设备ID  
63 - * @return 设备信息  
64 - */  
65 - DeviceDTO checkDeviceByTenantIdAndId(String tenantId,String deviceId,boolean isTbDeviceId); 49 + /**
  50 + * 通过设备ID和租户ID判断该设备是否存在
  51 + *
  52 + * @param tenantId 租户ID
  53 + * @param deviceId 设备ID
  54 + * @return 设备
  55 + */
  56 + DeviceDTO checkDeviceByTenantIdAndDeviceId(String tenantId, String deviceId);
  57 +
  58 + /**
  59 + * 通过网关子设备的TB设备ID查询网关设备信息
  60 + *
  61 + * @param tbDeviceId 网关子设备的TB设备ID
  62 + * @param tenantId 租户ID
  63 + * @return 网关设备信息
  64 + */
  65 + List<DeviceDTO> findGateWayDeviceByTbDeviceId(String tenantId, String tbDeviceId);
  66 +
  67 + /**
  68 + * 通过设备ID和租户ID检查设备是否存在
  69 + *
  70 + * @param tenantId 租户ID
  71 + * @param deviceId 设备ID
  72 + * @param isTbDeviceId 是TB设备ID
  73 + * @return 设备信息
  74 + */
  75 + DeviceDTO checkDeviceByTenantIdAndId(String tenantId, String deviceId, boolean isTbDeviceId);
  76 +
  77 + /**
  78 + * 更新设备告警状态
  79 + *
  80 + * @param tbDeviceId TB设备主键
  81 + * @param created 告警状态:0正常,1告警
  82 + * @return
  83 + */
  84 + boolean freshAlarmStatus(EntityId tbDeviceId, Integer created);
66 } 85 }
@@ -125,4 +125,10 @@ @@ -125,4 +125,10 @@
125 AND rl.relation_type_group = 'COMMON' AND rl.relation_type = 'Created' 125 AND rl.relation_type_group = 'COMMON' AND rl.relation_type = 'Created'
126 AND rl.from_type = 'DEVICE' AND rl.to_type = 'DEVICE' 126 AND rl.from_type = 'DEVICE' AND rl.to_type = 'DEVICE'
127 </select> 127 </select>
  128 +
  129 + <update id="freshAlarmStatus" >
  130 + UPDATE iotfs_device
  131 + SET alarm_status=#{created}
  132 + WHERE tb_device_id = #{tbDeviceId}
  133 + </update>
128 </mapper> 134 </mapper>
1 /** 1 /**
2 * Copyright © 2016-2021 The Thingsboard Authors 2 * Copyright © 2016-2021 The Thingsboard Authors
3 - * 3 + * <p>
4 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License. 5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at 6 * You may obtain a copy of the License at
7 - *  
8 - * http://www.apache.org/licenses/LICENSE-2.0  
9 - * 7 + * <p>
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + * <p>
10 * Unless required by applicable law or agreed to in writing, software 10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, 11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -21,8 +21,8 @@ import com.google.common.util.concurrent.ListenableFuture; @@ -21,8 +21,8 @@ import com.google.common.util.concurrent.ListenableFuture;
21 import lombok.Data; 21 import lombok.Data;
22 import lombok.extern.slf4j.Slf4j; 22 import lombok.extern.slf4j.Slf4j;
23 import org.apache.commons.lang3.StringUtils; 23 import org.apache.commons.lang3.StringUtils;
24 -import org.thingsboard.common.util.JacksonUtil;  
25 import org.thingsboard.common.util.DonAsynchron; 24 import org.thingsboard.common.util.DonAsynchron;
  25 +import org.thingsboard.common.util.JacksonUtil;
26 import org.thingsboard.rule.engine.action.TbAlarmResult; 26 import org.thingsboard.rule.engine.action.TbAlarmResult;
27 import org.thingsboard.rule.engine.api.TbContext; 27 import org.thingsboard.rule.engine.api.TbContext;
28 import org.thingsboard.rule.engine.profile.state.PersistedAlarmRuleState; 28 import org.thingsboard.rule.engine.profile.state.PersistedAlarmRuleState;
@@ -36,10 +36,12 @@ import org.thingsboard.server.common.data.device.profile.AlarmConditionSpecType; @@ -36,10 +36,12 @@ import org.thingsboard.server.common.data.device.profile.AlarmConditionSpecType;
36 import org.thingsboard.server.common.data.device.profile.DeviceProfileAlarm; 36 import org.thingsboard.server.common.data.device.profile.DeviceProfileAlarm;
37 import org.thingsboard.server.common.data.id.DashboardId; 37 import org.thingsboard.server.common.data.id.DashboardId;
38 import org.thingsboard.server.common.data.id.EntityId; 38 import org.thingsboard.server.common.data.id.EntityId;
  39 +import org.thingsboard.server.common.data.yunteng.utils.SpringBeanUtils;
39 import org.thingsboard.server.common.msg.TbMsg; 40 import org.thingsboard.server.common.msg.TbMsg;
40 import org.thingsboard.server.common.msg.TbMsgMetaData; 41 import org.thingsboard.server.common.msg.TbMsgMetaData;
41 import org.thingsboard.server.common.msg.queue.ServiceQueue; 42 import org.thingsboard.server.common.msg.queue.ServiceQueue;
42 import org.thingsboard.server.dao.alarm.AlarmOperationResult; 43 import org.thingsboard.server.dao.alarm.AlarmOperationResult;
  44 +import org.thingsboard.server.dao.yunteng.service.YtDeviceService;
43 45
44 import java.util.ArrayList; 46 import java.util.ArrayList;
45 import java.util.Comparator; 47 import java.util.Comparator;
@@ -62,12 +64,14 @@ class AlarmState { @@ -62,12 +64,14 @@ class AlarmState {
62 private volatile String lastMsgQueueName; 64 private volatile String lastMsgQueueName;
63 private volatile DataSnapshot dataSnapshot; 65 private volatile DataSnapshot dataSnapshot;
64 private final DynamicPredicateValueCtx dynamicPredicateValueCtx; 66 private final DynamicPredicateValueCtx dynamicPredicateValueCtx;
  67 + private YtDeviceService ytDeviceService;
65 68
66 AlarmState(ProfileState deviceProfile, EntityId originator, DeviceProfileAlarm alarmDefinition, PersistedAlarmState alarmState, DynamicPredicateValueCtx dynamicPredicateValueCtx) { 69 AlarmState(ProfileState deviceProfile, EntityId originator, DeviceProfileAlarm alarmDefinition, PersistedAlarmState alarmState, DynamicPredicateValueCtx dynamicPredicateValueCtx) {
67 this.deviceProfile = deviceProfile; 70 this.deviceProfile = deviceProfile;
68 this.originator = originator; 71 this.originator = originator;
69 this.dynamicPredicateValueCtx = dynamicPredicateValueCtx; 72 this.dynamicPredicateValueCtx = dynamicPredicateValueCtx;
70 this.updateState(alarmDefinition, alarmState); 73 this.updateState(alarmDefinition, alarmState);
  74 + this.ytDeviceService = SpringBeanUtils.getBean(YtDeviceService.class);
71 } 75 }
72 76
73 public boolean process(TbContext ctx, TbMsg msg, DataSnapshot data, SnapshotUpdate update) throws ExecutionException, InterruptedException { 77 public boolean process(TbContext ctx, TbMsg msg, DataSnapshot data, SnapshotUpdate update) throws ExecutionException, InterruptedException {
@@ -121,6 +125,7 @@ class AlarmState { @@ -121,6 +125,7 @@ class AlarmState {
121 ListenableFuture<AlarmOperationResult> alarmClearOperationResult = ctx.getAlarmService().clearAlarmForResult( 125 ListenableFuture<AlarmOperationResult> alarmClearOperationResult = ctx.getAlarmService().clearAlarmForResult(
122 ctx.getTenantId(), currentAlarm.getId(), createDetails(clearState), System.currentTimeMillis() 126 ctx.getTenantId(), currentAlarm.getId(), createDetails(clearState), System.currentTimeMillis()
123 ); 127 );
  128 + ytDeviceService.freshAlarmStatus(currentAlarm.getOriginator(), 0);
124 DonAsynchron.withCallback(alarmClearOperationResult, 129 DonAsynchron.withCallback(alarmClearOperationResult,
125 result -> { 130 result -> {
126 pushMsg(ctx, msg, new TbAlarmResult(false, false, true, result.getAlarm()), clearState); 131 pushMsg(ctx, msg, new TbAlarmResult(false, false, true, result.getAlarm()), clearState);
@@ -262,6 +267,7 @@ class AlarmState { @@ -262,6 +267,7 @@ class AlarmState {
262 currentAlarm.setPropagateRelationTypes(alarmDefinition.getPropagateRelationTypes()); 267 currentAlarm.setPropagateRelationTypes(alarmDefinition.getPropagateRelationTypes());
263 } 268 }
264 currentAlarm = ctx.getAlarmService().createOrUpdateAlarm(currentAlarm); 269 currentAlarm = ctx.getAlarmService().createOrUpdateAlarm(currentAlarm);
  270 + ytDeviceService.freshAlarmStatus(originator, 1);
265 boolean updated = currentAlarm.getStartTs() != currentAlarm.getEndTs(); 271 boolean updated = currentAlarm.getStartTs() != currentAlarm.getEndTs();
266 return new TbAlarmResult(!updated, updated, false, false, currentAlarm); 272 return new TbAlarmResult(!updated, updated, false, false, currentAlarm);
267 } 273 }