add corresponding tests for schedule from dynamic values
This commit is contained in:
parent
46e301b2db
commit
03256deee7
@ -44,6 +44,8 @@ import org.thingsboard.server.common.data.device.profile.DeviceProfileAlarm;
|
|||||||
import org.thingsboard.server.common.data.device.profile.DeviceProfileData;
|
import org.thingsboard.server.common.data.device.profile.DeviceProfileData;
|
||||||
import org.thingsboard.server.common.data.device.profile.DurationAlarmConditionSpec;
|
import org.thingsboard.server.common.data.device.profile.DurationAlarmConditionSpec;
|
||||||
import org.thingsboard.server.common.data.device.profile.RepeatingAlarmConditionSpec;
|
import org.thingsboard.server.common.data.device.profile.RepeatingAlarmConditionSpec;
|
||||||
|
import org.thingsboard.server.common.data.device.profile.CustomTimeSchedule;
|
||||||
|
import org.thingsboard.server.common.data.device.profile.CustomTimeScheduleItem;
|
||||||
import org.thingsboard.server.common.data.id.CustomerId;
|
import org.thingsboard.server.common.data.id.CustomerId;
|
||||||
import org.thingsboard.server.common.data.id.DeviceId;
|
import org.thingsboard.server.common.data.id.DeviceId;
|
||||||
import org.thingsboard.server.common.data.id.DeviceProfileId;
|
import org.thingsboard.server.common.data.id.DeviceProfileId;
|
||||||
@ -71,6 +73,7 @@ import java.math.RoundingMode;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@ -1086,6 +1089,182 @@ public class TbDeviceProfileNodeTest {
|
|||||||
verify(ctx, Mockito.never()).tellFailure(Mockito.any(), Mockito.any());
|
verify(ctx, Mockito.never()).tellFailure(Mockito.any(), Mockito.any());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testActiveAlarmScheduleFromDynamicValuesWhenDefaultScheduleIsInactive() throws Exception {
|
||||||
|
init();
|
||||||
|
|
||||||
|
DeviceProfile deviceProfile = new DeviceProfile();
|
||||||
|
deviceProfile.setId(deviceProfileId);
|
||||||
|
DeviceProfileData deviceProfileData = new DeviceProfileData();
|
||||||
|
|
||||||
|
Device device = new Device();
|
||||||
|
device.setId(deviceId);
|
||||||
|
device.setCustomerId(customerId);
|
||||||
|
|
||||||
|
AttributeKvCompositeKey compositeKeyActiveSchedule = new AttributeKvCompositeKey(
|
||||||
|
EntityType.TENANT, deviceId.getId(), "SERVER_SCOPE", "dynamicValueActiveSchedule"
|
||||||
|
);
|
||||||
|
|
||||||
|
AttributeKvEntity attributeKvEntityActiveSchedule = new AttributeKvEntity();
|
||||||
|
attributeKvEntityActiveSchedule.setId(compositeKeyActiveSchedule);
|
||||||
|
attributeKvEntityActiveSchedule.setJsonValue(
|
||||||
|
"{\"timezone\":\"Europe/Kiev\",\"items\":[{\"enabled\":true,\"dayOfWeek\":1,\"startsOn\":0,\"endsOn\":8.64e+7},{\"enabled\":true,\"dayOfWeek\":2,\"startsOn\":0,\"endsOn\":8.64e+7},{\"enabled\":true,\"dayOfWeek\":3,\"startsOn\":0,\"endsOn\":8.64e+7},{\"enabled\":true,\"dayOfWeek\":4,\"startsOn\":0,\"endsOn\":8.64e+7},{\"enabled\":true,\"dayOfWeek\":5,\"startsOn\":0,\"endsOn\":8.64e+7},{\"enabled\":true,\"dayOfWeek\":6,\"startsOn\":8.64e+7,\"endsOn\":8.64e+7},{\"enabled\":true,\"dayOfWeek\":7,\"startsOn\":0,\"endsOn\":8.64e+7}],\"dynamicValue\":null}"
|
||||||
|
);
|
||||||
|
attributeKvEntityActiveSchedule.setLastUpdateTs(0L);
|
||||||
|
|
||||||
|
AttributeKvEntry entryActiveSchedule = attributeKvEntityActiveSchedule.toData();
|
||||||
|
|
||||||
|
ListenableFuture<List<AttributeKvEntry>> listListenableFutureActiveSchedule =
|
||||||
|
Futures.immediateFuture(Collections.singletonList(entryActiveSchedule));
|
||||||
|
|
||||||
|
AlarmConditionFilter highTempFilter = new AlarmConditionFilter();
|
||||||
|
highTempFilter.setKey(new AlarmConditionFilterKey(AlarmConditionKeyType.TIME_SERIES, "temperature"));
|
||||||
|
highTempFilter.setValueType(EntityKeyValueType.NUMERIC);
|
||||||
|
NumericFilterPredicate highTemperaturePredicate = new NumericFilterPredicate();
|
||||||
|
highTemperaturePredicate.setOperation(NumericFilterPredicate.NumericOperation.GREATER);
|
||||||
|
highTemperaturePredicate.setValue(new FilterPredicateValue<>(
|
||||||
|
0.0,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
));
|
||||||
|
highTempFilter.setPredicate(highTemperaturePredicate);
|
||||||
|
AlarmCondition alarmCondition = new AlarmCondition();
|
||||||
|
alarmCondition.setCondition(Collections.singletonList(highTempFilter));
|
||||||
|
|
||||||
|
CustomTimeSchedule schedule = new CustomTimeSchedule();
|
||||||
|
schedule.setItems(Collections.emptyList());
|
||||||
|
schedule.setDynamicValue(new DynamicValue<>(DynamicValueSourceType.CURRENT_DEVICE, "dynamicValueActiveSchedule", false));
|
||||||
|
|
||||||
|
AlarmRule alarmRule = new AlarmRule();
|
||||||
|
alarmRule.setCondition(alarmCondition);
|
||||||
|
alarmRule.setSchedule(schedule);
|
||||||
|
DeviceProfileAlarm deviceProfileAlarmActiveSchedule = new DeviceProfileAlarm();
|
||||||
|
deviceProfileAlarmActiveSchedule.setId("highTemperatureAlarmID");
|
||||||
|
deviceProfileAlarmActiveSchedule.setAlarmType("highTemperatureAlarm");
|
||||||
|
deviceProfileAlarmActiveSchedule.setCreateRules(new TreeMap<>(Collections.singletonMap(AlarmSeverity.CRITICAL, alarmRule)));
|
||||||
|
|
||||||
|
deviceProfileData.setAlarms(Collections.singletonList(deviceProfileAlarmActiveSchedule));
|
||||||
|
deviceProfile.setProfileData(deviceProfileData);
|
||||||
|
|
||||||
|
Mockito.when(cache.get(tenantId, deviceId)).thenReturn(deviceProfile);
|
||||||
|
Mockito.when(timeseriesService.findLatest(tenantId, deviceId, Collections.singleton("temperature")))
|
||||||
|
.thenReturn(Futures.immediateFuture(Collections.emptyList()));
|
||||||
|
Mockito.when(alarmService.findLatestByOriginatorAndType(tenantId, deviceId, "highTemperatureAlarm"))
|
||||||
|
.thenReturn(Futures.immediateFuture(null));
|
||||||
|
Mockito.when(alarmService.createOrUpdateAlarm(Mockito.any())).thenAnswer(AdditionalAnswers.returnsFirstArg());
|
||||||
|
Mockito.when(ctx.getAttributesService()).thenReturn(attributesService);
|
||||||
|
Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.anyString(), Mockito.anySet()))
|
||||||
|
.thenReturn(listListenableFutureActiveSchedule);
|
||||||
|
|
||||||
|
TbMsg theMsg = TbMsg.newMsg("ALARM", deviceId, new TbMsgMetaData(), "");
|
||||||
|
Mockito.when(ctx.newMsg(Mockito.anyString(), Mockito.anyString(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.anyString()))
|
||||||
|
.thenReturn(theMsg);
|
||||||
|
|
||||||
|
ObjectNode data = mapper.createObjectNode();
|
||||||
|
data.put("temperature", 35);
|
||||||
|
TbMsg msg = TbMsg.newMsg(SessionMsgType.POST_TELEMETRY_REQUEST.name(), deviceId, new TbMsgMetaData(),
|
||||||
|
TbMsgDataType.JSON, mapper.writeValueAsString(data), null, null);
|
||||||
|
|
||||||
|
node.onMsg(ctx, msg);
|
||||||
|
verify(ctx).tellSuccess(msg);
|
||||||
|
verify(ctx).enqueueForTellNext(theMsg, "Alarm Created");
|
||||||
|
verify(ctx, Mockito.never()).tellFailure(Mockito.any(), Mockito.any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInactiveAlarmScheduleFromDynamicValuesWhenDefaultScheduleIsActive() throws Exception {
|
||||||
|
init();
|
||||||
|
|
||||||
|
DeviceProfile deviceProfile = new DeviceProfile();
|
||||||
|
deviceProfile.setId(deviceProfileId);
|
||||||
|
DeviceProfileData deviceProfileData = new DeviceProfileData();
|
||||||
|
|
||||||
|
Device device = new Device();
|
||||||
|
device.setId(deviceId);
|
||||||
|
device.setCustomerId(customerId);
|
||||||
|
|
||||||
|
AttributeKvCompositeKey compositeKeyInactiveSchedule = new AttributeKvCompositeKey(
|
||||||
|
EntityType.TENANT, deviceId.getId(), "SERVER_SCOPE", "dynamicValueInactiveSchedule"
|
||||||
|
);
|
||||||
|
|
||||||
|
AttributeKvEntity attributeKvEntityInactiveSchedule = new AttributeKvEntity();
|
||||||
|
attributeKvEntityInactiveSchedule.setId(compositeKeyInactiveSchedule);
|
||||||
|
attributeKvEntityInactiveSchedule.setJsonValue(
|
||||||
|
"{\"timezone\":\"Europe/Kiev\",\"items\":[{\"enabled\":false,\"dayOfWeek\":1,\"startsOn\":0,\"endsOn\":0},{\"enabled\":false,\"dayOfWeek\":2,\"startsOn\":0,\"endsOn\":0},{\"enabled\":false,\"dayOfWeek\":3,\"startsOn\":0,\"endsOn\":0},{\"enabled\":false,\"dayOfWeek\":4,\"startsOn\":0,\"endsOn\":0},{\"enabled\":false,\"dayOfWeek\":5,\"startsOn\":0,\"endsOn\":0},{\"enabled\":false,\"dayOfWeek\":6,\"startsOn\":0,\"endsOn\":0},{\"enabled\":false,\"dayOfWeek\":7,\"startsOn\":0,\"endsOn\":0}],\"dynamicValue\":null}"
|
||||||
|
);
|
||||||
|
|
||||||
|
attributeKvEntityInactiveSchedule.setLastUpdateTs(0L);
|
||||||
|
|
||||||
|
AttributeKvEntry entryInactiveSchedule = attributeKvEntityInactiveSchedule.toData();
|
||||||
|
|
||||||
|
ListenableFuture<List<AttributeKvEntry>> listListenableFutureInactiveSchedule =
|
||||||
|
Futures.immediateFuture(Collections.singletonList(entryInactiveSchedule));
|
||||||
|
|
||||||
|
AlarmConditionFilter highTempFilter = new AlarmConditionFilter();
|
||||||
|
highTempFilter.setKey(new AlarmConditionFilterKey(AlarmConditionKeyType.TIME_SERIES, "temperature"));
|
||||||
|
highTempFilter.setValueType(EntityKeyValueType.NUMERIC);
|
||||||
|
NumericFilterPredicate highTemperaturePredicate = new NumericFilterPredicate();
|
||||||
|
highTemperaturePredicate.setOperation(NumericFilterPredicate.NumericOperation.GREATER);
|
||||||
|
highTemperaturePredicate.setValue(new FilterPredicateValue<>(
|
||||||
|
0.0,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
));
|
||||||
|
|
||||||
|
highTempFilter.setPredicate(highTemperaturePredicate);
|
||||||
|
AlarmCondition alarmCondition = new AlarmCondition();
|
||||||
|
alarmCondition.setCondition(Collections.singletonList(highTempFilter));
|
||||||
|
|
||||||
|
CustomTimeSchedule schedule = new CustomTimeSchedule();
|
||||||
|
|
||||||
|
List<CustomTimeScheduleItem> items = new ArrayList<>();
|
||||||
|
for (int i = 0; i < 7; i++) {
|
||||||
|
CustomTimeScheduleItem item = new CustomTimeScheduleItem();
|
||||||
|
item.setEnabled(true);
|
||||||
|
item.setDayOfWeek(i + 1);
|
||||||
|
item.setEndsOn(0);
|
||||||
|
item.setStartsOn(0);
|
||||||
|
items.add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
schedule.setItems(items);
|
||||||
|
schedule.setDynamicValue(new DynamicValue<>(DynamicValueSourceType.CURRENT_DEVICE, "dynamicValueInactiveSchedule", false));
|
||||||
|
|
||||||
|
AlarmRule alarmRule = new AlarmRule();
|
||||||
|
alarmRule.setCondition(alarmCondition);
|
||||||
|
alarmRule.setSchedule(schedule);
|
||||||
|
DeviceProfileAlarm deviceProfileAlarmNonactiveSchedule = new DeviceProfileAlarm();
|
||||||
|
deviceProfileAlarmNonactiveSchedule.setId("highTemperatureAlarmID");
|
||||||
|
deviceProfileAlarmNonactiveSchedule.setAlarmType("highTemperatureAlarm");
|
||||||
|
deviceProfileAlarmNonactiveSchedule.setCreateRules(new TreeMap<>(Collections.singletonMap(AlarmSeverity.CRITICAL, alarmRule)));
|
||||||
|
|
||||||
|
deviceProfileData.setAlarms(Collections.singletonList(deviceProfileAlarmNonactiveSchedule));
|
||||||
|
deviceProfile.setProfileData(deviceProfileData);
|
||||||
|
|
||||||
|
Mockito.when(cache.get(tenantId, deviceId)).thenReturn(deviceProfile);
|
||||||
|
Mockito.when(timeseriesService.findLatest(tenantId, deviceId, Collections.singleton("temperature")))
|
||||||
|
.thenReturn(Futures.immediateFuture(Collections.emptyList()));
|
||||||
|
Mockito.when(alarmService.findLatestByOriginatorAndType(tenantId, deviceId, "highTemperatureAlarm"))
|
||||||
|
.thenReturn(Futures.immediateFuture(null));
|
||||||
|
Mockito.when(alarmService.createOrUpdateAlarm(Mockito.any())).thenAnswer(AdditionalAnswers.returnsFirstArg());
|
||||||
|
Mockito.when(ctx.getAttributesService()).thenReturn(attributesService);
|
||||||
|
Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.anyString(), Mockito.anySet()))
|
||||||
|
.thenReturn(listListenableFutureInactiveSchedule);
|
||||||
|
|
||||||
|
TbMsg theMsg = TbMsg.newMsg("ALARM", deviceId, new TbMsgMetaData(), "");
|
||||||
|
Mockito.when(ctx.newMsg(Mockito.anyString(), Mockito.anyString(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.anyString()))
|
||||||
|
.thenReturn(theMsg);
|
||||||
|
|
||||||
|
ObjectNode data = mapper.createObjectNode();
|
||||||
|
data.put("temperature", 35);
|
||||||
|
TbMsg msg = TbMsg.newMsg(SessionMsgType.POST_TELEMETRY_REQUEST.name(), deviceId, new TbMsgMetaData(),
|
||||||
|
TbMsgDataType.JSON, mapper.writeValueAsString(data), null, null);
|
||||||
|
|
||||||
|
node.onMsg(ctx, msg);
|
||||||
|
verify(ctx).tellSuccess(msg);
|
||||||
|
verify(ctx, Mockito.never()).enqueueForTellNext(theMsg, "Alarm Created");
|
||||||
|
verify(ctx, Mockito.never()).tellFailure(Mockito.any(), Mockito.any());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCurrentCustomersAttributeForDynamicValue() throws Exception {
|
public void testCurrentCustomersAttributeForDynamicValue() throws Exception {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user