diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml new file mode 100644 index 00000000000..45a7d6204e5 --- /dev/null +++ b/.github/workflows/dependency-review.yml @@ -0,0 +1,18 @@ +name: Maven Dependency Tree Dependency Submission +on: + schedule: + - cron: '0 0 * * *' + workflow_dispatch: + +permissions: + contents: write + +jobs: + dependency-detection-and-submission: + runs-on: ubuntu-latest + steps: + - name: 'Checkout Repository' + uses: actions/checkout@v4 + + - name: Submit Dependency Snapshot + uses: advanced-security/maven-dependency-submission-action@v3 diff --git a/integration-tests/cucumber-tests-core/pom.xml b/integration-tests/cucumber-tests-core/pom.xml index 3984aae7d9f..729a31d3be1 100644 --- a/integration-tests/cucumber-tests-core/pom.xml +++ b/integration-tests/cucumber-tests-core/pom.xml @@ -12,7 +12,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-integration-tests - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-integration-tests/pom.xml diff --git a/integration-tests/cucumber-tests-core/src/test/java/org/opensmartgridplatform/cucumber/core/DateTimeHelper.java b/integration-tests/cucumber-tests-core/src/test/java/org/opensmartgridplatform/cucumber/core/DateTimeHelper.java index 39da0c6aa1b..e9f6b37afc6 100644 --- a/integration-tests/cucumber-tests-core/src/test/java/org/opensmartgridplatform/cucumber/core/DateTimeHelper.java +++ b/integration-tests/cucumber-tests-core/src/test/java/org/opensmartgridplatform/cucumber/core/DateTimeHelper.java @@ -7,16 +7,15 @@ import com.luckycatlabs.sunrisesunset.SunriseSunsetCalculator; import com.luckycatlabs.sunrisesunset.dto.Location; import java.time.Instant; +import java.time.LocalTime; import java.time.ZoneId; import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import java.util.Calendar; -import java.util.TimeZone; +import java.util.Date; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.joda.time.format.DateTimeFormat; -import org.joda.time.format.DateTimeFormatter; +import org.opensmartgridplatform.shared.utils.JavaTimeHelpers; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,8 +28,8 @@ public class DateTimeHelper { /** * @return CET/CEST time zone based on ID {@value #CET_TIMEZONE} */ - public static DateTimeZone getCentralEuropeanTimeZone() { - return DateTimeZone.forID(CET_TIMEZONE); + public static ZoneId getCentralEuropeanTimeZone() { + return ZoneId.of(CET_TIMEZONE); } /** @@ -57,12 +56,12 @@ public static ZoneId getCentralEuropeanZoneId() { *
  • now at midday + 1 week * */ - public static DateTime getDateTime(final String dateString) { + public static ZonedDateTime getDateTime(final String dateString) { if (dateString.isEmpty()) { return null; } - DateTime retval = DateTime.now(getCentralEuropeanTimeZone()); + ZonedDateTime retval = ZonedDateTime.now(getCentralEuropeanTimeZone()); final String pattern = "([a-z ]*)[ ]*([+-]?)[ ]*([0-9]*)[ ]*([a-z]*)"; final Pattern r = Pattern.compile(pattern); @@ -105,18 +104,18 @@ public static DateTime getDateTime(final String dateString) { } // Normalize the seconds and milliseconds to zero - retval = retval.withSecondOfMinute(0); - retval = retval.withMillisOfSecond(0); + retval = retval.withSecond(0); + retval = retval.withNano(0); if (whenMatcher.groupCount() > 1 && whenMatcher.group(2).equals("at")) { switch (whenMatcher.group(3)) { case "midday": case "noon": - retval = retval.withHourOfDay(12); + retval = retval.withHour(12); break; case "midnight": - retval = retval.withHourOfDay(0); + retval = retval.withHour(0); break; default: throw new IllegalArgumentException( @@ -124,8 +123,8 @@ public static DateTime getDateTime(final String dateString) { + dateString + "], expected \"midday\", \"noon\" or \"midnight\""); } - retval = retval.withMinuteOfHour(0); - retval = retval.withSecondOfMinute(0); + retval = retval.withMinute(0); + retval = retval.withSecond(0); } if (op.equals("+")) { @@ -176,7 +175,7 @@ public static DateTime getDateTime(final String dateString) { } public static ZonedDateTime getZonedDateTime(final String dateString) { - return dateTimeToZonedDateTime(getDateTime(dateString)); + return getDateTime(dateString); } public static Instant getInstant(final String dateString) { @@ -184,17 +183,17 @@ public static Instant getInstant(final String dateString) { return dateTime.toInstant(); } - public static DateTime getDateTime2(final String startDate, final DateTime defaultStartDate) { + public static ZonedDateTime getDateTime2( + final String startDate, final ZonedDateTime defaultStartDate) { if (startDate == null) { return defaultStartDate; } - DateTime dateTime; + ZonedDateTime dateTime; try { dateTime = getDateTime(startDate); } catch (final IllegalArgumentException e) { - LOGGER.debug( - "The string {} could not be parsed by DateTimeHelper.getDateTime, lets org.joda.time.DateTime"); - dateTime = DateTime.parse(startDate); + LOGGER.debug("The string {} could not be parsed by DateTimeHelper.getDateTime"); + dateTime = JavaTimeHelpers.parseToZonedDateTime(startDate); } if (dateTime == null) { return defaultStartDate; @@ -204,13 +203,12 @@ public static DateTime getDateTime2(final String startDate, final DateTime defau public static ZonedDateTime getZonedDateTime2( final String startDate, final ZonedDateTime defaultStartDate) { - return dateTimeToZonedDateTime( - getDateTime2(startDate, zonedDateTimeToDateTime(defaultStartDate))); + return getDateTime2(startDate, defaultStartDate); } /** Get time of sunrise/sunset */ - public static DateTime getSunriseSunsetTime( - final String actionTimeType, final DateTime date, final Location location) { + public static ZonedDateTime getSunriseSunsetTime( + final String actionTimeType, final ZonedDateTime date, final Location location) { final SunriseSunsetCalculator calculator = new SunriseSunsetCalculator(location, "UTC"); Calendar officialTransition = null; @@ -218,10 +216,10 @@ public static DateTime getSunriseSunsetTime( final Calendar calender = Calendar.getInstance(); if (actionTimeType.equalsIgnoreCase("SUNSET")) { - calender.setTime(date.toDate()); + calender.setTime(Date.from(date.toInstant())); officialTransition = calculator.getOfficialSunsetCalendarForDate(calender); } else if (actionTimeType.equalsIgnoreCase("SUNRISE")) { - calender.setTime(date.plusDays(1).toDate()); + calender.setTime(Date.from(date.plusDays(1).toInstant())); officialTransition = calculator.getOfficialSunriseCalendarForDate(calender); } @@ -229,47 +227,13 @@ public static DateTime getSunriseSunsetTime( return null; } - return new DateTime(officialTransition.getTimeInMillis()); + return ZonedDateTime.ofInstant( + Instant.ofEpochMilli(officialTransition.getTimeInMillis()), ZoneId.systemDefault()); } public static ZonedDateTime getSunriseSunsetZonedDateTime( final String actionTimeType, final ZonedDateTime date, final Location location) { - return dateTimeToZonedDateTime( - getSunriseSunsetTime(actionTimeType, zonedDateTimeToDateTime(date), location)); - } - - /** - * Shifts a DateTime from the system's timezone to UTC. - * - * @param dateTime The DateTime in local system's timezone. - * @return shifted DateTime in UTC - */ - public static final DateTime shiftSystemZoneToUtc(final DateTime dateTime) { - return dateTime - .plusSeconds(ZonedDateTime.now().getOffset().getTotalSeconds()) - .withZone(DateTimeZone.UTC); - } - - /** - * Shifts a time to from the system's timezone to CET. It assumes the time is for the current - * date. - * - * @param time Time in system's timezone, formatted as HH:mm - * @return Time in CET, formatted as HH:mm - */ - public static String shiftSystemZoneToCET(final String time) { - return DateTimeHelper.shiftTimeToOtherZone(time, true); - } - - /** - * Shifts a time to from CET to the system's timezone. It assumes the time is for the current - * date. - * - * @param time Time in system's timezone, formatted as HH:mm - * @return Time in CET, formatted as HH:mm - */ - public static String shiftCETToSystemZone(final String time) { - return DateTimeHelper.shiftTimeToOtherZone(time, false); + return getSunriseSunsetTime(actionTimeType, date, location); } /** @@ -281,40 +245,26 @@ public static String shiftCETToSystemZone(final String time) { */ private static String shiftTimeToOtherZone(final String time, final boolean positiveShift) { // Extract hours and minutes from the time parameter - final DateTimeFormatter timeFormatter = DateTimeFormat.forPattern(TIME_FORMAT); - final DateTime parsedTime = timeFormatter.parseDateTime(time); + final DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern(TIME_FORMAT); + final LocalTime parsedTime = LocalTime.parse(time, timeFormatter); // Determine current CET offset in hours for the system timezone. - final int UTCOffsetForCET = DateTimeZone.forID(CET_TIMEZONE).getOffset(new DateTime()); - final int UTCOffsetForSystem = DateTimeZone.getDefault().getOffset(new DateTime()); + final int UTCOffsetForCET = + ZoneId.of(CET_TIMEZONE).getRules().getOffset(Instant.now()).getTotalSeconds(); + final int UTCOffsetForSystem = + ZoneId.systemDefault().getRules().getOffset(Instant.now()).getTotalSeconds(); final int offsetHours = - (UTCOffsetForCET - UTCOffsetForSystem) / (3600 * 1000) * (positiveShift ? 1 : -1); + (UTCOffsetForCET - UTCOffsetForSystem) / (3600) * (positiveShift ? 1 : -1); // Add offset - final DateTime shiftedTime = - new DateTime() - .withTime(parsedTime.getHourOfDay(), parsedTime.getMinuteOfHour(), 0, 0) + final ZonedDateTime shiftedTime = + ZonedDateTime.now() + .withHour(parsedTime.getHour()) + .withMinute(parsedTime.getMinute()) + .withSecond(0) + .withNano(0) .plusHours(offsetHours); - return timeFormatter.print(shiftedTime); - } - - public static ZonedDateTime dateTimeToZonedDateTime(final DateTime dateTime) { - if (dateTime == null) { - return null; - } - - return dateTime.toGregorianCalendar().toZonedDateTime(); - } - - private static DateTime zonedDateTimeToDateTime(final ZonedDateTime zonedDateTime) { - if (zonedDateTime == null) { - return null; - } - - final long millis = zonedDateTime.toInstant().toEpochMilli(); - final DateTimeZone dateTimeZone = - DateTimeZone.forTimeZone(TimeZone.getTimeZone(zonedDateTime.getZone())); - return new DateTime(millis, dateTimeZone); + return timeFormatter.format(shiftedTime); } } diff --git a/integration-tests/cucumber-tests-core/src/test/java/org/opensmartgridplatform/cucumber/core/ReadSettingsHelper.java b/integration-tests/cucumber-tests-core/src/test/java/org/opensmartgridplatform/cucumber/core/ReadSettingsHelper.java index c53a3af0d37..ae02c55a788 100644 --- a/integration-tests/cucumber-tests-core/src/test/java/org/opensmartgridplatform/cucumber/core/ReadSettingsHelper.java +++ b/integration-tests/cucumber-tests-core/src/test/java/org/opensmartgridplatform/cucumber/core/ReadSettingsHelper.java @@ -13,7 +13,7 @@ import org.apache.commons.codec.DecoderException; import org.apache.commons.codec.binary.Hex; import org.apache.commons.lang3.StringUtils; -import org.joda.time.DateTime; +import org.opensmartgridplatform.shared.utils.JavaTimeHelpers; public class ReadSettingsHelper { /** @@ -58,8 +58,8 @@ public static Boolean getBoolean( * @param key The key in the settings for the date time. * @return The date time. */ - public static DateTime getDate(final Map settings, final String key) { - return getDate(settings, key, DateTime.now()); + public static ZonedDateTime getDate(final Map settings, final String key) { + return getDate(settings, key, ZonedDateTime.now()); } /** @@ -70,13 +70,12 @@ public static DateTime getDate(final Map settings, final String * @param defaultDate The default date to return. * @return The date time. */ - public static DateTime getDate( - final Map settings, final String key, final DateTime defaultDate) { + public static ZonedDateTime getDate( + final Map settings, final String key, final ZonedDateTime defaultDate) { if (!settings.containsKey(key) || StringUtils.isBlank(settings.get(key))) { return defaultDate; } - - return DateTime.parse(settings.get(key)); + return JavaTimeHelpers.parseToZonedDateTime(settings.get(key)); } /** diff --git a/integration-tests/cucumber-tests-core/src/test/java/org/opensmartgridplatform/cucumber/core/TestGetDateTime.java b/integration-tests/cucumber-tests-core/src/test/java/org/opensmartgridplatform/cucumber/core/TestGetDateTime.java index dc90c37bfc3..b7a8b2f5380 100644 --- a/integration-tests/cucumber-tests-core/src/test/java/org/opensmartgridplatform/cucumber/core/TestGetDateTime.java +++ b/integration-tests/cucumber-tests-core/src/test/java/org/opensmartgridplatform/cucumber/core/TestGetDateTime.java @@ -6,20 +6,20 @@ import static org.assertj.core.api.Assertions.assertThat; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; +import java.time.ZoneId; +import java.time.ZonedDateTime; import org.junit.jupiter.api.Test; public class TestGetDateTime { - private DateTimeZone cetTime = DateTimeHelper.getCentralEuropeanTimeZone(); + private final ZoneId cetTime = DateTimeHelper.getCentralEuropeanTimeZone(); @Test public void testGetDateTime() { - final DateTime nowPlus4 = new DateTime(this.cetTime).plusMinutes(4); - final DateTime nowPlus6 = new DateTime(this.cetTime).plusMinutes(6); + final ZonedDateTime nowPlus4 = ZonedDateTime.now(this.cetTime).plusMinutes(4); + final ZonedDateTime nowPlus6 = ZonedDateTime.now(this.cetTime).plusMinutes(6); - final DateTime dt = DateTimeHelper.getDateTime("now + 5 minutes"); + final ZonedDateTime dt = DateTimeHelper.getDateTime("now + 5 minutes"); assertThat(dt).isStrictlyBetween(nowPlus4, nowPlus6); } diff --git a/integration-tests/cucumber-tests-execution/pom.xml b/integration-tests/cucumber-tests-execution/pom.xml index 845ac04ffc5..751c02cfb9f 100644 --- a/integration-tests/cucumber-tests-execution/pom.xml +++ b/integration-tests/cucumber-tests-execution/pom.xml @@ -12,7 +12,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-integration-tests - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-integration-tests/pom.xml diff --git a/integration-tests/cucumber-tests-execution/src/main/java/org/opensmartgridplatform/cucumber/execution/AppBase.java b/integration-tests/cucumber-tests-execution/src/main/java/org/opensmartgridplatform/cucumber/execution/AppBase.java index adb7e467735..07cecf0ede5 100644 --- a/integration-tests/cucumber-tests-execution/src/main/java/org/opensmartgridplatform/cucumber/execution/AppBase.java +++ b/integration-tests/cucumber-tests-execution/src/main/java/org/opensmartgridplatform/cucumber/execution/AppBase.java @@ -11,7 +11,6 @@ import java.util.stream.Collectors; import junit.runner.Version; import org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter; -import org.joda.time.DateTimeZone; import org.junit.runner.Computer; import org.junit.runner.Description; import org.junit.runner.JUnitCore; @@ -48,7 +47,6 @@ public abstract class AppBase { public static int run(final AppBase app, final String[] testClasses, final String... args) { // Ensure the tests are executed in UTC time TimeZone.setDefault(TimeZone.getTimeZone("UTC")); - DateTimeZone.setDefault(DateTimeZone.UTC); final CmdLineParser p = new CmdLineParser(app); try { diff --git a/integration-tests/cucumber-tests-platform-common/pom.xml b/integration-tests/cucumber-tests-platform-common/pom.xml index f018f1221d3..652a31e237e 100644 --- a/integration-tests/cucumber-tests-platform-common/pom.xml +++ b/integration-tests/cucumber-tests-platform-common/pom.xml @@ -13,7 +13,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-integration-tests - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-integration-tests/pom.xml diff --git a/integration-tests/cucumber-tests-platform-common/src/test/java/org/opensmartgridplatform/cucumber/platform/common/glue/steps/database/ws/WsCoreResponseDataSteps.java b/integration-tests/cucumber-tests-platform-common/src/test/java/org/opensmartgridplatform/cucumber/platform/common/glue/steps/database/ws/WsCoreResponseDataSteps.java index f73027afd42..66782c83e15 100644 --- a/integration-tests/cucumber-tests-platform-common/src/test/java/org/opensmartgridplatform/cucumber/platform/common/glue/steps/database/ws/WsCoreResponseDataSteps.java +++ b/integration-tests/cucumber-tests-platform-common/src/test/java/org/opensmartgridplatform/cucumber/platform/common/glue/steps/database/ws/WsCoreResponseDataSteps.java @@ -9,7 +9,7 @@ import io.cucumber.java.en.Given; import io.cucumber.java.en.Then; import java.lang.reflect.Field; -import java.util.Date; +import java.time.Instant; import java.util.Map; import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.Assertions; @@ -38,8 +38,8 @@ public ResponseData aResponseDataRecord(final Map settings) { final ResponseData responseData = this.responseDataRepository.save(new ResponseDataBuilder().fromSettings(settings).build()); - final Date creationTime = - DateTimeHelper.getDateTime(settings.get(PlatformKeys.KEY_CREATION_TIME)).toDate(); + final Instant creationTime = + DateTimeHelper.getDateTime(settings.get(PlatformKeys.KEY_CREATION_TIME)).toInstant(); LOGGER.info( "Creating response data record with correlationUid: {} and creationTime: {}", diff --git a/integration-tests/cucumber-tests-platform-common/src/test/java/org/opensmartgridplatform/cucumber/platform/common/glue/steps/ws/admin/devicemanagement/SetCommunicationNetworkInformationSteps.java b/integration-tests/cucumber-tests-platform-common/src/test/java/org/opensmartgridplatform/cucumber/platform/common/glue/steps/ws/admin/devicemanagement/SetCommunicationNetworkInformationSteps.java index c8487dea002..50a5dbe012e 100644 --- a/integration-tests/cucumber-tests-platform-common/src/test/java/org/opensmartgridplatform/cucumber/platform/common/glue/steps/ws/admin/devicemanagement/SetCommunicationNetworkInformationSteps.java +++ b/integration-tests/cucumber-tests-platform-common/src/test/java/org/opensmartgridplatform/cucumber/platform/common/glue/steps/ws/admin/devicemanagement/SetCommunicationNetworkInformationSteps.java @@ -28,7 +28,8 @@ public class SetCommunicationNetworkInformationSteps { public void receivingASetCommunicationNetworkInformationRequest( final Map inputSettings) throws WebServiceSecurityException { - final SetCommunicationNetworkInformationRequest request = createRequestFromInput(inputSettings); + final SetCommunicationNetworkInformationRequest request = + this.createRequestFromInput(inputSettings); final SetCommunicationNetworkInformationResponse response = this.client.setCommunicationNetworkInformation(request); @@ -48,7 +49,7 @@ public void theSetCommunicationNetworkInformationResponseShouldBeReturned( assertThat(response.getResult().name()) .as(PlatformKeys.KEY_RESULT) .isEqualTo(inputSettings.get(PlatformKeys.KEY_RESULT)); - assertThat(response.getIpAddress()).isEqualTo(inputSettings.get(PlatformKeys.IP_ADDRESS)); + assertThat(response.getIpAddress()).isEqualTo(inputSettings.get(PlatformKeys.NETWORK_ADDRESS)); assertThat(response.getBtsId()) .isEqualTo(Integer.parseInt(inputSettings.get(PlatformKeys.BTS_ID))); assertThat(response.getCellId()) @@ -56,12 +57,12 @@ public void theSetCommunicationNetworkInformationResponseShouldBeReturned( } private SetCommunicationNetworkInformationRequest createRequestFromInput( - Map inputSettings) { + final Map inputSettings) { final SetCommunicationNetworkInformationRequest request = new SetCommunicationNetworkInformationRequest(); request.setDeviceIdentification(inputSettings.get(PlatformKeys.KEY_DEVICE_IDENTIFICATION)); - request.setIpAddress(inputSettings.get(PlatformKeys.IP_ADDRESS)); + request.setIpAddress(inputSettings.get(PlatformKeys.NETWORK_ADDRESS)); if (inputSettings.get(PlatformKeys.BTS_ID) != null) { request.setBtsId(Integer.parseInt(inputSettings.get(PlatformKeys.BTS_ID))); @@ -78,7 +79,8 @@ private SetCommunicationNetworkInformationRequest createRequestFromInput( public void receivingASetCommunicationNetworkInformationRequestWithAnInvalidIp( final Map inputSettings) throws WebServiceSecurityException { - final SetCommunicationNetworkInformationRequest request = createRequestFromInput(inputSettings); + final SetCommunicationNetworkInformationRequest request = + this.createRequestFromInput(inputSettings); try { this.client.setCommunicationNetworkInformation(request); diff --git a/integration-tests/cucumber-tests-platform-common/src/test/java/org/opensmartgridplatform/cucumber/platform/common/glue/steps/ws/core/devicemanagement/FindScheduledTasksSteps.java b/integration-tests/cucumber-tests-platform-common/src/test/java/org/opensmartgridplatform/cucumber/platform/common/glue/steps/ws/core/devicemanagement/FindScheduledTasksSteps.java index 17ae0d7bfd9..c75001c1f25 100644 --- a/integration-tests/cucumber-tests-platform-common/src/test/java/org/opensmartgridplatform/cucumber/platform/common/glue/steps/ws/core/devicemanagement/FindScheduledTasksSteps.java +++ b/integration-tests/cucumber-tests-platform-common/src/test/java/org/opensmartgridplatform/cucumber/platform/common/glue/steps/ws/core/devicemanagement/FindScheduledTasksSteps.java @@ -15,11 +15,12 @@ import io.cucumber.java.en.Given; import io.cucumber.java.en.Then; import io.cucumber.java.en.When; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.util.List; import java.util.Map; import java.util.function.Predicate; import javax.xml.datatype.XMLGregorianCalendar; -import org.joda.time.DateTime; import org.opensmartgridplatform.adapter.ws.schema.core.devicemanagement.FindScheduledTasksRequest; import org.opensmartgridplatform.adapter.ws.schema.core.devicemanagement.FindScheduledTasksResponse; import org.opensmartgridplatform.cucumber.core.DateTimeHelper; @@ -27,6 +28,7 @@ import org.opensmartgridplatform.cucumber.platform.common.support.ws.core.CoreDeviceManagementClient; import org.opensmartgridplatform.cucumber.platform.glue.steps.database.core.ScheduledTaskSteps; import org.opensmartgridplatform.shared.exceptionhandling.WebServiceSecurityException; +import org.opensmartgridplatform.shared.utils.JavaTimeHelpers; import org.springframework.beans.factory.annotation.Autowired; public class FindScheduledTasksSteps { @@ -77,34 +79,36 @@ public void thenTheFindScheduledTasksResponseShouldContain(final DataTable tasks } } - private static final Predicate< + private static Predicate< org.opensmartgridplatform.adapter.ws.schema.core.devicemanagement.ScheduledTask> hasOrganizationIdentification(final String organizationIdentification) { return task -> task.getOrganisationIdentification().equals(organizationIdentification); } - private static final Predicate< + private static Predicate< org.opensmartgridplatform.adapter.ws.schema.core.devicemanagement.ScheduledTask> hasDeviceIdentification(final String deviceIdentification) { return task -> task.getDeviceIdentification().equals(deviceIdentification); } - private static final Predicate< + private static Predicate< org.opensmartgridplatform.adapter.ws.schema.core.devicemanagement.ScheduledTask> hasMessageType(final String messageType) { return task -> task.getMessageType().equals(messageType); } - private static final Predicate< + private static Predicate< org.opensmartgridplatform.adapter.ws.schema.core.devicemanagement.ScheduledTask> hasScheduledTime(final String scheduledTime) { return task -> isEqual(task.getScheduledTime(), scheduledTime); } - private static final boolean isEqual(final XMLGregorianCalendar actual, final String expected) { - final DateTime expectedDateTime = - DateTimeHelper.shiftSystemZoneToUtc(DateTimeHelper.getDateTime(expected)); - final DateTime actualDateTime = new DateTime(actual.toGregorianCalendar()); + private static boolean isEqual(final XMLGregorianCalendar actual, final String expected) { + final ZonedDateTime expectedDateTime = + DateTimeHelper.getDateTime(expected).withZoneSameInstant(ZoneId.of("UTC")); + final ZonedDateTime actualDateTime = + JavaTimeHelpers.gregorianCalendarToZonedDateTime( + actual.toGregorianCalendar(), ZoneId.of("UTC")); return actualDateTime.isEqual(expectedDateTime); } } diff --git a/integration-tests/cucumber-tests-platform-common/src/test/java/org/opensmartgridplatform/cucumber/platform/common/glue/steps/ws/core/devicemanagement/RetrieveReceivedEventNotifications.java b/integration-tests/cucumber-tests-platform-common/src/test/java/org/opensmartgridplatform/cucumber/platform/common/glue/steps/ws/core/devicemanagement/RetrieveReceivedEventNotifications.java index cc255ac7299..c4d964eecd8 100644 --- a/integration-tests/cucumber-tests-platform-common/src/test/java/org/opensmartgridplatform/cucumber/platform/common/glue/steps/ws/core/devicemanagement/RetrieveReceivedEventNotifications.java +++ b/integration-tests/cucumber-tests-platform-common/src/test/java/org/opensmartgridplatform/cucumber/platform/common/glue/steps/ws/core/devicemanagement/RetrieveReceivedEventNotifications.java @@ -15,10 +15,10 @@ import io.cucumber.java.en.When; import java.io.IOException; import java.security.GeneralSecurityException; +import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.List; import java.util.Map; -import org.joda.time.DateTime; import org.opensmartgridplatform.adapter.ws.schema.core.devicemanagement.FindEventsRequest; import org.opensmartgridplatform.adapter.ws.schema.core.devicemanagement.FindEventsResponse; import org.opensmartgridplatform.cucumber.core.ScenarioContext; @@ -56,7 +56,7 @@ public void allEvents(final Map data) { final Event event = new Event( deviceIdentification, - getDateTime(PlatformDefaults.TIMESTAMP).toDate(), + getDateTime(PlatformDefaults.TIMESTAMP).toInstant(), eventType, PlatformDefaults.DEFAULT_EVENT_DESCRIPTION, PlatformDefaults.DEFAULT_INDEX); @@ -73,7 +73,7 @@ public void anEvent(final int amount, final Map data) throws Exc new Event( deviceIdentification, getDateTime(getString(data, PlatformKeys.TIMESTAMP, PlatformDefaults.TIMESTAMP)) - .toDate(), + .toInstant(), getEnum(data, PlatformKeys.EVENT_TYPE, EventType.class, EventType.ALARM_NOTIFICATION), getString( data, PlatformKeys.KEY_DESCRIPTION, PlatformDefaults.DEFAULT_EVENT_DESCRIPTION), @@ -212,13 +212,13 @@ public void theStoredEventsFromADeviceAreFilteredAndRetrieved( throws Throwable { final List events = new ArrayList<>(); final List eventIterator = this.retrieveStoredEvents(deviceIdentification); - final DateTime + final ZonedDateTime fromTimestamp = getDateTime(getString(expectedResponse, PlatformKeys.FROM_TIMESTAMP)), toTimestamp = getDateTime(getString(expectedResponse, PlatformKeys.TO_TIMESTAMP)); for (final Event e : eventIterator) { - if (fromTimestamp.isBefore(e.getDateTime().getTime()) - && toTimestamp.isAfter(e.getDateTime().getTime())) { + if (fromTimestamp.isBefore(ZonedDateTime.from(e.getDateTime())) + && toTimestamp.isAfter(ZonedDateTime.from(e.getDateTime()))) { events.add(e); } } @@ -259,7 +259,7 @@ public void theStoredEventsAreRetrieved( @Then("^the stored events are filtered and retrieved$") public void theStoredEventsAreFilteredAndRetrieved(final Map expectedResponse) throws Throwable { - List events; + final List events; if (getString(expectedResponse, PlatformKeys.KEY_DEVICE_IDENTIFICATION).isEmpty()) { events = this.retrieveStoredEvents(); diff --git a/integration-tests/cucumber-tests-platform-common/src/test/resources/features/common/osgp-adapter-ws-admin/DeviceManagement/SetCommunicationNetworkInformation.feature b/integration-tests/cucumber-tests-platform-common/src/test/resources/features/common/osgp-adapter-ws-admin/DeviceManagement/SetCommunicationNetworkInformation.feature index ae4d3b76989..11a09868077 100644 --- a/integration-tests/cucumber-tests-platform-common/src/test/resources/features/common/osgp-adapter-ws-admin/DeviceManagement/SetCommunicationNetworkInformation.feature +++ b/integration-tests/cucumber-tests-platform-common/src/test/resources/features/common/osgp-adapter-ws-admin/DeviceManagement/SetCommunicationNetworkInformation.feature @@ -11,26 +11,16 @@ Feature: Set Communication Network Information Given a device | DeviceIdentification | TEST1024000000001 | | OrganizationIdentification | test-org | - | IpAddress | 127.0.0.1 | + | NetworkAddress | 127.0.0.1 | | BtsId | 0 | | CellId | 0 | When receiving a set communication network information request | DeviceIdentification | TEST1024000000001 | - | IpAddress | 10.0.0.1 | + | NetworkAddress | 10.0.0.1 | | BtsId | 20 | | CellId | 1 | Then the set communication network information response should be returned - | Result | OK | - | IpAddress | 10.0.0.1 | - | BtsId | 20 | - | CellId | 1 | - - Scenario: Set Communication Network Information with invalid ip - Given a device - | DeviceIdentification | TEST1024000000001 | - | OrganizationIdentification | test-org | - When receiving a set communication network information request with an invalid ip - | DeviceIdentification | TEST1024000000001 | - | IpAddress | scr@mbled | - Then the set communication network information response contains soap fault - | Message | INVALID_IP_ADDRESS | \ No newline at end of file + | Result | OK | + | NetworkAddress | 10.0.0.1 | + | BtsId | 20 | + | CellId | 1 | diff --git a/integration-tests/cucumber-tests-platform-distributionautomation/pom.xml b/integration-tests/cucumber-tests-platform-distributionautomation/pom.xml index 232354dbadc..98cfb750b68 100644 --- a/integration-tests/cucumber-tests-platform-distributionautomation/pom.xml +++ b/integration-tests/cucumber-tests-platform-distributionautomation/pom.xml @@ -13,7 +13,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-integration-tests - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-integration-tests/pom.xml diff --git a/integration-tests/cucumber-tests-platform-microgrids/pom.xml b/integration-tests/cucumber-tests-platform-microgrids/pom.xml index 5d7805572d8..be6487222c0 100644 --- a/integration-tests/cucumber-tests-platform-microgrids/pom.xml +++ b/integration-tests/cucumber-tests-platform-microgrids/pom.xml @@ -13,7 +13,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-integration-tests - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-integration-tests/pom.xml diff --git a/integration-tests/cucumber-tests-platform-microgrids/src/test/java/org/opensmartgridplatform/cucumber/platform/microgrids/glue/steps/database/ws/WsMicrogridsResponseDataSteps.java b/integration-tests/cucumber-tests-platform-microgrids/src/test/java/org/opensmartgridplatform/cucumber/platform/microgrids/glue/steps/database/ws/WsMicrogridsResponseDataSteps.java index 0a51caa58d3..0bdd4984bf9 100644 --- a/integration-tests/cucumber-tests-platform-microgrids/src/test/java/org/opensmartgridplatform/cucumber/platform/microgrids/glue/steps/database/ws/WsMicrogridsResponseDataSteps.java +++ b/integration-tests/cucumber-tests-platform-microgrids/src/test/java/org/opensmartgridplatform/cucumber/platform/microgrids/glue/steps/database/ws/WsMicrogridsResponseDataSteps.java @@ -48,7 +48,7 @@ public ResponseData aResponseDataRecord(final Map settings) { fld.setAccessible(true); fld.set( responseData, - DateTimeHelper.getDateTime(settings.get(PlatformKeys.KEY_CREATION_TIME)).toDate()); + DateTimeHelper.getDateTime(settings.get(PlatformKeys.KEY_CREATION_TIME)).toInstant()); this.microgridsResponseDataRepository.saveAndFlush(responseData); } } catch (final Exception e) { diff --git a/integration-tests/cucumber-tests-platform-publiclighting/pom.xml b/integration-tests/cucumber-tests-platform-publiclighting/pom.xml index 75baff75575..e2adf9b524c 100644 --- a/integration-tests/cucumber-tests-platform-publiclighting/pom.xml +++ b/integration-tests/cucumber-tests-platform-publiclighting/pom.xml @@ -12,7 +12,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-integration-tests - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-integration-tests/pom.xml diff --git a/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/domain/platform/LightMeasurementRtuDeviceCreator.java b/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/domain/platform/LightMeasurementRtuDeviceCreator.java index a7e6c5ce3d1..b919844c54b 100644 --- a/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/domain/platform/LightMeasurementRtuDeviceCreator.java +++ b/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/domain/platform/LightMeasurementRtuDeviceCreator.java @@ -21,7 +21,7 @@ public class LightMeasurementRtuDeviceCreator extends AbstractPlatformDeviceCrea public RtuDevice apply(final Protocol protocol, final Map settings) { RtuDevice device = new RtuDevice(this.deviceIdentification(settings)); device.setDeviceType(DeviceType.LIGHT_MEASUREMENT_RTU.getPlatformDeviceType()); - device.setNetworkAddress(this.networkAddress(settings)); + device.setNetworkAddress(this.networkAddress(settings).getHostAddress()); device.setDeviceLifecycleStatus(this.deviceLifecycleStatus(settings)); device.setActivated(this.activated(settings)); device.updateProtocol(this.protocolInfo(protocol)); diff --git a/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/glue/steps/database/adapterprotocoloslp/OslpDeviceSteps.java b/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/glue/steps/database/adapterprotocoloslp/OslpDeviceSteps.java index 52442cb7f5b..a1aa762c491 100644 --- a/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/glue/steps/database/adapterprotocoloslp/OslpDeviceSteps.java +++ b/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/glue/steps/database/adapterprotocoloslp/OslpDeviceSteps.java @@ -10,8 +10,8 @@ import io.cucumber.java.en.Given; import io.cucumber.java.en.Then; import java.nio.charset.StandardCharsets; +import java.time.Instant; import java.time.ZonedDateTime; -import java.util.Date; import java.util.HashMap; import java.util.Map; import org.apache.commons.codec.binary.Base64; @@ -83,8 +83,7 @@ public void aPendingSetScheduleRequest( PlatformKeys.KEY_ORGANIZATION_IDENTIFICATION, PlatformDefaults.DEFAULT_ORGANIZATION_IDENTIFICATION); - final Date expireDateTime = - Date.from(ZonedDateTime.now().plusMinutes(expiresInMinutes).toInstant()); + final Instant expireDateTime = ZonedDateTime.now().plusMinutes(expiresInMinutes).toInstant(); // just add a dummy DeviceRequest and a dummy // ScheduleMessageDataContainerDto diff --git a/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/glue/steps/database/ws/WsPublicLightingResponseDataSteps.java b/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/glue/steps/database/ws/WsPublicLightingResponseDataSteps.java index 6b066a646a9..aa07de6e8e8 100644 --- a/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/glue/steps/database/ws/WsPublicLightingResponseDataSteps.java +++ b/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/glue/steps/database/ws/WsPublicLightingResponseDataSteps.java @@ -53,7 +53,7 @@ private ResponseData createResponseDataRecord( fld.setAccessible(true); fld.set( responseData, - DateTimeHelper.getDateTime(settings.get(PlatformKeys.KEY_CREATION_TIME)).toDate()); + DateTimeHelper.getDateTime(settings.get(PlatformKeys.KEY_CREATION_TIME)).toInstant()); responseDataRepository.saveAndFlush(responseData); } } catch (final Exception e) { diff --git a/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/glue/steps/mocks/OslpDeviceSteps.java b/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/glue/steps/mocks/OslpDeviceSteps.java index d5e4f22e130..f391d8010f9 100644 --- a/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/glue/steps/mocks/OslpDeviceSteps.java +++ b/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/glue/steps/mocks/OslpDeviceSteps.java @@ -20,6 +20,8 @@ import java.net.InetSocketAddress; import java.net.UnknownHostException; import java.text.ParseException; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -27,7 +29,6 @@ import java.util.Map; import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang3.StringUtils; -import org.joda.time.DateTimeZone; import org.junit.Assert; import org.opensmartgridplatform.adapter.protocol.oslp.elster.domain.entities.OslpDevice; import org.opensmartgridplatform.adapter.protocol.oslp.elster.domain.repositories.OslpDeviceRepository; @@ -70,6 +71,7 @@ import org.opensmartgridplatform.oslp.OslpEnvelope; import org.opensmartgridplatform.oslp.OslpUtils; import org.opensmartgridplatform.shared.infra.jms.MessageType; +import org.opensmartgridplatform.shared.utils.JavaTimeHelpers; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.CollectionUtils; @@ -79,6 +81,8 @@ */ public class OslpDeviceSteps { + public static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd"); + @Autowired private CoreDeviceConfiguration configuration; @Autowired private MockOslpServer oslpMockServer; @@ -639,17 +643,19 @@ private void checkAndValidateRequest( if (StringUtils.isNotBlank( expectedRequest.get(PlatformPubliclightingKeys.SCHEDULE_STARTDAY))) { final String startDay = - getDate(expectedRequest, PlatformPubliclightingKeys.SCHEDULE_STARTDAY) - .toDateTime(DateTimeZone.UTC) - .toString("yyyyMMdd"); + JavaTimeHelpers.formatDate( + getDate(expectedRequest, PlatformPubliclightingKeys.SCHEDULE_STARTDAY) + .withZoneSameInstant(ZoneId.of("UTC")), + FORMATTER); assertThat(schedule.getStartDay()).isEqualTo(startDay); } if (StringUtils.isNotBlank(expectedRequest.get(PlatformPubliclightingKeys.SCHEDULE_ENDDAY))) { final String endDay = - getDate(expectedRequest, PlatformPubliclightingKeys.SCHEDULE_ENDDAY) - .toDateTime(DateTimeZone.UTC) - .toString("yyyyMMdd"); + JavaTimeHelpers.formatDate( + getDate(expectedRequest, PlatformPubliclightingKeys.SCHEDULE_ENDDAY) + .withZoneSameInstant(ZoneId.of("UTC")), + DateTimeFormatter.ofPattern("yyyyMMdd")); assertThat(schedule.getEndDay()).isEqualTo(endDay); } @@ -1211,7 +1217,7 @@ public void theDeviceSendsARegisterDeviceRequestToThePlatform( InetAddress.getByName( getString( settings, - PlatformPubliclightingKeys.IP_ADDRESS, + PlatformPubliclightingKeys.NETWORK_ADDRESS, PlatformPubliclightingDefaults.LOCALHOST)) .getAddress())) .setDeviceType( diff --git a/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/glue/steps/ws/basicosgpfunctions/AuthorizeDeviceFunctionsSteps.java b/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/glue/steps/ws/basicosgpfunctions/AuthorizeDeviceFunctionsSteps.java index f41365cc8ae..cfdf00cb446 100644 --- a/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/glue/steps/ws/basicosgpfunctions/AuthorizeDeviceFunctionsSteps.java +++ b/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/glue/steps/ws/basicosgpfunctions/AuthorizeDeviceFunctionsSteps.java @@ -12,10 +12,10 @@ import io.cucumber.java.en.When; import java.io.IOException; import java.security.GeneralSecurityException; +import java.time.ZonedDateTime; import java.util.Map; import javax.naming.OperationNotSupportedException; import javax.xml.datatype.DatatypeConfigurationException; -import org.joda.time.DateTime; import org.opensmartgridplatform.adapter.ws.schema.publiclighting.adhocmanagement.GetStatusRequest; import org.opensmartgridplatform.adapter.ws.schema.publiclighting.adhocmanagement.LightValue; import org.opensmartgridplatform.adapter.ws.schema.publiclighting.adhocmanagement.ResumeScheduleRequest; @@ -162,7 +162,7 @@ private void setLightSchedule(final Map requestParameters) schedule.setActionTime(ActionTimeType.SUNRISE); schedule.setIndex(0); schedule.setWeekDay(WeekDayType.ALL); - schedule.setTime(DateTime.now().toString()); + schedule.setTime(ZonedDateTime.now().toString()); schedule.setIsEnabled(true); schedule.setMinimumLightsOn(10); final org.opensmartgridplatform.adapter.ws.schema.publiclighting.schedulemanagement.LightValue @@ -207,7 +207,7 @@ private void setTariffSchedule(final Map requestParameters) schedule.setWeekDay( org.opensmartgridplatform.adapter.ws.schema.tariffswitching.schedulemanagement.WeekDayType .ALL); - schedule.setTime(DateTime.now().toString()); + schedule.setTime(ZonedDateTime.now().toString()); schedule.setIsEnabled(true); schedule.setMinimumLightsOn(10); request.getSchedules().add(schedule); diff --git a/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/glue/steps/ws/publiclighting/firmwaremanagement/UpdateFirmwareSteps.java b/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/glue/steps/ws/publiclighting/firmwaremanagement/UpdateFirmwareSteps.java index b88f7fc887c..bf4e67d2b0d 100644 --- a/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/glue/steps/ws/publiclighting/firmwaremanagement/UpdateFirmwareSteps.java +++ b/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/glue/steps/ws/publiclighting/firmwaremanagement/UpdateFirmwareSteps.java @@ -11,6 +11,7 @@ import io.cucumber.java.en.Then; import io.cucumber.java.en.When; +import java.util.Date; import java.util.GregorianCalendar; import java.util.Map; import javax.xml.datatype.DatatypeFactory; @@ -69,7 +70,9 @@ public void receivingAnUpdateFirmwareRequest(final Map requestPa if (requestParameters.containsKey(PlatformCommonKeys.SCHEDULED_TIME)) { final GregorianCalendar c = new GregorianCalendar(); c.setTime( - getDateTime(getString(requestParameters, PlatformCommonKeys.SCHEDULED_TIME)).toDate()); + Date.from( + getDateTime(getString(requestParameters, PlatformCommonKeys.SCHEDULED_TIME)) + .toInstant())); final XMLGregorianCalendar scheduledTime = DatatypeFactory.newInstance().newXMLGregorianCalendar(c); request.setScheduledTime(scheduledTime); diff --git a/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/glue/steps/ws/publiclighting/schedulemanagement/SetLightScheduleSteps.java b/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/glue/steps/ws/publiclighting/schedulemanagement/SetLightScheduleSteps.java index 096867a472c..a5ac2175a54 100644 --- a/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/glue/steps/ws/publiclighting/schedulemanagement/SetLightScheduleSteps.java +++ b/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/glue/steps/ws/publiclighting/schedulemanagement/SetLightScheduleSteps.java @@ -5,20 +5,18 @@ package org.opensmartgridplatform.cucumber.platform.publiclighting.glue.steps.ws.publiclighting.schedulemanagement; import static org.assertj.core.api.Assertions.assertThat; -import static org.opensmartgridplatform.cucumber.core.ReadSettingsHelper.getDate; -import static org.opensmartgridplatform.cucumber.core.ReadSettingsHelper.getEnum; -import static org.opensmartgridplatform.cucumber.core.ReadSettingsHelper.getShort; -import static org.opensmartgridplatform.cucumber.core.ReadSettingsHelper.getString; +import static org.opensmartgridplatform.cucumber.core.ReadSettingsHelper.*; import static org.opensmartgridplatform.cucumber.platform.core.CorrelationUidHelper.saveCorrelationUidInScenarioContext; import io.cucumber.java.en.Then; import io.cucumber.java.en.When; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.GregorianCalendar; import java.util.Map; import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeFactory; import org.apache.commons.lang3.StringUtils; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; import org.opensmartgridplatform.adapter.ws.schema.publiclighting.common.AsyncRequest; import org.opensmartgridplatform.adapter.ws.schema.publiclighting.common.OsgpResultType; import org.opensmartgridplatform.adapter.ws.schema.publiclighting.schedulemanagement.ActionTimeType; @@ -38,6 +36,7 @@ import org.opensmartgridplatform.cucumber.platform.publiclighting.PlatformPubliclightingDefaults; import org.opensmartgridplatform.cucumber.platform.publiclighting.PlatformPubliclightingKeys; import org.opensmartgridplatform.cucumber.platform.publiclighting.support.ws.publiclighting.PublicLightingScheduleManagementClient; +import org.opensmartgridplatform.shared.utils.JavaTimeHelpers; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -136,13 +135,14 @@ private void callAddSchedule( DatatypeFactory.newInstance() .newXMLGregorianCalendar( ((requestParameters - .get(PlatformPubliclightingKeys.SCHEDULE_SCHEDULEDTIME) - .isEmpty()) - ? DateTime.now() - : getDate( - requestParameters, PlatformPubliclightingKeys.SCHEDULE_SCHEDULEDTIME)) - .toDateTime(DateTimeZone.UTC) - .toGregorianCalendar())); + .get(PlatformPubliclightingKeys.SCHEDULE_SCHEDULEDTIME) + .isEmpty()) + ? GregorianCalendar.from(ZonedDateTime.now(ZoneId.of("UTC"))) + : GregorianCalendar.from( + getDate( + requestParameters, + PlatformPubliclightingKeys.SCHEDULE_SCHEDULEDTIME) + .withZoneSameInstant(ZoneId.of("UTC")))))); } for (int i = 0; i < countSchedules; i++) { @@ -186,13 +186,17 @@ private void addScheduleForRequest( schedule.setStartDay( DatatypeFactory.newInstance() .newXMLGregorianCalendar( - DateTime.parse(startDay).toDateTime(DateTimeZone.UTC).toGregorianCalendar())); + GregorianCalendar.from( + JavaTimeHelpers.parseToZonedDateTime(startDay) + .withZoneSameInstant(ZoneId.of("UTC"))))); } if (StringUtils.isNotBlank(endDay)) { schedule.setEndDay( DatatypeFactory.newInstance() .newXMLGregorianCalendar( - DateTime.parse(endDay).toDateTime(DateTimeZone.UTC).toGregorianCalendar())); + GregorianCalendar.from( + JavaTimeHelpers.parseToZonedDateTime(endDay) + .withZoneSameInstant(ZoneId.of("UTC"))))); } schedule.setActionTime(actionTime); schedule.setTime(time); diff --git a/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/glue/steps/ws/tariffswitching/schedulemanagement/SetTariffScheduleSteps.java b/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/glue/steps/ws/tariffswitching/schedulemanagement/SetTariffScheduleSteps.java index 30dd727cc9e..7c5bdb09a7c 100644 --- a/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/glue/steps/ws/tariffswitching/schedulemanagement/SetTariffScheduleSteps.java +++ b/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/glue/steps/ws/tariffswitching/schedulemanagement/SetTariffScheduleSteps.java @@ -13,11 +13,12 @@ import io.cucumber.java.en.Then; import io.cucumber.java.en.When; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.GregorianCalendar; import java.util.Map; import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeFactory; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; import org.opensmartgridplatform.adapter.ws.schema.tariffswitching.common.AsyncRequest; import org.opensmartgridplatform.adapter.ws.schema.tariffswitching.common.OsgpResultType; import org.opensmartgridplatform.adapter.ws.schema.tariffswitching.common.Page; @@ -35,6 +36,7 @@ import org.opensmartgridplatform.cucumber.platform.publiclighting.PlatformPubliclightingDefaults; import org.opensmartgridplatform.cucumber.platform.publiclighting.PlatformPubliclightingKeys; import org.opensmartgridplatform.cucumber.platform.publiclighting.support.ws.tariffswitching.TariffSwitchingScheduleManagementClient; +import org.opensmartgridplatform.shared.utils.JavaTimeHelpers; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -86,14 +88,15 @@ private void callAddSchedule( request.setScheduledTime( DatatypeFactory.newInstance() .newXMLGregorianCalendar( - ((requestParameters + GregorianCalendar.from( + (requestParameters .get(PlatformPubliclightingKeys.SCHEDULE_SCHEDULEDTIME) .isEmpty()) - ? DateTime.now() + ? ZonedDateTime.now(ZoneId.of("UTC")) : getDate( - requestParameters, PlatformPubliclightingKeys.SCHEDULE_SCHEDULEDTIME)) - .toDateTime(DateTimeZone.UTC) - .toGregorianCalendar())); + requestParameters, + PlatformPubliclightingKeys.SCHEDULE_SCHEDULEDTIME) + .withZoneSameInstant(ZoneId.of("UTC"))))); } for (int i = 0; i < countSchedules; i++) { @@ -141,13 +144,17 @@ private void addScheduleForRequest( schedule.setStartDay( DatatypeFactory.newInstance() .newXMLGregorianCalendar( - DateTime.parse(startDay).toDateTime(DateTimeZone.UTC).toGregorianCalendar())); + GregorianCalendar.from( + JavaTimeHelpers.parseToZonedDateTime(startDay) + .withZoneSameInstant(ZoneId.of("UTC"))))); } if (!endDay.isEmpty()) { schedule.setEndDay( DatatypeFactory.newInstance() .newXMLGregorianCalendar( - DateTime.parse(endDay).toDateTime(DateTimeZone.UTC).toGregorianCalendar())); + GregorianCalendar.from( + JavaTimeHelpers.parseToZonedDateTime(endDay) + .withZoneSameInstant(ZoneId.of("UTC"))))); } schedule.setTime(time); diff --git a/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/mocks/oslpdevice/MockOslpChannelHandler.java b/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/mocks/oslpdevice/MockOslpChannelHandler.java index 71000cfac89..d6a110898f6 100644 --- a/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/mocks/oslpdevice/MockOslpChannelHandler.java +++ b/integration-tests/cucumber-tests-platform-publiclighting/src/test/java/org/opensmartgridplatform/cucumber/platform/publiclighting/mocks/oslpdevice/MockOslpChannelHandler.java @@ -19,6 +19,7 @@ import java.security.PrivateKey; import java.text.ParseException; import java.time.LocalDateTime; +import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; @@ -31,7 +32,6 @@ import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.apache.commons.codec.binary.Base64; -import org.joda.time.DateTime; import org.opensmartgridplatform.cucumber.platform.publiclighting.PlatformPubliclightingDefaults; import org.opensmartgridplatform.oslp.Oslp; import org.opensmartgridplatform.oslp.Oslp.Message; @@ -531,9 +531,10 @@ void handle(final OslpEnvelope response) { public static class OutOfSequenceEvent { private final Long deviceId; private final String request; - private final DateTime timestamp; + private final ZonedDateTime timestamp; - public OutOfSequenceEvent(final Long deviceId, final String request, final DateTime timestamp) { + public OutOfSequenceEvent( + final Long deviceId, final String request, final ZonedDateTime timestamp) { this.deviceId = deviceId; this.request = request; this.timestamp = timestamp; @@ -547,7 +548,7 @@ public String getRequest() { return this.request; } - public DateTime getTimestamp() { + public ZonedDateTime getTimestamp() { return this.timestamp; } } diff --git a/integration-tests/cucumber-tests-platform-publiclighting/src/test/resources/features/publiclighting/osgp-adapter-ws-core/Firmwaremanagement/PendingFirmwareUpdate.feature b/integration-tests/cucumber-tests-platform-publiclighting/src/test/resources/features/publiclighting/osgp-adapter-ws-core/Firmwaremanagement/PendingFirmwareUpdate.feature index 856974e4fd1..c4e482d9da2 100644 --- a/integration-tests/cucumber-tests-platform-publiclighting/src/test/resources/features/publiclighting/osgp-adapter-ws-core/Firmwaremanagement/PendingFirmwareUpdate.feature +++ b/integration-tests/cucumber-tests-platform-publiclighting/src/test/resources/features/publiclighting/osgp-adapter-ws-core/Firmwaremanagement/PendingFirmwareUpdate.feature @@ -42,7 +42,7 @@ Feature: FirmwareManagement pending firmware update When the device sends a register device request to the platform over "" | DeviceIdentification | TEST1024010101010 | | DeviceUid | eHW0eEFzN0R2Okd5 | - | IpAddress | 127.0.0.2 | + | NetworkAddress | 127.0.0.2 | | DeviceType | SSLD | | HasSchedule | false | Then the register device response contains @@ -57,7 +57,7 @@ Feature: FirmwareManagement pending firmware update | DeviceType | SSLD | | DeviceUid | eHW0eEFzN0R2Okd5 | | HasSchedule | false | - | IpAddress | 127.0.0.2 | + | NetworkAddress | 127.0.0.2 | And a get firmware version "" message is sent to device "TEST1024010101010" with deviceUid "eHW0eEFzN0R2Okd5" And the device firmware file exists | DeviceIdentification | TEST1024010101010 | diff --git a/integration-tests/cucumber-tests-platform-publiclighting/src/test/resources/features/publiclighting/protocol-adapter-oslp/RegisterDevice.feature b/integration-tests/cucumber-tests-platform-publiclighting/src/test/resources/features/publiclighting/protocol-adapter-oslp/RegisterDevice.feature index 663af5d79de..a7977189bcb 100644 --- a/integration-tests/cucumber-tests-platform-publiclighting/src/test/resources/features/publiclighting/protocol-adapter-oslp/RegisterDevice.feature +++ b/integration-tests/cucumber-tests-platform-publiclighting/src/test/resources/features/publiclighting/protocol-adapter-oslp/RegisterDevice.feature @@ -17,7 +17,7 @@ Feature: ProtocolAdapterOSLP Device Registration | DeviceIdentification | TESTDEVICE0000001 | | Protocol | | | DeviceUid | eHW0eEFzN0R2Okd5 | - | IpAddress | 127.0.0.2 | + | NetworkAddress | 127.0.0.2 | | DeviceType | SSLD | | HasSchedule | false | Then the register device response contains @@ -27,7 +27,7 @@ Feature: ProtocolAdapterOSLP Device Registration | DeviceType | SSLD | | DeviceUid | eHW0eEFzN0R2Okd5 | | HasSchedule | false | - | IpAddress | 127.0.0.2 | + | NetworkAddress | 127.0.0.2 | Examples: | Protocol | @@ -49,7 +49,7 @@ Feature: ProtocolAdapterOSLP Device Registration | DeviceIdentification | TESTDEVICE0000001 | | Protocol | | | DeviceUid | eHW0eEFzN0R2Okd5 | - | IpAddress | 127.0.0.2 | + | NetworkAddress | 127.0.0.2 | | DeviceType | SSLD | Then the register device response contains | Status | OK | @@ -58,7 +58,7 @@ Feature: ProtocolAdapterOSLP Device Registration | DeviceType | SSLD | | DeviceUid | eHW0eEFzN0R2Okd5 | | HasSchedule | false | - | IpAddress | 127.0.0.2 | + | NetworkAddress | 127.0.0.2 | Examples: | Protocol | @@ -80,7 +80,7 @@ Feature: ProtocolAdapterOSLP Device Registration | DeviceIdentification | TESTDEVICE0000001 | | DeviceUid | eHW0eEFzN0R2Okd5 | | Protocol | | - | IpAddress | 127.0.0.2 | + | NetworkAddress | 127.0.0.2 | | DeviceType | SSLD | Then the register device response contains | Status | OK | @@ -89,31 +89,31 @@ Feature: ProtocolAdapterOSLP Device Registration | DeviceType | SSLD | | DeviceUid | eHW0eEFzN0R2Okd5 | | HasSchedule | false | - | IpAddress | 127.0.0.2 | + | NetworkAddress | 127.0.0.2 | Examples: | Protocol | | OSLP ELSTER | @OslpMockServer - Scenario Outline: Register device with IpAddress already in use by another device + Scenario Outline: Register device with NetworkAddress already in use by another device Given an ssld oslp device | DeviceIdentification | TESTDEVICE0000002 | | DeviceUid | eHW0eEFzN0R2Okd5 | | Protocol | | - | IpAddress | 127.0.0.3 | + | NetworkAddress | 127.0.0.3 | | DeviceType | SSLD | And an ssld oslp device | DeviceIdentification | TESTDEVICE0000003 | | DeviceUid | sdfhDFDFLS34FDLSd | - | IpAddress | 127.0.0.5 | + | NetworkAddress | 127.0.0.5 | | Protocol | | | DeviceType | SSLD | When the device sends a register device request to the platform over "" | DeviceIdentification | TESTDEVICE0000003 | | DeviceUid | fIX1fFGaO1S3Ple6 | | Protocol | | - | IpAddress | 127.0.0.3 | + | NetworkAddress | 127.0.0.3 | | DeviceType | SSLD | Then the register device response contains | Status | OK | @@ -121,13 +121,13 @@ Feature: ProtocolAdapterOSLP Device Registration | DeviceIdentification | TESTDEVICE0000003 | | DeviceUid | fIX1fFGaO1S3Ple6 | | Protocol | | - | IpAddress | 127.0.0.3 | + | NetworkAddress | 127.0.0.3 | | DeviceType | SSLD | And the ssld oslp device contains | DeviceIdentification | TESTDEVICE0000002 | | DeviceUid | eHW0eEFzN0R2Okd5 | | Protocol | | - | IpAddress | null | + | NetworkAddress | null | | DeviceType | SSLD | Examples: diff --git a/integration-tests/cucumber-tests-platform-smartmetering/pom.xml b/integration-tests/cucumber-tests-platform-smartmetering/pom.xml index b92a53e7157..9f8b6aff4a6 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/pom.xml +++ b/integration-tests/cucumber-tests-platform-smartmetering/pom.xml @@ -13,7 +13,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-integration-tests - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-integration-tests/pom.xml diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/PlatformSmartmeteringDefaults.java b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/PlatformSmartmeteringDefaults.java index 0febb458352..1118b3599a8 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/PlatformSmartmeteringDefaults.java +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/PlatformSmartmeteringDefaults.java @@ -6,6 +6,7 @@ import java.net.InetAddress; import java.net.UnknownHostException; +import java.time.Instant; import java.util.Date; import java.util.HashMap; import java.util.Map; @@ -60,24 +61,26 @@ public class PlatformSmartmeteringDefaults public static final String PROTOCOL = "DSMR"; public static final String PROTOCOL_VERSION = "4.2.2"; - public static final Map PORT_MAPPING = new HashMap<>(); + public static final Map PORT_MAPPING = new HashMap<>(); static { + // for DSMR 2.2 we will use the DSMR 4.2.2 simulator port, so we can test the config developed + // for DSMR 2.2 PORT_MAPPING.put( - 1024L, - new ProtocolInfo.Builder().withProtocol("DSMR").withProtocolVersion("4.2.2").build()); + new ProtocolInfo.Builder().withProtocol("DSMR").withProtocolVersion("2.2").build(), 1024L); PORT_MAPPING.put( - 1026L, new ProtocolInfo.Builder().withProtocol("DSMR").withProtocolVersion("2.2").build()); + new ProtocolInfo.Builder().withProtocol("DSMR").withProtocolVersion("4.2.2").build(), + 1024L); PORT_MAPPING.put( - 1027L, new ProtocolInfo.Builder().withProtocol("SMR").withProtocolVersion("5.0.0").build()); + new ProtocolInfo.Builder().withProtocol("SMR").withProtocolVersion("5.0.0").build(), 1027L); PORT_MAPPING.put( - 1028L, new ProtocolInfo.Builder().withProtocol("SMR").withProtocolVersion("5.1").build()); + new ProtocolInfo.Builder().withProtocol("SMR").withProtocolVersion("5.1").build(), 1028L); PORT_MAPPING.put( - 1029L, new ProtocolInfo.Builder().withProtocol("SMR").withProtocolVersion("5.2").build()); + new ProtocolInfo.Builder().withProtocol("SMR").withProtocolVersion("5.2").build(), 1029L); PORT_MAPPING.put( - 1030L, new ProtocolInfo.Builder().withProtocol("SMR").withProtocolVersion("5.5").build()); + new ProtocolInfo.Builder().withProtocol("SMR").withProtocolVersion("5.5").build(), 1030L); PORT_MAPPING.put( - 1031L, new ProtocolInfo.Builder().withProtocol("SMR").withProtocolVersion("4.3").build()); + new ProtocolInfo.Builder().withProtocol("SMR").withProtocolVersion("4.3").build(), 1031L); } public static final Long INVOCATION_COUNTER = 12345L; @@ -89,7 +92,7 @@ public class PlatformSmartmeteringDefaults public static final boolean SELECTIVE_ACCESS_SUPPORTED = false; public static final String SMART_METER_E = "SMART_METER_E"; public static final String SMART_METER_G = "SMART_METER_G"; - public static final Date TECHNICAL_INSTALLATION_DATE = new Date(); + public static final Instant TECHNICAL_INSTALLATION_DATE = Instant.now(); public static final Date VALID_TO = null; public static final Long VERSION = 0L; public static final boolean WITH_LIST_SUPPORTED = false; diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/PlatformSmartmeteringKeys.java b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/PlatformSmartmeteringKeys.java index 75fede84014..af0a0bce904 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/PlatformSmartmeteringKeys.java +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/PlatformSmartmeteringKeys.java @@ -61,6 +61,7 @@ public class PlatformSmartmeteringKeys public static final String MODULE_ACTIVE_FIRMWARE = "module_active_firmware"; public static final String COMM_MODULE_ACTIVE_FIRMWARE = "communication_module_active_firmware"; public static final String ACTIVE_FIRMWARE = "active_firmware"; + public static final String FIRMWARE_HASH = "FirmwareHash"; public static final String KEY_DEVICE_MASTERKEY = "Master_key"; public static final String KEY_DEVICE_AUTHENTICATIONKEY = "Authentication_key"; public static final String KEY_DEVICE_ENCRYPTIONKEY = "Encryption_key"; diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/builders/entities/BaseDeviceBuilder.java b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/builders/entities/BaseDeviceBuilder.java index a850b0e5e5b..14e853025d9 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/builders/entities/BaseDeviceBuilder.java +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/builders/entities/BaseDeviceBuilder.java @@ -6,18 +6,18 @@ import java.net.InetAddress; import java.net.UnknownHostException; -import java.util.Date; +import java.time.Instant; import java.util.Map; import org.apache.commons.lang3.StringUtils; import org.opensmartgridplatform.cucumber.core.ReadSettingsHelper; import org.opensmartgridplatform.cucumber.platform.PlatformDefaults; import org.opensmartgridplatform.cucumber.platform.PlatformKeys; -import org.opensmartgridplatform.cucumber.platform.inputparsers.DateInputParser; import org.opensmartgridplatform.cucumber.platform.smartmetering.PlatformSmartmeteringDefaults; import org.opensmartgridplatform.cucumber.platform.smartmetering.PlatformSmartmeteringKeys; import org.opensmartgridplatform.domain.core.entities.DeviceModel; import org.opensmartgridplatform.domain.core.entities.ProtocolInfo; import org.opensmartgridplatform.domain.core.valueobjects.DeviceLifecycleStatus; +import org.opensmartgridplatform.shared.utils.JavaTimeHelpers; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -42,7 +42,7 @@ public abstract class BaseDeviceBuilder> { String alias = PlatformSmartmeteringDefaults.ALIAS; boolean inMaintenance = PlatformSmartmeteringDefaults.IN_MAINTENANCE; String gatewayDeviceIdentification = PlatformSmartmeteringDefaults.GATEWAY_DEVICE_IDENTIFICATION; - Date technicalInstallationDate = PlatformSmartmeteringDefaults.TECHNICAL_INSTALLATION_DATE; + Instant technicalInstallationDate = PlatformSmartmeteringDefaults.TECHNICAL_INSTALLATION_DATE; DeviceModel deviceModel = PlatformSmartmeteringDefaults.DEVICE_MODEL; DeviceLifecycleStatus deviceLifeCycleStatus = PlatformDefaults.DEFAULT_DEVICE_LIFECYCLE_STATUS; @@ -143,7 +143,7 @@ public T setGatewayDevice(final String gatewayDeviceIdentification) { return (T) this; } - public T setTechnicalInstallationDate(final Date technicalInstallationDate) { + public T setTechnicalInstallationDate(final Instant technicalInstallationDate) { this.technicalInstallationDate = technicalInstallationDate; return (T) this; } @@ -208,8 +208,9 @@ public T withSettings(final Map inputSettings) { } if (inputSettings.containsKey(PlatformSmartmeteringKeys.TECHNICAL_INSTALLATION_DATE)) { this.setTechnicalInstallationDate( - DateInputParser.parse( - inputSettings.get(PlatformSmartmeteringKeys.TECHNICAL_INSTALLATION_DATE))); + JavaTimeHelpers.parseToZonedDateTime( + inputSettings.get(PlatformSmartmeteringKeys.TECHNICAL_INSTALLATION_DATE)) + .toInstant()); } if (inputSettings.containsKey(PlatformKeys.KEY_DEVICE_LIFECYCLE_STATUS)) { this.setDeviceLifecycleStatus( diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/builders/entities/DeviceBuilder.java b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/builders/entities/DeviceBuilder.java index cf452a79bed..2914bc78194 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/builders/entities/DeviceBuilder.java +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/builders/entities/DeviceBuilder.java @@ -53,7 +53,7 @@ public Device build() { device.setTechnicalInstallationDate(this.technicalInstallationDate); // updateRegistrationData sets the status to IN_USE, so setting of any // other status has to be done after that. - device.updateRegistrationData(this.networkAddress, this.deviceType); + device.updateRegistrationData(this.networkAddress.getHostAddress(), this.deviceType); device.setDeviceLifecycleStatus(this.deviceLifeCycleStatus); return device; diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/builders/entities/DlmsDeviceBuilder.java b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/builders/entities/DlmsDeviceBuilder.java index 3764239bf25..b407cb710f8 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/builders/entities/DlmsDeviceBuilder.java +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/builders/entities/DlmsDeviceBuilder.java @@ -42,6 +42,7 @@ public class DlmsDeviceBuilder implements CucumberBuilder { private String protocolName = PlatformSmartmeteringDefaults.PROTOCOL; private String protocolVersion = PlatformSmartmeteringDefaults.PROTOCOL_VERSION; private Long invocationCounter = PlatformSmartmeteringDefaults.INVOCATION_COUNTER; + private String firmwareHash = null; private String timezone; @@ -166,6 +167,11 @@ public DlmsDeviceBuilder setInvocationCounter(final Long invocationCounter) { return this; } + public DlmsDeviceBuilder setFirmwareHash(final String firmwareHash) { + this.firmwareHash = firmwareHash; + return this; + } + @Override public DlmsDeviceBuilder withSettings(final Map inputSettings) { if (inputSettings.containsKey(PlatformSmartmeteringKeys.DEVICE_IDENTIFICATION)) { @@ -251,6 +257,9 @@ public DlmsDeviceBuilder withSettings(final Map inputSettings) { if (inputSettings.containsKey(PlatformSmartmeteringKeys.KEY_DEVICE_TIMEZONE)) { this.setTimezone(getString(inputSettings, PlatformSmartmeteringKeys.KEY_DEVICE_TIMEZONE)); } + if (inputSettings.containsKey(PlatformSmartmeteringKeys.FIRMWARE_HASH)) { + this.setFirmwareHash(getString(inputSettings, PlatformSmartmeteringKeys.FIRMWARE_HASH)); + } /** * For port/logical_id we want to be able to override the default value to be null to enable @@ -263,8 +272,9 @@ public DlmsDeviceBuilder withSettings(final Map inputSettings) { this.setLogicalId(Long.parseLong(inputSettings.get(PlatformSmartmeteringKeys.LOGICAL_ID))); } } - if (inputSettings.containsKey(PlatformSmartmeteringKeys.PORT)) { - if (inputSettings.get(PlatformSmartmeteringKeys.PORT).isEmpty()) { + final String port = inputSettings.get(PlatformSmartmeteringKeys.PORT); + if (hasPortDefined(inputSettings, port)) { + if (port.isEmpty()) { this.setPort(null); } else { this.setPort(Long.parseLong(inputSettings.get(PlatformSmartmeteringKeys.PORT))); @@ -276,6 +286,11 @@ public DlmsDeviceBuilder withSettings(final Map inputSettings) { return this; } + private static boolean hasPortDefined( + final Map inputSettings, final String port) { + return inputSettings.containsKey(PlatformSmartmeteringKeys.PORT) && port != null; + } + private void setTimezone(final String timezone) { this.timezone = timezone; } @@ -308,15 +323,16 @@ public DlmsDevice build() { dlmsDevice.setProtocol(this.protocolName, this.protocolVersion); dlmsDevice.setInvocationCounter(this.invocationCounter); dlmsDevice.setTimezone(this.timezone); + dlmsDevice.setFirmwareHash(this.firmwareHash); return dlmsDevice; } public Long getPortBasedOnProtocolInfo(final String protocol, final String protocolVersion) { - return PlatformSmartmeteringDefaults.PORT_MAPPING.entrySet().stream() - .filter(e -> this.protocolsAreEqual(protocol, protocolVersion, e.getValue())) + return PlatformSmartmeteringDefaults.PORT_MAPPING.keySet().stream() + .filter(protocol1 -> this.protocolsAreEqual(protocol, protocolVersion, protocol1)) .findFirst() - .map(e2 -> e2.getKey()) + .map(protocol2 -> PlatformSmartmeteringDefaults.PORT_MAPPING.get(protocol2)) .orElseThrow( () -> new IllegalArgumentException( diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/builders/entities/SecretBuilder.java b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/builders/entities/SecretBuilder.java index 495afa4d6fc..95951f46ae5 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/builders/entities/SecretBuilder.java +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/builders/entities/SecretBuilder.java @@ -4,7 +4,7 @@ package org.opensmartgridplatform.cucumber.platform.smartmetering.builders.entities; -import java.util.Date; +import java.time.Instant; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.SecurityKeyType; import org.opensmartgridplatform.cucumber.platform.core.builders.Builder; import org.opensmartgridplatform.cucumber.platform.smartmetering.SecurityKey; @@ -19,7 +19,7 @@ public class SecretBuilder implements Builder { private String key = SecurityKey.SECURITY_KEY_A.getDatabaseKey(); private SecretStatus status; private String deviceIdentification; - private Date creationTime; + private Instant creationTime; private DbEncryptionKeyReference encryptionKeyReference; public SecretBuilder withSecretType(final SecretType secretType) { @@ -57,7 +57,7 @@ public SecretBuilder withSecretStatus(final SecretStatus status) { return this; } - public SecretBuilder withCreationTime(final Date creationTime) { + public SecretBuilder withCreationTime(final Instant creationTime) { this.creationTime = creationTime; return this; } @@ -75,7 +75,7 @@ public DbEncryptedSecret build() { securityKey.setSecretType(this.secretType); securityKey.setEncodedSecret(this.key); securityKey.setSecretStatus(this.status == null ? SecretStatus.ACTIVE : this.status); - securityKey.setCreationTime(this.creationTime == null ? new Date() : this.creationTime); + securityKey.setCreationTime(this.creationTime == null ? Instant.now() : this.creationTime); securityKey.setEncryptionKeyReference(this.encryptionKeyReference); return securityKey; } diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/builders/entities/SmartMeterBuilder.java b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/builders/entities/SmartMeterBuilder.java index ee2d33a3eae..822ba06e5bd 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/builders/entities/SmartMeterBuilder.java +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/builders/entities/SmartMeterBuilder.java @@ -77,7 +77,11 @@ public SmartMeter build() { new GpsCoordinates(this.gpsLatitude, this.gpsLongitude)); device.setActivated(this.isActivated); - device.updateRegistrationData(this.networkAddress, this.deviceType); + if (this.networkAddress != null) { + device.updateRegistrationData(this.networkAddress.getHostAddress(), this.deviceType); + } else { + device.updateRegistrationData(null, this.deviceType); + } device.setBtsId(this.baseTransceiverStationId); device.setCellId(this.cellId); diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/database/DlmsDatabase.java b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/database/DlmsDatabase.java index 411000af810..a545f18807f 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/database/DlmsDatabase.java +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/database/DlmsDatabase.java @@ -4,7 +4,7 @@ package org.opensmartgridplatform.cucumber.platform.smartmetering.database; -import java.util.Date; +import java.time.Instant; import java.util.TimeZone; import org.opensmartgridplatform.adapter.protocol.dlms.domain.repositories.DlmsDeviceRepository; import org.opensmartgridplatform.secretmanagement.application.domain.DbEncryptionKeyReference; @@ -34,12 +34,12 @@ public void prepareDatabaseForScenario() { this.secretRepository.deleteAllInBatch(); if (this.encryptionKeyRepository.count() == 0) { - final DbEncryptionKeyReference jreEncryptionKey = this.getJreEncryptionKey(new Date()); + final DbEncryptionKeyReference jreEncryptionKey = this.getJreEncryptionKey(Instant.now()); this.encryptionKeyRepository.save(jreEncryptionKey); } } - private DbEncryptionKeyReference getJreEncryptionKey(final Date now) { + private DbEncryptionKeyReference getJreEncryptionKey(final Instant now) { final DbEncryptionKeyReference jreEncryptionKey = new DbEncryptionKeyReference(); jreEncryptionKey.setEncryptionProviderType(EncryptionProviderType.JRE); jreEncryptionKey.setReference("1"); diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/database/device/DlmsDeviceSteps.java b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/database/device/DlmsDeviceSteps.java index 7654ebd00a1..c0c9ba2ca4b 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/database/device/DlmsDeviceSteps.java +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/database/device/DlmsDeviceSteps.java @@ -19,6 +19,7 @@ import static org.opensmartgridplatform.cucumber.platform.smartmetering.PlatformSmartmeteringKeys.KEY_DEVICE_ENCRYPTIONKEY; import static org.opensmartgridplatform.cucumber.platform.smartmetering.PlatformSmartmeteringKeys.KEY_DEVICE_FIRMWARE_UPDATE_KEY; import static org.opensmartgridplatform.cucumber.platform.smartmetering.PlatformSmartmeteringKeys.KEY_DEVICE_MASTERKEY; +import static org.opensmartgridplatform.cucumber.platform.smartmetering.PlatformSmartmeteringKeys.LLS1_ACTIVE; import static org.opensmartgridplatform.cucumber.platform.smartmetering.PlatformSmartmeteringKeys.MBUS_DEFAULT_KEY; import static org.opensmartgridplatform.cucumber.platform.smartmetering.PlatformSmartmeteringKeys.MBUS_FIRMWARE_UPDATE_AUTHENTICATION_KEY; import static org.opensmartgridplatform.cucumber.platform.smartmetering.PlatformSmartmeteringKeys.MBUS_P0_KEY; @@ -34,10 +35,11 @@ import io.cucumber.java.en.Given; import io.cucumber.java.en.Then; import io.cucumber.java.en.When; +import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -241,6 +243,12 @@ public void theDlmsDeviceWithIdentificationExistsWithProperties( assertThat(device.getTimezone()) .as(PlatformKeys.DLMS_DEVICE_TIMEZONE) .isEqualTo(dlmsDeviceAttributes.get(DLMS_DEVICE_TIMEZONE)); + + if (dlmsDeviceAttributes.containsKey(LLS1_ACTIVE)) { + assertThat(device.isLls1Active()) + .as(LLS1_ACTIVE) + .isEqualTo(Boolean.valueOf(dlmsDeviceAttributes.get(LLS1_ACTIVE))); + } } @Then("^the smart meter is registered in the core database$") @@ -702,8 +710,7 @@ private void createDlmsDeviceInSecretManagementDatabase( final String deviceType = inputSettings.getOrDefault(PlatformSmartmeteringKeys.DEVICE_TYPE, SMART_METER_E); final List secretBuilders = new ArrayList<>(); - if (inputSettings.containsKey(PlatformSmartmeteringKeys.LLS1_ACTIVE) - && "true".equals(inputSettings.get(PlatformSmartmeteringKeys.LLS1_ACTIVE))) { + if (inputSettings.containsKey(LLS1_ACTIVE) && "true".equals(inputSettings.get(LLS1_ACTIVE))) { secretBuilders.add( this.getAppropriateSecretBuilder(PlatformSmartmeteringKeys.PASSWORD, inputSettings)); secretBuilders.add(this.getAppropriateSecretBuilder(KEY_DEVICE_ENCRYPTIONKEY, inputSettings)); @@ -736,7 +743,7 @@ private void createDlmsDeviceInSecretManagementDatabase( } final DbEncryptionKeyReference encryptionKeyRef = this.encryptionKeyRepository - .findByTypeAndValid(EncryptionProviderType.JRE, new Date()) + .findByTypeAndValid(EncryptionProviderType.JRE, Instant.now()) .iterator() .next(); secretBuilders.stream() @@ -852,7 +859,7 @@ public void simulateFailureOfChangeFromPreviousKeyOfDevice( final DbEncryptionKeyReference encryptionKeyRef = this.encryptionKeyRepository - .findByTypeAndValid(EncryptionProviderType.JRE, new Date()) + .findByTypeAndValid(EncryptionProviderType.JRE, Instant.now()) .iterator() .next(); final DbEncryptedSecret secret = @@ -862,7 +869,7 @@ public void simulateFailureOfChangeFromPreviousKeyOfDevice( .withKey(key) .withSecretStatus(SecretStatus.ACTIVE) .withEncryptionKeyReference(encryptionKeyRef) - .withCreationTime(new Date()) + .withCreationTime(Instant.now()) .build(); this.encryptedSecretRepository.save(secret); } @@ -896,7 +903,7 @@ private void registerNewKeys(final long minutesAgo, final Map in } final DbEncryptionKeyReference encryptionKeyRef = this.encryptionKeyRepository - .findByTypeAndValid(EncryptionProviderType.JRE, new Date()) + .findByTypeAndValid(EncryptionProviderType.JRE, Instant.now()) .iterator() .next(); for (int i = 0; i < secretTypesToCreate.size(); i++) { @@ -910,7 +917,7 @@ private void registerNewKeys(final long minutesAgo, final Map in .withKey(key) .withSecretStatus(SecretStatus.NEW) .withEncryptionKeyReference(encryptionKeyRef) - .withCreationTime(new Date(System.currentTimeMillis() - (minutesAgo * 60000L))) + .withCreationTime(Instant.now().minus(minutesAgo * 60000L, ChronoUnit.MILLIS)) .build(); this.encryptedSecretRepository.save(secret); } diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/database/ws/WsSmartMeteringResponseDataSteps.java b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/database/ws/WsSmartMeteringResponseDataSteps.java index 03a8ec82657..42f7cf0fe9e 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/database/ws/WsSmartMeteringResponseDataSteps.java +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/database/ws/WsSmartMeteringResponseDataSteps.java @@ -52,7 +52,7 @@ public ResponseData aResponseDataRecord(final Map settings) { fld.setAccessible(true); fld.set( responseData, - DateTimeHelper.getDateTime(settings.get(PlatformKeys.KEY_CREATION_TIME)).toDate()); + DateTimeHelper.getDateTime(settings.get(PlatformKeys.KEY_CREATION_TIME)).toInstant()); this.smartMeteringResponseDataRepository.saveAndFlush(responseData); } } catch (final Exception e) { diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/simulator/SimulatedConfigurationObjectSteps.java b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/simulator/SimulatedConfigurationObjectSteps.java index 4b4f1d6f4a4..bd8e943017e 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/simulator/SimulatedConfigurationObjectSteps.java +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/simulator/SimulatedConfigurationObjectSteps.java @@ -6,7 +6,6 @@ import static org.assertj.core.api.Assertions.assertThat; -import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.ObjectNode; @@ -14,6 +13,7 @@ import io.cucumber.java.en.Then; import java.util.List; import java.util.Map; +import lombok.extern.slf4j.Slf4j; import org.openmuc.jdlms.ObisCode; import org.opensmartgridplatform.adapter.ws.schema.smartmetering.configuration.ConfigurationFlag; import org.opensmartgridplatform.adapter.ws.schema.smartmetering.configuration.ConfigurationFlags; @@ -24,6 +24,7 @@ import org.opensmartgridplatform.dlms.interfaceclass.attribute.DataAttribute; import org.springframework.beans.factory.annotation.Autowired; +@Slf4j public class SimulatedConfigurationObjectSteps { private static final int CLASS_ID = InterfaceClass.DATA.id(); @@ -35,8 +36,9 @@ public class SimulatedConfigurationObjectSteps { @Autowired private JsonObjectCreator jsonObjectCreator; - @Given("device simulation of {string} with configuration object") - public void deviceSimulationOfConfigurationObject( + @Given( + "device simulation of {string} with configuration object values in structure type value attribute") + public void deviceSimulationOfConfigurationObjectValuesInStructureTypeValueAttribute( final String deviceIdentification, final Map settings) { this.deviceSimulatorSteps.deviceSimulationOfEquipmentIdentifier(deviceIdentification); @@ -49,16 +51,52 @@ public void deviceSimulationOfConfigurationObject( CLASS_ID, OBIS_CODE, ATTRIBUTE_ID_VALUE, attributeValue, OBJECT_DESCRIPTION); } - @Then("device simulation of {string} should be with configuration object") - public void deviceSimulationOfShouldBeWithConfigurationObject( + @Given( + "device simulation of {string} with configuration object values in bitstring type value attribute") + public void deviceSimulationOfConfigurationObjectValuesInBitstringTypeValueAttribute( final String deviceIdentification, final Map settings) { + this.deviceSimulatorSteps.deviceSimulationOfEquipmentIdentifier(deviceIdentification); + + final ConfigurationObject configurationObject = + ConfigurationObjectFactory.fromParameterMap(settings); + final ObjectNode attributeValue = + this.createBitstringForConfigurationObject(configurationObject, new JsonNodeFactory(false)); + this.deviceSimulatorSteps.setDlmsAttributeValue( + CLASS_ID, OBIS_CODE, ATTRIBUTE_ID_VALUE, attributeValue, OBJECT_DESCRIPTION); + } + + @Then( + "device simulation should have values in a bitstring type value attribute of the configuration object") + public void + deviceSimulationShouldHaveValuesInABitstringTypeValueAttributeOfTheConfigurationObject( + final Map settings) { + + final ConfigurationObject expectedConfigurationObject = + ConfigurationObjectFactory.fromParameterMap(settings); + final ObjectNode expectedValue = + this.createBitstringForConfigurationObject( + expectedConfigurationObject, new JsonNodeFactory(false)); + + this.assertDlmsAttributeValue(expectedValue); + } + + @Then( + "device simulation should have values in a structure type value attribute of the configuration object") + public void + deviceSimulationShouldHaveValuesInAStructureTypeValueAttributeOfTheConfigurationObject( + final Map settings) { + final ConfigurationObject expectedConfigurationObject = ConfigurationObjectFactory.fromParameterMap(settings); final ObjectNode expectedValue = this.createStructureForConfigurationObject( expectedConfigurationObject, new JsonNodeFactory(false)); + this.assertDlmsAttributeValue(expectedValue); + } + + private void assertDlmsAttributeValue(final ObjectNode expectedValue) { final ObjectNode actualValue = this.deviceSimulatorSteps.getDlmsAttributeValue( CLASS_ID, OBIS_CODE, ATTRIBUTE_ID_VALUE, OBJECT_DESCRIPTION); @@ -71,22 +109,35 @@ private ObjectNode createStructureForConfigurationObject( final ObjectNode structureForConfigurationObject = jsonNodeFactory.objectNode(); this.jsonObjectCreator.setTypeNode(structureForConfigurationObject, "structure"); + final ArrayNode configurationObjectElements = jsonNodeFactory.arrayNode(); + configurationObjectElements.add( this.createGprsOperationModeForConfigurationObject( configurationObject.getGprsOperationMode(), jsonNodeFactory)); - configurationObjectElements.add( - this.createFlagsForConfigurationObject( - configurationObject.getConfigurationFlags(), jsonNodeFactory)); + + final String flagsString = this.createFlagString(configurationObject.getConfigurationFlags()); + final ObjectNode flagsForConfigurationObject = + this.jsonObjectCreator.createAttributeValue("bit-string", flagsString, jsonNodeFactory); + configurationObjectElements.add(flagsForConfigurationObject); + structureForConfigurationObject.set("value", configurationObjectElements); return structureForConfigurationObject; } + private ObjectNode createBitstringForConfigurationObject( + final ConfigurationObject configurationObject, final JsonNodeFactory jsonNodeFactory) { + + final String flagsString = this.createFlagString(configurationObject.getConfigurationFlags()); + + return this.jsonObjectCreator.createAttributeValue("bit-string", flagsString, jsonNodeFactory); + } + private ObjectNode createGprsOperationModeForConfigurationObject( final GprsOperationModeType gprsOperationMode, final JsonNodeFactory jsonNodeFactory) { - String textValue; + final String textValue; if (gprsOperationMode == GprsOperationModeType.ALWAYS_ON) { textValue = "1"; } else if (gprsOperationMode == GprsOperationModeType.TRIGGERED) { @@ -97,9 +148,7 @@ private ObjectNode createGprsOperationModeForConfigurationObject( return this.jsonObjectCreator.createAttributeValue("enumerate", textValue, jsonNodeFactory); } - private JsonNode createFlagsForConfigurationObject( - final ConfigurationFlags configurationFlags, final JsonNodeFactory jsonNodeFactory) { - + private String createFlagString(final ConfigurationFlags configurationFlags) { final int bitStringLength = 16; final char[] flags = new char[bitStringLength]; for (int i = 0; i < bitStringLength; i++) { @@ -114,7 +163,6 @@ private JsonNode createFlagsForConfigurationObject( } } } - return this.jsonObjectCreator.createAttributeValue( - "bit-string", new String(flags), jsonNodeFactory); + return new String(flags); } } diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/ws/core/audittrail/AuditTrail.java b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/ws/core/audittrail/AuditTrail.java index 437ec5d2452..9c5b41784aa 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/ws/core/audittrail/AuditTrail.java +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/ws/core/audittrail/AuditTrail.java @@ -29,7 +29,7 @@ public class AuditTrail { @Autowired private DeviceLogItemPagingRepository deviceLogItemRepository; - @Then("^the audit trail contains multiple retry log records$") + @Then("^the audit trail contains a retry log records$") public void theAuditTrailContainsMultipleRetryLogRecords(final Map settings) throws Throwable { final String deviceIdentification = @@ -38,7 +38,7 @@ public void theAuditTrailContainsMultipleRetryLogRecords(final Map filter = dli -> Pattern.matches(PATTERN_RETRY_OPERATION, dli.getDecodedMessage()); diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/ws/smartmetering/notification/SmartMeteringNotificationSteps.java b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/ws/smartmetering/notification/SmartMeteringNotificationSteps.java index a77af901f4d..b2a7cc2a20c 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/ws/smartmetering/notification/SmartMeteringNotificationSteps.java +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/ws/smartmetering/notification/SmartMeteringNotificationSteps.java @@ -4,8 +4,12 @@ package org.opensmartgridplatform.cucumber.platform.smartmetering.glue.steps.ws.smartmetering.notification; +import static org.assertj.core.api.Assertions.assertThat; + import io.cucumber.java.en.Then; +import java.util.Map; import java.util.concurrent.TimeUnit; +import org.apache.commons.beanutils.BeanUtils; import org.junit.jupiter.api.Assertions; import org.opensmartgridplatform.adapter.ws.schema.smartmetering.notification.Notification; import org.opensmartgridplatform.cucumber.core.ScenarioContext; @@ -54,9 +58,27 @@ public void noNotificationIsSent() throws Throwable { this.waitForNotification(MAX_WAIT_FOR_NOTIFICATION, correlationUid, false); } - private void waitForNotification( - final int maxTimeOut, final String correlationUid, final boolean expectCorrelationUid) - throws Throwable { + @Then("^check notification$") + public void checkNotification(final Map notificationData) throws Throwable { + final String correlationUid = + (String) ScenarioContext.current().get(PlatformKeys.KEY_CORRELATION_UID); + if (correlationUid == null) { + Assertions.fail( + "No " + + PlatformKeys.KEY_CORRELATION_UID + + " stored in the scenario context. Unable to make assumptions as to whether a notification has been sent."); + } + final Notification notification = + this.waitForNotification(MAX_WAIT_FOR_NOTIFICATION, correlationUid, true); + + assertThat(notification).isNotNull(); + for (final String key : notificationData.keySet()) { + assertThat(BeanUtils.getProperty(notification, key)).isEqualTo(notificationData.get(key)); + } + } + + private Notification waitForNotification( + final int maxTimeOut, final String correlationUid, final boolean expectCorrelationUid) { LOGGER.info( "Waiting to make sure {} notification is received for correlation UID {} for at most {} milliseconds.", @@ -70,7 +92,7 @@ private void waitForNotification( final boolean gotExpectedNotification = expectCorrelationUid && notification != null; final boolean didNotGetUnexpectedNotification = !expectCorrelationUid && notification == null; if (gotExpectedNotification || didNotGetUnexpectedNotification) { - return; + return notification; } if (expectCorrelationUid) { @@ -83,5 +105,7 @@ private void waitForNotification( } else { Assertions.fail("Received notification for correlation UID: " + correlationUid); } + + return notification; } } diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/ws/smartmetering/smartmeteringbundle/BundleSteps.java b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/ws/smartmetering/smartmeteringbundle/BundleSteps.java index 05df87188a7..a70fde4278a 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/ws/smartmetering/smartmeteringbundle/BundleSteps.java +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/ws/smartmetering/smartmeteringbundle/BundleSteps.java @@ -156,7 +156,8 @@ private Map additionalSoapHeaders(final Map sett (localPartOfName, value) -> { if (dateTimeInMillisHeaders.contains(localPartOfName)) { extraHeaders.put( - localPartOfName, Long.toString(DateTimeHelper.getDateTime(value).getMillis())); + localPartOfName, + Long.toString(DateTimeHelper.getDateTime(value).toInstant().toEpochMilli())); } else { extraHeaders.put(localPartOfName, value); } diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/ws/smartmetering/smartmeteringbundle/BundledGetConfigurationObjectSteps.java b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/ws/smartmetering/smartmeteringbundle/BundledGetConfigurationObjectSteps.java index 4822aaa7769..75622183aab 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/ws/smartmetering/smartmeteringbundle/BundledGetConfigurationObjectSteps.java +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/ws/smartmetering/smartmeteringbundle/BundledGetConfigurationObjectSteps.java @@ -10,6 +10,7 @@ import io.cucumber.java.en.Given; import io.cucumber.java.en.Then; import java.util.Map; +import org.apache.commons.lang3.StringUtils; import org.opensmartgridplatform.adapter.ws.schema.smartmetering.bundle.GetConfigurationObjectRequest; import org.opensmartgridplatform.adapter.ws.schema.smartmetering.bundle.GetConfigurationObjectResponse; import org.opensmartgridplatform.adapter.ws.schema.smartmetering.common.Response; @@ -18,6 +19,8 @@ public class BundledGetConfigurationObjectSteps extends BaseBundleSteps { + static final String GPRS_OPERATION_MODE = "GprsOperationMode"; + @Given("^the bundle request contains a get configuration object action$") public void theBundleRequestContainsAGetConfigurationObject() throws Throwable { @@ -49,9 +52,14 @@ public void theBundleResponseShouldContainAConfigurationObjectResponse( final ConfigurationObject configurationObject = ((GetConfigurationObjectResponse) response).getConfigurationObject(); - assertThat(configurationObject.getGprsOperationMode().toString()) - .as("The gprs operation mode is not equal") - .isEqualTo(values.get("GprsOperationMode")); + if (values.containsKey(GPRS_OPERATION_MODE) + && StringUtils.isNotBlank(values.get(GPRS_OPERATION_MODE))) { + assertThat(configurationObject.getGprsOperationMode()) + .as("The gprs operation mode is not equal") + .hasToString(values.get(GPRS_OPERATION_MODE)); + } else { + assertThat(configurationObject.getGprsOperationMode()).isNull(); + } configurationObject .getConfigurationFlags() diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/ws/smartmetering/smartmeteringbundle/BundledGetPowerQualityProfileDataSteps.java b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/ws/smartmetering/smartmeteringbundle/BundledGetPowerQualityProfileDataSteps.java index 2c0e3a92524..7034f26f5b9 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/ws/smartmetering/smartmeteringbundle/BundledGetPowerQualityProfileDataSteps.java +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/ws/smartmetering/smartmeteringbundle/BundledGetPowerQualityProfileDataSteps.java @@ -6,22 +6,52 @@ import static org.assertj.core.api.Assertions.assertThat; +import io.cucumber.datatable.DataTable; import io.cucumber.java.en.Given; import io.cucumber.java.en.Then; +import java.io.IOException; +import java.math.BigDecimal; import java.math.BigInteger; +import java.security.GeneralSecurityException; +import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Optional; +import javax.xml.datatype.XMLGregorianCalendar; +import lombok.extern.slf4j.Slf4j; +import org.openmuc.jdlms.ObisCode; import org.opensmartgridplatform.adapter.ws.schema.smartmetering.bundle.GetPowerQualityProfileRequest; +import org.opensmartgridplatform.adapter.ws.schema.smartmetering.bundle.GetPowerQualityProfileResponse; import org.opensmartgridplatform.adapter.ws.schema.smartmetering.common.CaptureObject; +import org.opensmartgridplatform.adapter.ws.schema.smartmetering.common.ObisCodeValues; +import org.opensmartgridplatform.adapter.ws.schema.smartmetering.common.OsgpUnitType; import org.opensmartgridplatform.adapter.ws.schema.smartmetering.common.ProfileEntry; +import org.opensmartgridplatform.adapter.ws.schema.smartmetering.common.ProfileEntryValue; import org.opensmartgridplatform.adapter.ws.schema.smartmetering.common.Response; -import org.opensmartgridplatform.adapter.ws.schema.smartmetering.monitoring.GetPowerQualityProfileResponse; import org.opensmartgridplatform.adapter.ws.schema.smartmetering.monitoring.PowerQualityProfileData; -import org.opensmartgridplatform.cucumber.platform.helpers.SettingsHelper; +import org.opensmartgridplatform.cucumber.core.ScenarioContext; import org.opensmartgridplatform.cucumber.platform.smartmetering.builders.GetPowerQualityProfileRequestBuilder; +import org.opensmartgridplatform.domain.core.valueobjects.smartmetering.SignalQualityType; +import org.opensmartgridplatform.shared.exceptionhandling.WebServiceSecurityException; +@Slf4j public class BundledGetPowerQualityProfileDataSteps extends BaseBundleSteps { + public static final String CLASS_ID = "classId"; + + public static final String LOGICAL_NAME = "logicalName"; + + public static final String DESCRIPTION = "description"; + + public static final String ATTRIBUTE_INDEX = "attributeIndex"; + + public static final String DATA_INDEX = "dataIndex"; + + public static final String UNIT = "unit"; + public static final String VALUE_TYPE = "value_type"; + + private static final String LAST_RESPONSE = "last_response"; + @Given("^the bundle request contains a get power quality profile request with parameters$") public void theBundleRequestContainsAGetPowerQualityProfileRequestAction( final Map parameters) throws Throwable { @@ -32,85 +62,197 @@ public void theBundleRequestContainsAGetPowerQualityProfileRequestAction( this.addActionToBundleRequest(action); } - @Then("^the bundle response should contain a power quality profile response with values$") + @Then( + "^the same bundle response should contain a power quality profile response with (\\d++) values for profile \"([^\"]*)\"$") + public void theSameBundleResponseShouldContainAGetPowerQualityProfileResponse( + final int nrOfValues, final String profileLogicalName, final DataTable valuesDataTable) + throws Throwable { + + final Response response = (Response) ScenarioContext.current().get(LAST_RESPONSE); + this.theBundleResponseShouldContainAGetPowerQualityProfileResponse( + nrOfValues, profileLogicalName, response, valuesDataTable); + } + + @Then( + "^the bundle response should contain a power quality profile response with (\\d++) values for profile \"([^\"]*)\"$") public void theBundleResponseShouldContainAGetPowerQualityProfileResponse( - final Map values) throws Throwable { + final int nrOfValues, final String profileLogicalName, final DataTable valuesDataTable) + throws Throwable { + + final Response response = this.getNextBundleResponse(); + ScenarioContext.current().put(LAST_RESPONSE, response); + + this.theBundleResponseShouldContainAGetPowerQualityProfileResponse( + nrOfValues, profileLogicalName, response, valuesDataTable); + } + + @Then("^the bundle response should contain an empty power quality profile response$") + public void theBundleResponseShouldContainAnEmptyGetPowerQualityProfileResponse() + throws GeneralSecurityException, IOException, WebServiceSecurityException { final Response response = this.getNextBundleResponse(); + ScenarioContext.current().put(LAST_RESPONSE, response); assertThat(response).isInstanceOf(GetPowerQualityProfileResponse.class); final GetPowerQualityProfileResponse getPowerQualityProfileResponse = (GetPowerQualityProfileResponse) response; - final PowerQualityProfileData powerQualityProfileData = - getPowerQualityProfileResponse.getPowerQualityProfileDatas().get(0); - this.assertEqualCaptureObjects( - powerQualityProfileData.getCaptureObjectList().getCaptureObjects(), values); - this.assertEqualProfileEntries( - powerQualityProfileData.getProfileEntryList().getProfileEntries(), values); + assertThat(getPowerQualityProfileResponse.getPowerQualityProfileDatas()).isEmpty(); } - private void assertEqualCaptureObjects( - final List actualCaptureObjects, final Map expectedValues) - throws AssertionError { + public void theBundleResponseShouldContainAGetPowerQualityProfileResponse( + final int nrOfValues, + final String profileLogicalName, + final Response response, + final DataTable valuesDataTable) { + + assertThat(response).isInstanceOf(GetPowerQualityProfileResponse.class); + + final GetPowerQualityProfileResponse getPowerQualityProfileResponse = + (GetPowerQualityProfileResponse) response; + final Optional optionalPowerQualityProfileData = + getPowerQualityProfileResponse.getPowerQualityProfileDatas().stream() + .filter(data -> this.matches(new ObisCode(profileLogicalName), data.getLogicalName())) + .findFirst(); + + assertThat(optionalPowerQualityProfileData).isPresent(); + final PowerQualityProfileData powerQualityProfileData = optionalPowerQualityProfileData.get(); - final int expectedNumberOfCaptureObjects = - SettingsHelper.getIntegerValue(expectedValues, "NumberOfCaptureObjects"); + this.logData(powerQualityProfileData); - assertThat(actualCaptureObjects.size()) - .as("Number of capture objects") - .isEqualTo(expectedNumberOfCaptureObjects); + final List> expectedCaptureObjects = + valuesDataTable.asMaps(String.class, String.class); - for (int i = 0; i < expectedNumberOfCaptureObjects; i++) { - final CaptureObject actualCaptureObject = actualCaptureObjects.get(i); - this.assertEqualCaptureObject(actualCaptureObject, expectedValues, i + 1); + int columnNr = 0; + for (final CaptureObject captureObject : + powerQualityProfileData.getCaptureObjectList().getCaptureObjects()) { + log.info( + "Search data in response | {} | {} | {} | {} | {} |", + captureObject.getClassId(), + captureObject.getLogicalName(), + captureObject.getAttributeIndex(), + captureObject.getDataIndex(), + captureObject.getUnit()); + + this.assertCaptureObjectIsExpected(captureObject, expectedCaptureObjects); + + final List valuesForCaptureObject = + this.getValuesForCaptureObject( + powerQualityProfileData.getProfileEntryList().getProfileEntries(), columnNr++); + this.validateAllValues( + valuesForCaptureObject, + this.getExpectedCaptureObject(captureObject, expectedCaptureObjects)); + } + assertThat(powerQualityProfileData.getCaptureObjectList().getCaptureObjects()) + .hasSize(expectedCaptureObjects.size()); + + assertThat(powerQualityProfileData.getProfileEntryList().getProfileEntries()) + .hasSize(nrOfValues); + } + + private List getValuesForCaptureObject( + final List profileEntries, final int columnNr) { + final List valuesForCaptureObject = new ArrayList<>(); + for (final ProfileEntry profileEntry : profileEntries) { + final ProfileEntryValue profileEntryValue = profileEntry.getProfileEntryValue().get(columnNr); + assertThat(profileEntryValue.getStringValueOrDateValueOrFloatValue()).hasSize(1); + valuesForCaptureObject.addAll(profileEntryValue.getStringValueOrDateValueOrFloatValue()); } + return valuesForCaptureObject; + } + + private void validateAllValues( + final List valuesForCaptureObject, final Map expectedCaptureObject) { + final ValueType valueType = ValueType.valueOf(expectedCaptureObject.get(VALUE_TYPE)); + final String description = expectedCaptureObject.get(DESCRIPTION); + + assertThat(valuesForCaptureObject) + .isNotEmpty() + .allMatch(value -> this.isOfValueOfType(value, valueType, description)); + } + + private boolean isOfValueOfType( + final Object value, final ValueType valueType, final String description) { + return switch (valueType) { + case SIGNAL_QUALITY -> { + SignalQualityType.valueOf((String) value); + yield true; + } + case DATE_TIME -> value instanceof XMLGregorianCalendar; + case NUMBER -> value instanceof Number; + case BIG_DECIMAL -> value instanceof BigDecimal; + }; } - private void assertEqualCaptureObject( - final CaptureObject actualCaptureObject, - final Map expectedValues, - final int index) - throws AssertionError { - final Long expectedClassId = - SettingsHelper.getLongValue(expectedValues, "CaptureObject_ClassId", index); - assertThat(Long.valueOf(actualCaptureObject.getClassId())) - .as("ClassId of CaptureObject " + index) - .isEqualTo(expectedClassId); - - final String expectedLogicalName = - SettingsHelper.getStringValue(expectedValues, "CaptureObject_LogicalName", index); - assertThat(actualCaptureObject.getLogicalName()) - .as("LogicalName of CaptureObject " + index) - .isEqualTo(expectedLogicalName); - - final BigInteger expectedAttributeIndex = - SettingsHelper.getBigIntegerValue(expectedValues, "CaptureObject_AttributeIndex", index); - assertThat(actualCaptureObject.getAttributeIndex()) - .as("AttributeIndex of CaptureObject " + index) - .isEqualTo(expectedAttributeIndex); - - final Long expectedDataIndex = - SettingsHelper.getLongValue(expectedValues, "CaptureObject_DataIndex", index); - assertThat(Long.valueOf(actualCaptureObject.getDataIndex())) - .as("DataIndex of CaptureObject " + index) - .isEqualTo(expectedDataIndex); - - final String expectedUnit = - SettingsHelper.getStringValue(expectedValues, "CaptureObject_Unit", index); - assertThat(actualCaptureObject.getUnit().value()) - .as("Unit of CaptureObject " + index) - .isEqualTo(expectedUnit); + private boolean matches(final ObisCode obisCode, final ObisCodeValues logicalName) { + final String obisCodeValue = + String.format( + "%d.%d.%d.%d.%d.%d", + logicalName.getA(), + logicalName.getB(), + logicalName.getC(), + logicalName.getD(), + logicalName.getE(), + logicalName.getF()); + return (obisCodeValue).equals(obisCode.asDecimalString()); } - private void assertEqualProfileEntries( - final List actualProfileEntries, final Map expectedValues) { - final int expectedNumberOfProfileEntries = - SettingsHelper.getIntegerValue(expectedValues, "NumberOfProfileEntries"); + private void assertCaptureObjectIsExpected( + final CaptureObject captureObject, final List> expectedCaptureObjects) { + final Map expectedCaptureObject = + this.getExpectedCaptureObject(captureObject, expectedCaptureObjects); + + assertThat(captureObject.getClassId()) + .isEqualTo(Long.valueOf(expectedCaptureObject.get(CLASS_ID))); + assertThat(captureObject.getLogicalName()).isEqualTo(expectedCaptureObject.get(LOGICAL_NAME)); + assertThat(captureObject.getAttributeIndex()) + .isEqualTo(new BigInteger(expectedCaptureObject.get(ATTRIBUTE_INDEX))); + + assertThat(captureObject.getDataIndex()) + .isEqualTo(Long.valueOf(expectedCaptureObject.get(DATA_INDEX))); + assertThat(captureObject.getUnit()) + .isEqualTo(OsgpUnitType.valueOf(expectedCaptureObject.get(UNIT))); + + this.validateValues(captureObject, expectedCaptureObjects); + } + + private Map getExpectedCaptureObject( + final CaptureObject captureObject, final List> expectedCaptureObjects) { + final Optional> optExpectedCaptureObject = + expectedCaptureObjects.stream() + .filter( + d -> + d.get(LOGICAL_NAME).equals(captureObject.getLogicalName()) + && new BigInteger(d.get(ATTRIBUTE_INDEX)) + .equals(captureObject.getAttributeIndex()) + && Long.parseLong(d.get(DATA_INDEX)) == captureObject.getDataIndex()) + .findFirst(); + assertThat(optExpectedCaptureObject).isPresent(); + return optExpectedCaptureObject.get(); + } + + private void validateValues( + final CaptureObject captureObject, final List> expectedCaptureObjects) {} + + private void logData(final PowerQualityProfileData powerQualityProfileData) { + log.info("| classId | logicalName | attributeIndex | dataIndex | unit |"); + for (final CaptureObject captureObject : + powerQualityProfileData.getCaptureObjectList().getCaptureObjects()) { + log.info( + "| {} | {} | {} | {} | {} |", + captureObject.getClassId(), + captureObject.getLogicalName(), + captureObject.getAttributeIndex(), + captureObject.getDataIndex(), + captureObject.getUnit()); + } + } - assertThat(actualProfileEntries.size()) - .as("Number of profile entries") - .isEqualTo(expectedNumberOfProfileEntries); + private enum ValueType { + NUMBER, + BIG_DECIMAL, + SIGNAL_QUALITY, + DATE_TIME } } diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/ws/smartmetering/smartmeteringconfiguration/GetAdministrativeStatus.java b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/ws/smartmetering/smartmeteringconfiguration/GetAdministrativeStatus.java index 8f6085e3cf8..39470cfde85 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/ws/smartmetering/smartmeteringconfiguration/GetAdministrativeStatus.java +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/ws/smartmetering/smartmeteringconfiguration/GetAdministrativeStatus.java @@ -8,6 +8,7 @@ import io.cucumber.java.en.Then; import io.cucumber.java.en.When; +import java.time.Instant; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -16,7 +17,6 @@ import java.util.Objects; import java.util.concurrent.CountDownLatch; import java.util.stream.Collectors; -import org.joda.time.Instant; import org.opensmartgridplatform.adapter.ws.schema.smartmetering.configuration.GetAdministrativeStatusAsyncRequest; import org.opensmartgridplatform.adapter.ws.schema.smartmetering.configuration.GetAdministrativeStatusAsyncResponse; import org.opensmartgridplatform.adapter.ws.schema.smartmetering.configuration.GetAdministrativeStatusRequest; diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/ws/smartmetering/smartmeteringconfiguration/SetConfigurationObject.java b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/ws/smartmetering/smartmeteringconfiguration/SetConfigurationObject.java index 45ef3d588cf..db71f0e1a82 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/ws/smartmetering/smartmeteringconfiguration/SetConfigurationObject.java +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/glue/steps/ws/smartmetering/smartmeteringconfiguration/SetConfigurationObject.java @@ -51,6 +51,17 @@ public void theSetConfigurationObjectRequestIsReceived(final Map @Then("^the configuration object should be set on the device$") public void theConfigurationObjectShouldBeSetOnTheDevice(final Map settings) throws Throwable { + this.theConfigurationObjectShouldBeSetOrNotOnTheDevice(settings, OsgpResultType.OK); + } + + @Then("^the configuration object should not be set on the device$") + public void theConfigurationObjectShouldNotBeSetOnTheDevice(final Map settings) + throws Throwable { + this.theConfigurationObjectShouldBeSetOrNotOnTheDevice(settings, OsgpResultType.NOT_OK); + } + + public void theConfigurationObjectShouldBeSetOrNotOnTheDevice( + final Map settings, final OsgpResultType result) throws Throwable { final SetConfigurationObjectAsyncRequest setConfigurationObjectAsyncRequest = SetConfigurationObjectRequestFactory.fromScenarioContext(); final SetConfigurationObjectResponse setConfigurationObjectResponse = @@ -59,6 +70,6 @@ public void theConfigurationObjectShouldBeSetOnTheDevice(final Map settings, final String key) { - final DateTime dateTime = getDate(settings, key, new DateTime()); - return DateConverter.createXMLGregorianCalendar(dateTime.toDate()); + final ZonedDateTime dateTime = getDate(settings, key, ZonedDateTime.now()); + return DateConverter.createXMLGregorianCalendar(Date.from(dateTime.toInstant())); } } diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/support/ws/smartmetering/bundle/FindEventsRequestBuilder.java b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/support/ws/smartmetering/bundle/FindEventsRequestBuilder.java index 7eac12ab98c..9e2439fda40 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/support/ws/smartmetering/bundle/FindEventsRequestBuilder.java +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/support/ws/smartmetering/bundle/FindEventsRequestBuilder.java @@ -7,11 +7,12 @@ import static org.opensmartgridplatform.cucumber.core.ReadSettingsHelper.getDate; import static org.opensmartgridplatform.cucumber.core.ReadSettingsHelper.getEnum; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.util.Collections; +import java.util.Date; import java.util.Map; import javax.xml.datatype.XMLGregorianCalendar; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; import org.opensmartgridplatform.adapter.ws.schema.smartmetering.bundle.FindEventsRequest; import org.opensmartgridplatform.adapter.ws.schema.smartmetering.management.EventLogCategory; import org.opensmartgridplatform.cucumber.platform.helpers.DateConverter; @@ -21,8 +22,10 @@ public class FindEventsRequestBuilder { private static final EventLogCategory DEFAULT_EVENT_LOG_CATEGORY = EventLogCategory.FRAUD_DETECTION_LOG; - private static final DateTime DEFAULT_FROM = new DateTime(2016, 1, 1, 0, 0, 0, DateTimeZone.UTC); - private static final DateTime DEFAULT_UNTIL = new DateTime(2017, 1, 1, 0, 0, 0, DateTimeZone.UTC); + private static final ZonedDateTime DEFAULT_FROM = + ZonedDateTime.of(2016, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC")); + private static final ZonedDateTime DEFAULT_UNTIL = + ZonedDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC")); private EventLogCategory eventLogCategory; private XMLGregorianCalendar from; @@ -56,14 +59,14 @@ private EventLogCategory getEventLogCategory(final Map parameter } private XMLGregorianCalendar getFrom(final Map parameters) { - final DateTime dateTime = + final ZonedDateTime dateTime = getDate(parameters, PlatformSmartmeteringKeys.FROM_DATE, DEFAULT_FROM); - return DateConverter.createXMLGregorianCalendar(dateTime.toDate()); + return DateConverter.createXMLGregorianCalendar(Date.from(dateTime.toInstant())); } private XMLGregorianCalendar getUntil(final Map parameters) { - final DateTime dateTime = + final ZonedDateTime dateTime = getDate(parameters, PlatformSmartmeteringKeys.UNTIL_DATE, DEFAULT_UNTIL); - return DateConverter.createXMLGregorianCalendar(dateTime.toDate()); + return DateConverter.createXMLGregorianCalendar(Date.from(dateTime.toInstant())); } } diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/support/ws/smartmetering/bundle/GetPeriodicMeterReadsRequestBuilder.java b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/support/ws/smartmetering/bundle/GetPeriodicMeterReadsRequestBuilder.java index f446d282307..d545d181e19 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/support/ws/smartmetering/bundle/GetPeriodicMeterReadsRequestBuilder.java +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/support/ws/smartmetering/bundle/GetPeriodicMeterReadsRequestBuilder.java @@ -7,11 +7,12 @@ import static org.opensmartgridplatform.cucumber.core.ReadSettingsHelper.getDate; import static org.opensmartgridplatform.cucumber.core.ReadSettingsHelper.getEnum; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.util.Collections; +import java.util.Date; import java.util.Map; import javax.xml.datatype.XMLGregorianCalendar; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; import org.opensmartgridplatform.adapter.ws.schema.smartmetering.bundle.GetPeriodicMeterReadsRequest; import org.opensmartgridplatform.adapter.ws.schema.smartmetering.monitoring.PeriodType; import org.opensmartgridplatform.cucumber.platform.helpers.DateConverter; @@ -20,10 +21,10 @@ public class GetPeriodicMeterReadsRequestBuilder { private static final PeriodType DEFAULT_PERIOD_TYPE = PeriodType.DAILY; - private static final DateTime DEFAULT_BEGIN_DATE = - new DateTime(2016, 1, 1, 0, 0, 0, DateTimeZone.UTC); - private static final DateTime DEFAULT_END_DATE = - new DateTime(2017, 1, 1, 0, 0, 0, DateTimeZone.UTC); + private static final ZonedDateTime DEFAULT_BEGIN_DATE = + ZonedDateTime.of(2016, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC")); + private static final ZonedDateTime DEFAULT_END_DATE = + ZonedDateTime.of(2017, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC")); private PeriodType periodType; private XMLGregorianCalendar beginDate; @@ -58,14 +59,14 @@ private PeriodType getPeriodType(final Map parameters) { } private XMLGregorianCalendar getBeginDate(final Map parameters) { - final DateTime dateTime = + final ZonedDateTime dateTime = getDate(parameters, PlatformSmartmeteringKeys.KEY_BEGIN_DATE, DEFAULT_BEGIN_DATE); - return DateConverter.createXMLGregorianCalendar(dateTime.toDate()); + return DateConverter.createXMLGregorianCalendar(Date.from(dateTime.toInstant())); } private XMLGregorianCalendar getEndDate(final Map parameters) { - final DateTime dateTime = + final ZonedDateTime dateTime = getDate(parameters, PlatformSmartmeteringKeys.KEY_END_DATE, DEFAULT_END_DATE); - return DateConverter.createXMLGregorianCalendar(dateTime.toDate()); + return DateConverter.createXMLGregorianCalendar(Date.from(dateTime.toInstant())); } } diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/support/ws/smartmetering/configuration/ConfigurationObjectFactory.java b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/support/ws/smartmetering/configuration/ConfigurationObjectFactory.java index 607cce5afdc..7d8089b2602 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/support/ws/smartmetering/configuration/ConfigurationObjectFactory.java +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/support/ws/smartmetering/configuration/ConfigurationObjectFactory.java @@ -9,6 +9,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import org.apache.commons.lang3.StringUtils; import org.opensmartgridplatform.adapter.ws.schema.smartmetering.configuration.ConfigurationFlag; import org.opensmartgridplatform.adapter.ws.schema.smartmetering.configuration.ConfigurationFlagType; import org.opensmartgridplatform.adapter.ws.schema.smartmetering.configuration.ConfigurationFlags; @@ -85,7 +86,12 @@ private static void setConfigurationFlags( final int numberOfFlags = Integer.parseInt(requestParameters.get(PlatformSmartmeteringKeys.CONFIGURATION_FLAG_COUNT)); for (int i = 1; i <= numberOfFlags; i++) { - configurationFlagList.add(getConfigurationFlag(requestParameters, i)); + if (isConfigurationFlagDefined(requestParameters, i)) { + configurationFlagList.add(getConfigurationFlag(requestParameters, i)); + } + } + if (configurationFlagList.isEmpty()) { + return; } configurationFlags.getConfigurationFlag().addAll(configurationFlagList); configurationObject.setConfigurationFlags(configurationFlags); @@ -93,9 +99,10 @@ private static void setConfigurationFlags( private static ConfigurationFlag getConfigurationFlag( final Map parameters, final int index) { + final Boolean configurationFlagEnabled = getConfigurationFlagEnabled(parameters, index); final ConfigurationFlag configurationFlag = new ConfigurationFlag(); configurationFlag.setConfigurationFlagType(getConfigurationFlagType(parameters, index)); - configurationFlag.setEnabled(getConfigurationFlagEnabled(parameters, index)); + configurationFlag.setEnabled(configurationFlagEnabled); return configurationFlag; } @@ -113,4 +120,11 @@ private static boolean getConfigurationFlagEnabled( SettingsHelper.makeKey(PlatformSmartmeteringKeys.CONFIGURATION_FLAG_ENABLED, index); return ReadSettingsHelper.getBoolean(parameters, key); } + + private static boolean isConfigurationFlagDefined( + final Map parameters, final int index) { + final String key = + SettingsHelper.makeKey(PlatformSmartmeteringKeys.CONFIGURATION_FLAG_ENABLED, index); + return StringUtils.isNotBlank(parameters.get(key)); + } } diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/support/ws/smartmetering/installation/DeviceFactory.java b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/support/ws/smartmetering/installation/DeviceFactory.java index cdd0d451363..32953e5a9d0 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/support/ws/smartmetering/installation/DeviceFactory.java +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/support/ws/smartmetering/installation/DeviceFactory.java @@ -55,6 +55,11 @@ public static Device fromParameterMap(final Map requestParameter device.setSupplier(settings.get(PlatformKeys.KEY_DEVICE_SUPPLIER)); device.setTimezone(settings.get(PlatformSmartmeteringKeys.KEY_DEVICE_TIMEZONE)); + device.setLls1Active( + getBoolean( + settings, + PlatformKeys.KEY_DEVICE_LLS1ACTIVE, + PlatformDefaults.DLMS_DEFAULT_LLS1_ACTIVE)); device.setHls3Active( getBoolean( settings, diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/support/ws/smartmetering/management/FindEventsRequestDataFactory.java b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/support/ws/smartmetering/management/FindEventsRequestDataFactory.java index dc0e1e70d79..1ba0f6e7131 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/support/ws/smartmetering/management/FindEventsRequestDataFactory.java +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/support/ws/smartmetering/management/FindEventsRequestDataFactory.java @@ -7,12 +7,13 @@ import static org.opensmartgridplatform.cucumber.core.ReadSettingsHelper.getDate; import static org.opensmartgridplatform.cucumber.core.ReadSettingsHelper.getString; +import java.time.ZonedDateTime; +import java.util.Date; import java.util.GregorianCalendar; import java.util.Map; import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; -import org.joda.time.DateTime; import org.opensmartgridplatform.adapter.ws.schema.smartmetering.management.EventLogCategory; import org.opensmartgridplatform.adapter.ws.schema.smartmetering.management.FindEventsRequestData; import org.opensmartgridplatform.cucumber.platform.smartmetering.PlatformSmartmeteringKeys; @@ -42,11 +43,11 @@ public static FindEventsRequestData fromParameterMap( private static final XMLGregorianCalendar createXMLGregorianCalendar( final Map settings, final String key) { - final DateTime dateTime = getDate(settings, key, new DateTime()); + final ZonedDateTime dateTime = getDate(settings, key, ZonedDateTime.now()); try { final GregorianCalendar gregorianCalendar = new GregorianCalendar(); - gregorianCalendar.setTime(dateTime.toDate()); + gregorianCalendar.setTime(Date.from(dateTime.toInstant())); return DatatypeFactory.newInstance().newXMLGregorianCalendar(gregorianCalendar); } catch (final DatatypeConfigurationException e) { throw new RuntimeException(e); diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/support/ws/smartmetering/management/GetGsmDiagnosticResponseFactory.java b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/support/ws/smartmetering/management/GetGsmDiagnosticResponseFactory.java index 48b32e13b23..0c3fa2b1885 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/support/ws/smartmetering/management/GetGsmDiagnosticResponseFactory.java +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/support/ws/smartmetering/management/GetGsmDiagnosticResponseFactory.java @@ -7,6 +7,7 @@ import static org.opensmartgridplatform.cucumber.core.ReadSettingsHelper.getEnum; import static org.opensmartgridplatform.cucumber.core.ReadSettingsHelper.getInteger; import static org.opensmartgridplatform.cucumber.core.ReadSettingsHelper.getLong; +import static org.opensmartgridplatform.cucumber.core.ReadSettingsHelper.getShort; import static org.opensmartgridplatform.cucumber.core.ReadSettingsHelper.getString; import java.util.Arrays; @@ -16,7 +17,6 @@ import java.util.stream.IntStream; import org.opensmartgridplatform.adapter.ws.schema.smartmetering.bundle.GetGsmDiagnosticResponse; import org.opensmartgridplatform.adapter.ws.schema.smartmetering.management.AdjacentCellInfo; -import org.opensmartgridplatform.adapter.ws.schema.smartmetering.management.BitErrorRate; import org.opensmartgridplatform.adapter.ws.schema.smartmetering.management.CellInfo; import org.opensmartgridplatform.adapter.ws.schema.smartmetering.management.CircuitSwitchedStatus; import org.opensmartgridplatform.adapter.ws.schema.smartmetering.management.ModemRegistrationStatus; @@ -44,8 +44,7 @@ public static GetGsmDiagnosticResponse fromParameterMap( final Integer locationId = getInteger(requestParameters, "locationId"); final SignalQuality signalQuality = getEnum(requestParameters, "signalQuality", SignalQuality.class); - final BitErrorRate bitErrorRate = - getEnum(requestParameters, "bitErrorRate", BitErrorRate.class); + final short bitErrorRate = getShort(requestParameters, "bitErrorRate"); final Integer mobileCountryCode = getInteger(requestParameters, "mobileCountryCode"); final Integer mobileNetworkCode = getInteger(requestParameters, "mobileNetworkCode"); final Long channelNumber = getLong(requestParameters, "channelNumber"); diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/support/ws/smartmetering/monitoring/GetPowerQualityProfileRequestFactory.java b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/support/ws/smartmetering/monitoring/GetPowerQualityProfileRequestFactory.java index beeb7127fcd..b1e0370f862 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/support/ws/smartmetering/monitoring/GetPowerQualityProfileRequestFactory.java +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/support/ws/smartmetering/monitoring/GetPowerQualityProfileRequestFactory.java @@ -7,8 +7,9 @@ import static org.opensmartgridplatform.cucumber.core.ReadSettingsHelper.getDate; import static org.opensmartgridplatform.cucumber.core.ReadSettingsHelper.getString; +import java.time.ZonedDateTime; +import java.util.Date; import java.util.Map; -import org.joda.time.DateTime; import org.opensmartgridplatform.adapter.ws.schema.smartmetering.common.CaptureObjectDefinitions; import org.opensmartgridplatform.adapter.ws.schema.smartmetering.monitoring.GetPowerQualityProfileAsyncRequest; import org.opensmartgridplatform.adapter.ws.schema.smartmetering.monitoring.GetPowerQualityProfileRequest; @@ -26,8 +27,10 @@ public static GetPowerQualityProfileRequest fromParameterMap( final Map requestParameters) { final GetPowerQualityProfileRequest getPowerQualityProfileRequestData = new GetPowerQualityProfileRequest(); - final DateTime beginDate = dateFromParameterMap(requestParameters, PlatformKeys.KEY_BEGIN_DATE); - final DateTime endDate = dateFromParameterMap(requestParameters, PlatformKeys.KEY_END_DATE); + final ZonedDateTime beginDate = + dateFromParameterMap(requestParameters, PlatformKeys.KEY_BEGIN_DATE); + final ZonedDateTime endDate = + dateFromParameterMap(requestParameters, PlatformKeys.KEY_END_DATE); final String profileType = getString(requestParameters, PlatformKeys.KEY_POWER_QUALITY_PROFILE_TYPE); final CaptureObjectDefinitions captureObjecDefinitions = @@ -36,18 +39,18 @@ public static GetPowerQualityProfileRequest fromParameterMap( getPowerQualityProfileRequestData.setDeviceIdentification( requestParameters.get(PlatformKeys.KEY_DEVICE_IDENTIFICATION)); getPowerQualityProfileRequestData.setBeginDate( - DateConverter.createXMLGregorianCalendar(beginDate.toDate())); + DateConverter.createXMLGregorianCalendar(Date.from(beginDate.toInstant()))); getPowerQualityProfileRequestData.setEndDate( - DateConverter.createXMLGregorianCalendar(endDate.toDate())); + DateConverter.createXMLGregorianCalendar(Date.from(endDate.toInstant()))); getPowerQualityProfileRequestData.setProfileType(profileType); getPowerQualityProfileRequestData.setSelectedValues(captureObjecDefinitions); return getPowerQualityProfileRequestData; } - private static DateTime dateFromParameterMap( + private static ZonedDateTime dateFromParameterMap( final Map requestParameters, final String key) { - return getDate(requestParameters, key, new DateTime()); + return getDate(requestParameters, key, ZonedDateTime.now()); } public static GetPowerQualityProfileAsyncRequest fromScenarioContext() { diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/support/ws/smartmetering/monitoring/PeriodicReadsRequestDataFactory.java b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/support/ws/smartmetering/monitoring/PeriodicReadsRequestDataFactory.java index b1dff05ed65..4e8c5d8cb15 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/support/ws/smartmetering/monitoring/PeriodicReadsRequestDataFactory.java +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/java/org/opensmartgridplatform/cucumber/platform/smartmetering/support/ws/smartmetering/monitoring/PeriodicReadsRequestDataFactory.java @@ -7,9 +7,10 @@ import static org.opensmartgridplatform.cucumber.core.ReadSettingsHelper.getDate; import static org.opensmartgridplatform.cucumber.core.ReadSettingsHelper.getString; +import java.time.ZonedDateTime; +import java.util.Date; import java.util.Map; import javax.xml.datatype.XMLGregorianCalendar; -import org.joda.time.DateTime; import org.opensmartgridplatform.adapter.ws.schema.smartmetering.monitoring.PeriodType; import org.opensmartgridplatform.adapter.ws.schema.smartmetering.monitoring.PeriodicReadsRequestData; import org.opensmartgridplatform.cucumber.platform.PlatformKeys; @@ -40,7 +41,7 @@ public static PeriodicReadsRequestData fromParameterMap( private static final XMLGregorianCalendar createXMLGregorianCalendar( final Map settings, final String key) { - final DateTime dateTime = getDate(settings, key, new DateTime()); - return DateConverter.createXMLGregorianCalendar(dateTime.toDate()); + final ZonedDateTime dateTime = getDate(settings, key, ZonedDateTime.now()); + return DateConverter.createXMLGregorianCalendar(Date.from(dateTime.toInstant())); } } diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-core/AuditTrail.feature b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-core/AuditTrail.feature index 8e99b8718e7..ed4234913b4 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-core/AuditTrail.feature +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-core/AuditTrail.feature @@ -14,5 +14,5 @@ Feature: Core operations | Port | 9999 | When the get actual meter reads request is received | DeviceIdentification | TEST1024000000002 | - Then the audit trail contains multiple retry log records + Then the audit trail contains a retry log records | DeviceIdentification | TEST1024000000002 | diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/ad-hoc/TestAlarmScheduler.feature b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/ad-hoc/TestAlarmScheduler.feature index f8511601cca..13f68a6f22a 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/ad-hoc/TestAlarmScheduler.feature +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/ad-hoc/TestAlarmScheduler.feature @@ -1,20 +1,18 @@ # SPDX-FileCopyrightText: Contributors to the GXF project # # SPDX-License-Identifier: Apache-2.0 - @SmartMetering @Platform @SmartMeteringAdHoc @NightlyBuildOnly Feature: SmartMetering schedule test alarms As a grid operator I want to be able to set a test alarm on a device So scheduled alarms will be sent - Scenario: Set test alarm PARTIAL_POWER_OUTAGE on a device + Scenario Outline: Set test alarm PARTIAL_POWER_OUTAGE on a device Given a dlms device | DeviceIdentification | TEST1027000000001 | | DeviceType | SMART_METER_E | - | Protocol | SMR | - | ProtocolVersion | 5.0.0 | - | Port | 1027 | + | Protocol | | + | ProtocolVersion | | When receiving a test alarm scheduler request | DeviceIdentification | TEST1027000000001 | | TestAlarmType | PARTIAL_POWER_OUTAGE | @@ -22,8 +20,13 @@ Feature: SmartMetering schedule test alarms Then a response is received | DeviceIdentification | TEST1027000000001 | + Examples: + | protocol | version | + | SMR | 5.1 | + | SMR | 5.2 | + | SMR | 5.5 | - Scenario: Set test alarm LAST_GASP on a device + Scenario: Set test alarm LAST_GASP on a SMR 5.5 device Given a dlms device | DeviceIdentification | TEST1030000000001 | | DeviceType | SMART_METER_E | diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/bundle/BundledClearAlarmRegister.feature b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/bundle/BundledClearAlarmRegister.feature index 02b4a5c1699..125bebc1714 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/bundle/BundledClearAlarmRegister.feature +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/bundle/BundledClearAlarmRegister.feature @@ -7,30 +7,34 @@ Feature: SmartMetering Bundle - ClearAlarmRegister As a grid operator I want to be able to clear the alarm register from a meter via a bundle request - Scenario: Clear alarm register with SMR 5.1 + Scenario Outline: Bundled clear alarm only for register 1 for protocol for device Given a dlms device - | DeviceIdentification | TEST1028000000002 | + | DeviceIdentification | | | DeviceType | SMART_METER_E | - | SelectiveAccessSupported | true | - | Protocol | SMR | - | ProtocolVersion | 5.1 | - | Port | 1028 | + | Protocol | | + | ProtocolVersion | | And device "TEST1028000000002" has alarm register "1" with some value And a bundle request - | DeviceIdentification | TEST1028000000002 | + | DeviceIdentification | | And the bundle request contains a clear alarm register action When the bundle request is received Then the bundle response should contain a clear alarm register response - And alarm register "1" of device "TEST1028000000002" has been cleared + And alarm register "1" of device "" has been cleared + Examples: + | deviceIdentification | protocol | version | + | TEST1024000000002 | DSMR | 2.2 | + | TEST1024000000002 | DSMR | 4.2.2 | + | TEST1031000000002 | SMR | 4.3 | + | TEST1027000000002 | SMR | 5.0.0 | + | TEST1028000000002 | SMR | 5.1 | + Scenario: Clear both alarm registers with SMR 5.2 Given a dlms device | DeviceIdentification | TEST1029000000001 | | DeviceType | SMART_METER_E | - | SelectiveAccessSupported | true | | Protocol | SMR | | ProtocolVersion | 5.2 | - | Port | 1029 | And device "TEST1029000000001" has alarm register "1" with some value And device "TEST1029000000001" has alarm register "2" with some value And a bundle request @@ -45,10 +49,8 @@ Feature: SmartMetering Bundle - ClearAlarmRegister Given a dlms device | DeviceIdentification | TEST1030000000001 | | DeviceType | SMART_METER_E | - | SelectiveAccessSupported | true | | Protocol | SMR | | ProtocolVersion | 5.5 | - | Port | 1030 | And device "TEST1030000000001" has alarm register "1" with some value And device "TEST1030000000001" has alarm register "2" with some value And device "TEST1030000000001" has alarm register "3" with some value diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/bundle/BundledClearMBusStatusOnAllChannels.feature b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/bundle/BundledClearMBusStatusOnAllChannels.feature index 80379ecd47d..3f576ec5b40 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/bundle/BundledClearMBusStatusOnAllChannels.feature +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/bundle/BundledClearMBusStatusOnAllChannels.feature @@ -7,29 +7,40 @@ Feature: SmartMetering Bundle - Clear M-Bus alarm status on all channels of a E As a grid operator I want to be able to clear the M-Bus alarm status on all channels of a E meter - Scenario: Clear M-Bus alarm status on all channels of a E-meter + Scenario Outline: Clear M-Bus alarm status on all channels of a E-meter for protocol and check result OK Given a bundle request - | DeviceIdentification | TEST1028000000001 | + | DeviceIdentification | | And the bundle request contains a clear M-Bus status on all channels action And a dlms device - | DeviceIdentification | TEST1028000000001 | + | DeviceIdentification | | | DeviceType | SMART_METER_E | - | Protocol | SMR | - | ProtocolVersion | 5.1 | - | Port | 1028 | + | Protocol | | + | ProtocolVersion | | When the bundle request is received Then the bundle response should be OK - Scenario: Clear M-Bus alarm status of a E-meter with a non supported protocol should fail + Examples: + | deviceIdentification | protocol | version | + | TEST1028000000001 | SMR | 5.1 | + | TEST1029000000001 | SMR | 5.2 | + | TEST1030000000001 | SMR | 5.5 | + + Scenario Outline: Clear M-Bus alarm status of a E-meter with a non supported protocol should fail Given a bundle request - | DeviceIdentification | TEST1027000000001 | + | DeviceIdentification | | And the bundle request contains a clear M-Bus status on all channels action And a dlms device - | DeviceIdentification | TEST1027000000001 | - | DeviceType | SMART_METER_E | - | Protocol | SMR | - | ProtocolVersion | 5.0.0 | - | Port | 1027 | + | DeviceIdentification | | + | DeviceType | SMART_METER_E | + | Protocol | | + | ProtocolVersion | | When the bundle request is received Then the bundle response should be a FaultResponse with message containing - | Message | Error handling request with ClearMBusStatusOnAllChannelsCommandExecutor: Did not find CLEAR_MBUS_STATUS object for device 27000000001 for channel 1 | + | Message | | + + Examples: + | deviceIdentification | protocol | version | message | + | TEST1024000000001 | DSMR | 2.2 | Did not find READ_MBUS_STATUS object for device 24000000001 for channel 1 | + | TEST1024000000001 | DSMR | 4.2.2 | Did not find READ_MBUS_STATUS object for device 24000000001 for channel 1 | + | TEST1031000000001 | SMR | 4.3 | Did not find READ_MBUS_STATUS object for device 31000000001 for channel 1 | + | TEST1027000000001 | SMR | 5.0.0 | Did not find CLEAR_MBUS_STATUS object for device 27000000001 for channel 1 | \ No newline at end of file diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/bundle/BundledGetActualMeterReads.feature b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/bundle/BundledGetActualMeterReads.feature index 20c05b925b4..dc4e15c2546 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/bundle/BundledGetActualMeterReads.feature +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/bundle/BundledGetActualMeterReads.feature @@ -14,6 +14,7 @@ Feature: SmartMetering Bundle - GetActualMeterReads | DeviceType | SMART_METER_E | | Protocol | | | ProtocolVersion | | + | Port | | | Lls1active | | | Hls5active | | And a bundle request @@ -23,10 +24,10 @@ Feature: SmartMetering Bundle - GetActualMeterReads Then the bundle response should contain a get actual meter reads response Examples: - | deviceIdentification | protocol | protocolversion | lls1active | hls5active | - | TEST1024000000001 | DSMR | 4.2.2 | false | true | - | KTEST10260000001 | DSMR | 2.2 | true | false | - | ZTEST10260000001 | DSMR | 2.2 | true | false | + | deviceIdentification | protocol | protocolversion | port |lls1active | hls5active | + | TEST1024000000001 | DSMR | 4.2.2 | | false | true | + | KTEST10260000001 | DSMR | 2.2 | 1026 | true | false | + | ZTEST10260000001 | DSMR | 2.2 | 1026 | true | false | @DSMR22 Scenario Outline: Get actual meter reads gas of a device ( ) in a bundle request @@ -35,6 +36,7 @@ Feature: SmartMetering Bundle - GetActualMeterReads | DeviceType | SMART_METER_E | | Protocol | | | ProtocolVersion | | + | Port | | | Lls1active | | | Hls5active | | And a dlms device @@ -50,10 +52,10 @@ Feature: SmartMetering Bundle - GetActualMeterReads Then the bundle response should contain a get actual meter reads gas response Examples: - | deviceIdentificationGateway | deviceIdentification | protocol | protocolversion | lls1active | hls5active | - | TEST1024000000001 | TESTG102400000001 | DSMR | 4.2.2 | false | true | + | deviceIdentificationGateway | deviceIdentification | protocol | protocolversion | port | lls1active | hls5active | + | TEST1024000000001 | TESTG102400000001 | DSMR | 4.2.2 | | false | true | # identification for device with protocol DSMR 2.2 has only 16 positions (E-meter) or start with a number (G-meter) - | TEST102600000001 | 2TEST102600000001 | DSMR | 2.2 | true | false | + | TEST102600000001 | 2TEST102600000001 | DSMR | 2.2 | 1026 | true | false | Scenario: Get actual meter reads of E and G of a device in a bundle request Given a dlms device diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/bundle/BundledGetConfigurationObject.feature b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/bundle/BundledGetConfigurationObject.feature index c7657297645..fac2c0e62a6 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/bundle/BundledGetConfigurationObject.feature +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/bundle/BundledGetConfigurationObject.feature @@ -2,45 +2,85 @@ # # SPDX-License-Identifier: Apache-2.0 -@SmartMetering @Platform +@SmartMetering @Platform @SmartMeteringConfiguration @NightlyBuildOnly Feature: SmartMetering Bundle - GetConfigurationObject As a grid operator I want to retrieve the configuration object from a meter via a bundle request - Background: A smart meter with a configuration object expected to be on the device + Scenario Outline: Get configuration object on a device Given a dlms device - | DeviceIdentification | TEST1024000000001 | - | DeviceType | SMART_METER_E | - And device simulation of "TEST1024000000001" with configuration object - | GprsOperationModeType | ALWAYS_ON | - | ConfigurationFlagCount | 10 | - | ConfigurationFlagType_1 | DISCOVER_ON_OPEN_COVER | - | ConfigurationFlagEnabled_1 | false | - | ConfigurationFlagType_2 | DISCOVER_ON_POWER_ON | - | ConfigurationFlagEnabled_2 | true | - | ConfigurationFlagType_3 | DYNAMIC_MBUS_ADDRESS | - | ConfigurationFlagEnabled_3 | false | - | ConfigurationFlagType_4 | PO_ENABLE | - | ConfigurationFlagEnabled_4 | false | - | ConfigurationFlagType_5 | HLS_3_ON_P_3_ENABLE | - | ConfigurationFlagEnabled_5 | false | - | ConfigurationFlagType_6 | HLS_4_ON_P_3_ENABLE | - | ConfigurationFlagEnabled_6 | false | - | ConfigurationFlagType_7 | HLS_5_ON_P_3_ENABLE | - | ConfigurationFlagEnabled_7 | true | - | ConfigurationFlagType_8 | HLS_3_ON_PO_ENABLE | - | ConfigurationFlagEnabled_8 | false | - | ConfigurationFlagType_9 | HLS_4_ON_PO_ENABLE | - | ConfigurationFlagEnabled_9 | false | - | ConfigurationFlagType_10 | HLS_5_ON_PO_ENABLE | - | ConfigurationFlagEnabled_10 | false | - - Scenario: Get configuration object on a device - Given a bundle request - | DeviceIdentification | TEST1024000000001 | + | DeviceIdentification | | + | DeviceType | SMART_METER_E | + | Protocol | | + | ProtocolVersion | | + And device simulation of "" with configuration object values in type value attribute + | GprsOperationModeType | | + | ConfigurationFlagCount | | + | ConfigurationFlagType_1 | DISCOVER_ON_OPEN_COVER | + | ConfigurationFlagEnabled_1 | false | + | ConfigurationFlagType_2 | DISCOVER_ON_POWER_ON | + | ConfigurationFlagEnabled_2 | | + | ConfigurationFlagType_3 | DYNAMIC_MBUS_ADDRESS | + | ConfigurationFlagEnabled_3 | false | + | ConfigurationFlagType_4 | PO_ENABLE | + | ConfigurationFlagEnabled_4 | | + | ConfigurationFlagType_5 | HLS_3_ON_P3_ENABLE | + | ConfigurationFlagEnabled_5 | false | + | ConfigurationFlagType_6 | HLS_4_ON_P3_ENABLE | + | ConfigurationFlagEnabled_6 | false | + | ConfigurationFlagType_7 | HLS_5_ON_P3_ENABLE | + | ConfigurationFlagEnabled_7 | false | + | ConfigurationFlagType_8 | HLS_3_ON_P0_ENABLE | + | ConfigurationFlagEnabled_8 | false | + | ConfigurationFlagType_9 | HLS_4_ON_P0_ENABLE | + | ConfigurationFlagEnabled_9 | false | + | ConfigurationFlagType_10 | HLS_5_ON_P0_ENABLE | + | ConfigurationFlagEnabled_10 | false | + | ConfigurationFlagType_11 | DIRECT_ATTACH_AT_POWER_ON | + | ConfigurationFlagEnabled_11 | | + | ConfigurationFlagType_12 | HLS_6_ON_P3_ENABLE | + | ConfigurationFlagEnabled_12 | | + | ConfigurationFlagType_13 | HLS_7_ON_P3_ENABLE | + | ConfigurationFlagEnabled_13 | false | + | ConfigurationFlagType_14 | HLS_6_ON_P0_ENABLE | + | ConfigurationFlagEnabled_14 | false | + | ConfigurationFlagType_15 | HLS_7_ON_P0_ENABLE | + | ConfigurationFlagEnabled_15 | false | + And a bundle request + | DeviceIdentification | | And the bundle request contains a get configuration object action When the bundle request is received Then the bundle response should contain a get configuration object response with values - | GprsOperationMode | ALWAYS_ON | - | DISCOVER_ON_POWER_ON | true | - | HLS_5_ON_P_3_ENABLE | true | + | GprsOperationMode | | + | DISCOVER_ON_OPEN_COVER | false | + | DISCOVER_ON_POWER_ON | | + | DYNAMIC_MBUS_ADDRESS | false | + | PO_ENABLE | | + | HLS_3_ON_P3_ENABLE | false | + | HLS_4_ON_P3_ENABLE | false | + | HLS_5_ON_P3_ENABLE | false | + | HLS_3_ON_P0_ENABLE | false | + | HLS_4_ON_P0_ENABLE | false | + | HLS_5_ON_P0_ENABLE | false | + | DIRECT_ATTACH_AT_POWER_ON | | + | HLS_6_ON_P3_ENABLE | | + | HLS_7_ON_P3_ENABLE | false | + | HLS_6_ON_P0_ENABLE | false | + | HLS_7_ON_P0_ENABLE | false | + Examples: + | deviceIdentification | protocol | version | valueType | count | OPMO | DOPO | P0EN | DAPO | H6P3 | + | TEST1024000000001 | DSMR | 4.2.2 | structure | 10 | ALWAYS_ON | true | false | false | false | + | TEST1031000000001 | SMR | 4.3 | structure | 11 | TRIGGERED | true | false | true | false | + | TEST1027000000001 | SMR | 5.0.0 | bitstring | 15 | | false | true | true | true | + | TEST1028000000001 | SMR | 5.1 | bitstring | 15 | | false | true | false | false | + + Scenario: Get configuration object on a DSMR 2.2 device + Given a dlms device + | DeviceIdentification | TEST1022000000001 | + | DeviceType | SMART_METER_E | + | Protocol | DSMR | + | ProtocolVersion | 2.2 | + And a bundle request + | DeviceIdentification | TEST1022000000001 | + And the bundle request contains a get configuration object action + When the bundle request is received diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/bundle/BundledGetGsmDiagnostic.feature b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/bundle/BundledGetGsmDiagnostic.feature index ae796e3fea3..180db514ece 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/bundle/BundledGetGsmDiagnostic.feature +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/bundle/BundledGetGsmDiagnostic.feature @@ -27,7 +27,7 @@ Feature: SmartMetering Bundle - Get Gsm Diagnostic | cellId | 77 | | locationId | 2230 | | signalQuality | MINUS_87_DBM | - | bitErrorRate | RXQUAL_6 | + | bitErrorRate | 6 | | mobileCountryCode | 66 | | mobileNetworkCode | 204 | | channelNumber | 107 | diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/bundle/BundledGetPowerQualityProfile.feature b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/bundle/BundledGetPowerQualityProfile.feature index 2478ab9f8f1..a0cdbd97fd9 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/bundle/BundledGetPowerQualityProfile.feature +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/bundle/BundledGetPowerQualityProfile.feature @@ -2,51 +2,392 @@ # # SPDX-License-Identifier: Apache-2.0 -@Skip @SmartMetering @Platform +@SmartMetering @Platform Feature: SmartMetering Bundle - GetPowerQualityProfile As a grid operator I want to be able to retrieve power quality profile data from a meter via a bundle request - Background: + Scenario Outline: Retrieve power quality profile data as part of a bundled request for - public - single phase - (D)SMR - ( - ) Given a dlms device - | DeviceIdentification | TEST1024000000001 | - | DeviceType | SMART_METER_E | - | Protocol | DSMR | - | ProtocolVersion | 4.2.2 | - | Port | 1024 | - | FirmwareModuleVersionComm | V 1.1 | - | FirmwareModuleVersionMa | V 1.2 | - | FirmwareModuleVersionFunc | V 1.3 | + | DeviceIdentification | | + | DeviceType | SMART_METER_E | + | Protocol | | + | ProtocolVersion | | + | Port | | + | Polyphase | false | + And a bundle request + | DeviceIdentification | | + And the bundle request contains a get power quality profile request with parameters + | ProfileType | PUBLIC | + | BeginDate | 2015-01-01 00:00:00 | + | EndDate | 2017-01-10 00:00:00 | + When the bundle request is received + Then the bundle response should contain a power quality profile response with 960 values for profile "0.1.94.31.6.255" + | description | classId | logicalName | attributeIndex | dataIndex | unit | value_type | + | Clock | 8 | 0.0.1.0.0.255 | 2 | 0 | UNDEFINED | DATE_TIME | + | Voltage swells L1 | 1 | 1.0.32.36.0.255 | 2 | 0 | UNDEFINED | NUMBER | + | Voltage sags L1 | 1 | 1.0.32.32.0.255 | 2 | 0 | UNDEFINED | NUMBER | + | Number of Powerfailures | 1 | 0.0.96.7.21.255 | 2 | 0 | UNDEFINED | NUMBER | + | Instantaneous voltage L1 | 3 | 1.0.32.7.0.255 | 2 | 0 | V | BIG_DECIMAL | + | Average voltage L1 | 3 | 1.0.32.24.0.255 | 2 | 0 | V | BIG_DECIMAL | + + Examples: + | deviceIdentification | port | protocol | version | + | TEST1024000011100 | 1024 | DSMR | 4.2.2 | + + Scenario Outline: Retrieve power quality profile data as part of a bundled request for - public - single phase - (D)SMR - ( - ) + Given a dlms device + | DeviceIdentification | | + | DeviceType | SMART_METER_E | + | Protocol | | + | ProtocolVersion | | + | Port | | + | Polyphase | false | + And a bundle request + | DeviceIdentification | | + And the bundle request contains a get power quality profile request with parameters + | ProfileType | PUBLIC | + | BeginDate | 2015-01-01 00:00:00 | + | EndDate | 2017-01-10 00:00:00 | + When the bundle request is received + Then the bundle response should contain a power quality profile response with 960 values for profile "0.1.94.31.6.255" + | description | classId | logicalName | attributeIndex | dataIndex | unit | value_type | + | Clock | 8 | 0.0.1.0.0.255 | 2 | 0 | UNDEFINED | DATE_TIME | + | Voltage swells L1 | 1 | 1.0.32.36.0.255 | 2 | 0 | UNDEFINED | NUMBER | + | Voltage sags L1 | 1 | 1.0.32.32.0.255 | 2 | 0 | UNDEFINED | NUMBER | + | Number of Powerfailures | 1 | 0.0.96.7.21.255 | 2 | 0 | UNDEFINED | NUMBER | + | Instantaneous voltage L1 | 3 | 1.0.32.7.0.255 | 2 | 0 | V | BIG_DECIMAL | + | Average voltage L1 | 3 | 1.0.32.24.0.255 | 2 | 0 | V | BIG_DECIMAL | + | CDMA Diagnostics (Signal quality) | 47 | 0.1.25.6.0.255 | 6 | 3 | UNDEFINED | SIGNAL_QUALITY | + + Examples: + | deviceIdentification | port | protocol | version | + | TEST1031000011101 | 1031 | SMR | 4.3 | + + Scenario Outline: Retrieve power quality profile data as part of a bundled request for - public - poly phase - (D)SMR - ( - ) + Given a dlms device + | DeviceIdentification | | + | DeviceType | SMART_METER_E | + | Protocol | | + | ProtocolVersion | | + | Port | | + | Polyphase | true | + And a bundle request + | DeviceIdentification | | + And the bundle request contains a get power quality profile request with parameters + | ProfileType | PUBLIC | + | BeginDate | 2015-01-01 00:00:00 | + | EndDate | 2017-01-10 00:00:00 | + When the bundle request is received + Then the bundle response should contain a power quality profile response with 960 values for profile "0.1.94.31.6.255" + | description | classId | logicalName | attributeIndex | dataIndex | unit | value_type | + | Clock | 8 | 0.0.1.0.0.255 | 2 | 0 | UNDEFINED | DATE_TIME | + | Instantaneous voltage L1 | 3 | 1.0.32.7.0.255 | 2 | 0 | V | BIG_DECIMAL | + | Average voltage L1 | 3 | 1.0.32.24.0.255 | 2 | 0 | V | BIG_DECIMAL | + | Instantaneous voltage L2 | 3 | 1.0.52.7.0.255 | 2 | 0 | V | BIG_DECIMAL | + | Average voltage L2 | 3 | 1.0.52.24.0.255 | 2 | 0 | V | BIG_DECIMAL | + | Instantaneous voltage L3 | 3 | 1.0.72.7.0.255 | 2 | 0 | V | BIG_DECIMAL | + | Average voltage L3 | 3 | 1.0.72.24.0.255 | 2 | 0 | V | BIG_DECIMAL | + + Examples: + | deviceIdentification | port | protocol | version | + | TEST1024000011100 | 1024 | DSMR | 4.2.2 | + + Scenario Outline: Retrieve power quality profile data as part of a bundled request for - public - poly phase - (D)SMR - ( - ) + Given a dlms device + | DeviceIdentification | | + | DeviceType | SMART_METER_E | + | Protocol | | + | ProtocolVersion | | + | Port | | + | Polyphase | true | + And a bundle request + | DeviceIdentification | | + And the bundle request contains a get power quality profile request with parameters + | ProfileType | PUBLIC | + | BeginDate | 2015-01-01 00:00:00 | + | EndDate | 2017-01-10 00:00:00 | + When the bundle request is received + Then the bundle response should contain a power quality profile response with 960 values for profile "0.1.94.31.6.255" + | description | classId | logicalName | attributeIndex | dataIndex | unit | value_type | + | Clock | 8 | 0.0.1.0.0.255 | 2 | 0 | UNDEFINED | DATE_TIME | + | Instantaneous voltage L1 | 3 | 1.0.32.7.0.255 | 2 | 0 | V | BIG_DECIMAL | + | Average voltage L1 | 3 | 1.0.32.24.0.255 | 2 | 0 | V | BIG_DECIMAL | + | Instantaneous voltage L2 | 3 | 1.0.52.7.0.255 | 2 | 0 | V | BIG_DECIMAL | + | Average voltage L2 | 3 | 1.0.52.24.0.255 | 2 | 0 | V | BIG_DECIMAL | + | Instantaneous voltage L3 | 3 | 1.0.72.7.0.255 | 2 | 0 | V | BIG_DECIMAL | + | Average voltage L3 | 3 | 1.0.72.24.0.255 | 2 | 0 | V | BIG_DECIMAL | + | CDMA Diagnostics (Signal quality) | 47 | 0.1.25.6.0.255 | 6 | 3 | UNDEFINED | SIGNAL_QUALITY | + + Examples: + | deviceIdentification | port | protocol | version | + | TEST1031000011101 | 1031 | SMR | 4.3 | + + Scenario Outline: Retrieve power quality profile data as part of a bundled request for - private - (D)SMR - single phase ( - ) + Given a dlms device + | DeviceIdentification | | + | DeviceType | SMART_METER_E | + | Protocol | | + | ProtocolVersion | | + | Port | | + | Polyphase | false | + And a bundle request + | DeviceIdentification | | + And the bundle request contains a get power quality profile request with parameters + | ProfileType | PRIVATE | + | BeginDate | 2015-01-01 00:00:00 | + | EndDate | 2017-01-10 00:00:00 | + When the bundle request is received + Then the bundle response should contain a power quality profile response with 960 values for profile "0.1.94.31.6.255" + | description | classId | logicalName | attributeIndex | dataIndex | unit | value_type | + | Clock | 8 | 0.0.1.0.0.255 | 2 | 0 | UNDEFINED | DATE_TIME | + | Instantaneous current L1 | 3 | 1.0.31.7.0.255 | 2 | 0 | AMP | BIG_DECIMAL | + | L1 Average Current | 3 | 1.0.31.24.0.255 | 2 | 0 | AMP | BIG_DECIMAL | + | L1 Average Active Power Import | 3 | 1.0.21.24.0.255 | 2 | 0 | W | BIG_DECIMAL | + | L1 Average Active Power Export | 3 | 1.0.22.24.0.255 | 2 | 0 | W | BIG_DECIMAL | + | L1 Average Reactive Power Import | 3 | 1.0.23.24.0.255 | 2 | 0 | VAR | BIG_DECIMAL | + | L1 Average Reactive Power Export | 3 | 1.0.24.24.0.255 | 2 | 0 | VAR | BIG_DECIMAL | + + Examples: + | deviceIdentification | port | protocol | version | + | TEST1024000011100 | 1024 | DSMR | 4.2.2 | + | TEST1031000011101 | 1031 | SMR | 4.3 | + + Scenario Outline: Retrieve power quality profile data as part of a bundled request for - private - (D)SMR - poly phase ( - ) + Given a dlms device + | DeviceIdentification | | + | DeviceType | SMART_METER_E | + | Protocol | | + | ProtocolVersion | | + | Port | | + | Polyphase | true | + And a bundle request + | DeviceIdentification | | + And the bundle request contains a get power quality profile request with parameters + | ProfileType | PRIVATE | + | BeginDate | 2015-01-01 00:00:00 | + | EndDate | 2017-01-10 00:00:00 | + When the bundle request is received + Then the bundle response should contain a power quality profile response with 960 values for profile "0.1.94.31.6.255" + | description | classId | logicalName | attributeIndex | dataIndex | unit | value_type | + | Clock | 8 | 0.0.1.0.0.255 | 2 | 0 | UNDEFINED | DATE_TIME | + | Instantaneous current Total | 3 | 1.0.90.7.0.255 | 2 | 0 | AMP | BIG_DECIMAL | + | L1 Average Active Power Import | 3 | 1.0.21.24.0.255 | 2 | 0 | W | BIG_DECIMAL | + | L2 Average Active Power Import | 3 | 1.0.41.24.0.255 | 2 | 0 | W | BIG_DECIMAL | + | L3 Average Active Power Import | 3 | 1.0.61.24.0.255 | 2 | 0 | W | BIG_DECIMAL | + | L1 Average Active Power Export | 3 | 1.0.22.24.0.255 | 2 | 0 | W | BIG_DECIMAL | + | L2 Average Active Power Export | 3 | 1.0.42.24.0.255 | 2 | 0 | W | BIG_DECIMAL | + | L3 Average Active Power Export | 3 | 1.0.62.24.0.255 | 2 | 0 | W | BIG_DECIMAL | + | L1 Average Reactive Power Import | 3 | 1.0.23.24.0.255 | 2 | 0 | VAR | BIG_DECIMAL | + | L2 Average Reactive Power Import | 3 | 1.0.43.24.0.255 | 2 | 0 | VAR | BIG_DECIMAL | + | L3 Average Reactive Power Import | 3 | 1.0.63.24.0.255 | 2 | 0 | VAR | BIG_DECIMAL | + | L1 Average Reactive Power Export | 3 | 1.0.24.24.0.255 | 2 | 0 | VAR | BIG_DECIMAL | + | L2 Average Reactive Power Export | 3 | 1.0.44.24.0.255 | 2 | 0 | VAR | BIG_DECIMAL | + | L4 Average Reactive Power Export | 3 | 1.0.64.24.0.255 | 2 | 0 | VAR | BIG_DECIMAL | - Scenario: Retrieve power quality profile data as part of a bundled request - Given a bundle request - | DeviceIdentification | TEST1024000000001 | + Examples: + | deviceIdentification | port | protocol | version | + | TEST1024000011100 | 1024 | DSMR | 4.2.2 | + | TEST1031000011101 | 1031 | SMR | 4.3 | + + # + # SMR + # + + Scenario Outline: Retrieve power quality profile data as part of a bundled request for - public - single phase - SMR - ( - ) + Given a dlms device + | DeviceIdentification | | + | DeviceType | SMART_METER_E | + | Protocol | | + | ProtocolVersion | | + | Port | | + | Polyphase | false | + And a bundle request + | DeviceIdentification | | And the bundle request contains a get power quality profile request with parameters | ProfileType | PUBLIC | | BeginDate | 2015-01-01 00:00:00 | | EndDate | 2017-01-10 00:00:00 | When the bundle request is received - Then the bundle response should contain a power quality profile response with values - | DeviceIdentification | TEST1024000000001 | - | NumberOfCaptureObjects | 4 | - | CaptureObject_ClassId_1 | 8 | - | CaptureObject_LogicalName_1 | 0.0.1.0.0.255 | - | CaptureObject_AttributeIndex_1 | 2 | - | CaptureObject_DataIndex_1 | 0 | - | CaptureObject_Unit_1 | UNDEFINED | - | CaptureObject_ClassId_2 | 1 | - | CaptureObject_LogicalName_2 | 0.0.96.10.2.255 | - | CaptureObject_AttributeIndex_2 | 2 | - | CaptureObject_DataIndex_2 | 0 | - | CaptureObject_Unit_2 | UNDEFINED | - | CaptureObject_ClassId_3 | 3 | - | CaptureObject_LogicalName_3 | 1.0.1.8.0.255 | - | CaptureObject_AttributeIndex_3 | 2 | - | CaptureObject_DataIndex_3 | 0 | - | CaptureObject_Unit_3 | KWH | - | CaptureObject_ClassId_4 | 3 | - | CaptureObject_LogicalName_4 | 1.0.2.8.0.255 | - | CaptureObject_AttributeIndex_4 | 2 | - | CaptureObject_DataIndex_4 | 0 | - | CaptureObject_Unit_4 | KWH | - | NumberOfProfileEntries | 960 | + Then the bundle response should contain a power quality profile response with 960 values for profile "0.1.94.31.6.255" + | description | classId | logicalName | attributeIndex | dataIndex | unit | value_type | + | Clock | 8 | 0.0.1.0.0.255 | 2 | 0 | UNDEFINED | DATE_TIME | + | Number of voltage sags in phase L1 | 1 | 1.0.32.32.0.255 | 2 | 0 | UNDEFINED | NUMBER | + | Number of voltage swells in phase L1 | 1 | 1.0.32.36.0.255 | 2 | 0 | UNDEFINED | NUMBER | + | Number of power failures in any phase | 1 | 0.0.96.7.21.255 | 2 | 0 | UNDEFINED | NUMBER | + | CDMA Diagnostics (Signal quality) | 47 | 0.1.25.6.0.255 | 6 | 3 | UNDEFINED | SIGNAL_QUALITY | + | GPRS Diagnostics (Signal quality) | 47 | 0.0.25.6.0.255 | 6 | 3 | UNDEFINED | SIGNAL_QUALITY | + | CDMA Diagnostics (BER) | 47 | 0.1.25.6.0.255 | 6 | 4 | UNDEFINED | NUMBER | + | GPRS Diagnostics (BER) | 47 | 0.0.25.6.0.255 | 6 | 4 | UNDEFINED | NUMBER | + | M-Bus Client Setup CHn1 | 72 | 0.1.24.1.0.255 | 11 | 0 | UNDEFINED | NUMBER | + | M-Bus Client Setup CHn2 | 72 | 0.2.24.1.0.255 | 11 | 0 | UNDEFINED | NUMBER | + | M-Bus diagnostics RSSi CHn1 | 77 | 0.1.24.9.0.255 | 2 | 0 | UNDEFINED | NUMBER | + | M-Bus diagnostics RSSi CHn2 | 77 | 0.2.24.9.0.255 | 2 | 0 | UNDEFINED | NUMBER | + | M-Bus diagnostics FCS-NOK CHn1 | 77 | 0.1.24.9.0.255 | 8 | 0 | UNDEFINED | NUMBER | + | M-Bus diagnostics FCS-NOK CHn2 | 77 | 0.2.24.9.0.255 | 8 | 0 | UNDEFINED | NUMBER | + Then the same bundle response should contain a power quality profile response with 1440 values for profile "1.0.99.1.2.255" + | description | classId | logicalName | attributeIndex | dataIndex | unit | value_type | + | Clock | 8 | 0.0.1.0.0.255 | 2 | 0 | UNDEFINED | DATE_TIME | + | L1 Average Voltage | 3 | 1.0.32.24.0.255 | 2 | 0 | V | BIG_DECIMAL | + | L1 Instantaneous Voltage | 3 | 1.0.32.7.0.255 | 2 | 0 | V | BIG_DECIMAL | + + Examples: + | deviceIdentification | port | protocol | version | + | TEST1027000011101 | 1027 | SMR | 5.0.0 | + | TEST1028000011102 | 1028 | SMR | 5.1 | + | TEST1029000011103 | 1029 | SMR | 5.2 | + | TEST1030000011104 | 1030 | SMR | 5.5 | + + Scenario Outline: Retrieve power quality profile data as part of a bundled request for - public - poly phase - SMR - ( - ) + Given a dlms device + | DeviceIdentification | | + | DeviceType | SMART_METER_E | + | Protocol | | + | ProtocolVersion | | + | Port | | + | Polyphase | true | + And a bundle request + | DeviceIdentification | | + And the bundle request contains a get power quality profile request with parameters + | ProfileType | PUBLIC | + | BeginDate | 2015-01-01 00:00:00 | + | EndDate | 2017-01-10 00:00:00 | + When the bundle request is received + Then the bundle response should contain a power quality profile response with 960 values for profile "0.1.94.31.6.255" + | description | classId | logicalName | attributeIndex | dataIndex | unit | value_type | + | Clock | 8 | 0.0.1.0.0.255 | 2 | 0 | UNDEFINED | DATE_TIME | + | Number of voltage sags in phase L1 | 1 | 1.0.32.32.0.255 | 2 | 0 | UNDEFINED | NUMBER | + | Number of voltage sags in phase L2 | 1 | 1.0.52.32.0.255 | 2 | 0 | UNDEFINED | NUMBER | + | Number of voltage sags in phase L3 | 1 | 1.0.72.32.0.255 | 2 | 0 | UNDEFINED | NUMBER | + | Number of voltage swells in phase L1 | 1 | 1.0.32.36.0.255 | 2 | 0 | UNDEFINED | NUMBER | + | Number of voltage swells in phase L2 | 1 | 1.0.52.36.0.255 | 2 | 0 | UNDEFINED | NUMBER | + | Number of voltage swells in phase L3 | 1 | 1.0.72.36.0.255 | 2 | 0 | UNDEFINED | NUMBER | + | Number of power failures in any phase | 1 | 0.0.96.7.21.255 | 2 | 0 | UNDEFINED | NUMBER | + | CDMA Diagnostics (Signal quality) | 47 | 0.1.25.6.0.255 | 6 | 3 | UNDEFINED | SIGNAL_QUALITY | + | GPRS Diagnostics (Signal quality) | 47 | 0.0.25.6.0.255 | 6 | 3 | UNDEFINED | SIGNAL_QUALITY | + | CDMA Diagnostics (BER) | 47 | 0.1.25.6.0.255 | 6 | 4 | UNDEFINED | NUMBER | + | GPRS Diagnostics (BER) | 47 | 0.0.25.6.0.255 | 6 | 4 | UNDEFINED | NUMBER | + | M-Bus Client Setup CHn1 | 72 | 0.1.24.1.0.255 | 11 | 0 | UNDEFINED | NUMBER | + | M-Bus Client Setup CHn2 | 72 | 0.2.24.1.0.255 | 11 | 0 | UNDEFINED | NUMBER | + | M-Bus diagnostics RSSi CHn1 | 77 | 0.1.24.9.0.255 | 2 | 0 | UNDEFINED | NUMBER | + | M-Bus diagnostics RSSi CHn2 | 77 | 0.2.24.9.0.255 | 2 | 0 | UNDEFINED | NUMBER | + | M-Bus diagnostics FCS-NOK CHn1 | 77 | 0.1.24.9.0.255 | 8 | 0 | UNDEFINED | NUMBER | + | M-Bus diagnostics FCS-NOK CHn2 | 77 | 0.2.24.9.0.255 | 8 | 0 | UNDEFINED | NUMBER | + Then the same bundle response should contain a power quality profile response with 1440 values for profile "1.0.99.1.2.255" + | description | classId | logicalName | attributeIndex | dataIndex | unit | value_type | + | Clock | 8 | 0.0.1.0.0.255 | 2 | 0 | UNDEFINED | DATE_TIME | + | L1 Average Voltage | 3 | 1.0.32.24.0.255 | 2 | 0 | V | BIG_DECIMAL | + | L2 Average Voltage | 3 | 1.0.52.24.0.255 | 2 | 0 | V | BIG_DECIMAL | + | L3 Average Voltage | 3 | 1.0.72.24.0.255 | 2 | 0 | V | BIG_DECIMAL | + + Examples: + | deviceIdentification | port | protocol | version | + | TEST1027000011101 | 1027 | SMR | 5.0.0 | + | TEST1028000011102 | 1028 | SMR | 5.1 | + | TEST1029000011103 | 1029 | SMR | 5.2 | + | TEST1030000011104 | 1030 | SMR | 5.5 | + + Scenario Outline: Retrieve power quality profile data as part of a bundled request for - private - SMR - single phase ( - ) + Given a dlms device + | DeviceIdentification | | + | DeviceType | SMART_METER_E | + | Protocol | | + | ProtocolVersion | | + | Port | | + | Polyphase | false | + And a bundle request + | DeviceIdentification | | + And the bundle request contains a get power quality profile request with parameters + | ProfileType | PRIVATE | + | BeginDate | 2015-01-01 00:00:00 | + | EndDate | 2017-01-10 00:00:00 | + When the bundle request is received + Then the bundle response should contain a power quality profile response with 960 values for profile "1.0.99.1.1.255" + | description | classId | logicalName | attributeIndex | dataIndex | unit | value_type | + | Clock | 8 | 0.0.1.0.0.255 | 2 | 0 | UNDEFINED | DATE_TIME | + | L1 Average Active Power Import | 3 | 1.0.21.4.0.255 | 2 | 0 | W | BIG_DECIMAL | + | L1 Average Active Power Export | 3 | 1.0.22.4.0.255 | 2 | 0 | W | BIG_DECIMAL | + | L1 Average Reactive Power Import | 3 | 1.0.23.4.0.255 | 2 | 0 | VAR | BIG_DECIMAL | + | L1 Average Reactive Power Export | 3 | 1.0.24.4.0.255 | 2 | 0 | VAR | BIG_DECIMAL | + Then the same bundle response should contain a power quality profile response with 1440 values for profile "1.0.99.1.2.255" + | description | classId | logicalName | attributeIndex | dataIndex | unit | value_type | + | Clock | 8 | 0.0.1.0.0.255 | 2 | 0 | UNDEFINED | DATE_TIME | + | L1 Average Current | 3 | 1.0.31.24.0.255 | 2 | 0 | AMP | BIG_DECIMAL | + | Instantaneous current L1 | 3 | 1.0.31.7.0.255 | 2 | 0 | AMP | BIG_DECIMAL | + + Examples: + | deviceIdentification | port | protocol | version | + | TEST1027000011101 | 1027 | SMR | 5.0.0 | + | TEST1028000011102 | 1028 | SMR | 5.1 | + | TEST1029000011103 | 1029 | SMR | 5.2 | + | TEST1030000011104 | 1030 | SMR | 5.5 | + + Scenario Outline: Retrieve power quality profile data as part of a bundled request for - private - SMR - poly phase ( - ) + Given a dlms device + | DeviceIdentification | | + | DeviceType | SMART_METER_E | + | Protocol | | + | ProtocolVersion | | + | Port | | + | Polyphase | true | + And a bundle request + | DeviceIdentification | | + And the bundle request contains a get power quality profile request with parameters + | ProfileType | PRIVATE | + | BeginDate | 2015-01-01 00:00:00 | + | EndDate | 2017-01-10 00:00:00 | + When the bundle request is received + Then the bundle response should contain a power quality profile response with 960 values for profile "1.0.99.1.1.255" + | description | classId | logicalName | attributeIndex | dataIndex | unit | value_type | + | Clock | 8 | 0.0.1.0.0.255 | 2 | 0 | UNDEFINED | DATE_TIME | + | L1 Average Active Power Import | 3 | 1.0.21.4.0.255 | 2 | 0 | W | BIG_DECIMAL | + | L2 Average Active Power Import | 3 | 1.0.41.4.0.255 | 2 | 0 | W | BIG_DECIMAL | + | L3 Average Active Power Import | 3 | 1.0.61.4.0.255 | 2 | 0 | W | BIG_DECIMAL | + | L1 Average Active Power Export | 3 | 1.0.22.4.0.255 | 2 | 0 | W | BIG_DECIMAL | + | L2 Average Active Power Export | 3 | 1.0.42.4.0.255 | 2 | 0 | W | BIG_DECIMAL | + | L3 Average Active Power Export | 3 | 1.0.62.4.0.255 | 2 | 0 | W | BIG_DECIMAL | + | L1 Average Reactive Power Import | 3 | 1.0.23.4.0.255 | 2 | 0 | VAR | BIG_DECIMAL | + | L2 Average Reactive Power Import | 3 | 1.0.43.4.0.255 | 2 | 0 | VAR | BIG_DECIMAL | + | L3 Average Reactive Power Import | 3 | 1.0.63.4.0.255 | 2 | 0 | VAR | BIG_DECIMAL | + | L1 Average Reactive Power Export | 3 | 1.0.24.4.0.255 | 2 | 0 | VAR | BIG_DECIMAL | + | L2 Average Reactive Power Export | 3 | 1.0.44.4.0.255 | 2 | 0 | VAR | BIG_DECIMAL | + | L3 Average Reactive Power Export | 3 | 1.0.64.4.0.255 | 2 | 0 | VAR | BIG_DECIMAL | + Then the same bundle response should contain a power quality profile response with 1440 values for profile "1.0.99.1.2.255" + | description | classId | logicalName | attributeIndex | dataIndex | unit | value_type | + | Clock | 8 | 0.0.1.0.0.255 | 2 | 0 | UNDEFINED | DATE_TIME | + | L1 Average Current | 3 | 1.0.31.24.0.255 | 2 | 0 | AMP | BIG_DECIMAL | + | L2 Average Current | 3 | 1.0.51.24.0.255 | 2 | 0 | AMP | BIG_DECIMAL | + | L3 Average Current | 3 | 1.0.71.24.0.255 | 2 | 0 | AMP | BIG_DECIMAL | + + Examples: + | deviceIdentification | port | protocol | version | + | TEST1027000011101 | 1027 | SMR | 5.0.0 | + | TEST1028000011102 | 1028 | SMR | 5.1 | + | TEST1029000011103 | 1029 | SMR | 5.2 | + | TEST1030000011104 | 1030 | SMR | 5.5 | + + Scenario Outline: Retrieve power quality profile data as part of a bundled request for - [profileType: - polyphase: ] (DSMR - 2.2) + Given a dlms device + | DeviceIdentification | | + | DeviceType | SMART_METER_E | + | Protocol | DSMR | + | ProtocolVersion | 2.2 | + | Port | | + | Polyphase | | + | Lls1active | true | + | Hls5active | false | + And a bundle request + | DeviceIdentification | | + And the bundle request contains a get power quality profile request with parameters + | ProfileType | | + | BeginDate | 2015-01-01 00:00:00 | + | EndDate | 2017-01-10 00:00:00 | + When the bundle request is received + Then the bundle response should contain an empty power quality profile response + + Examples: + | deviceIdentification | port | polyphase | profileType | + | TEST1026000011100 | 1026 | false | PUBLIC | + | TEST1026000011101 | 1026 | true | PUBLIC | + | TEST1026000011100 | 1026 | false | PRIVATE | + | TEST1026000011101 | 1026 | true | PRIVATE | diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/bundle/BundledReadAlarmRegister.feature b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/bundle/BundledReadAlarmRegister.feature index 8a22d41cc68..0cca0abed54 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/bundle/BundledReadAlarmRegister.feature +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/bundle/BundledReadAlarmRegister.feature @@ -7,14 +7,27 @@ Feature: SmartMetering Bundle - ReadAlarmRegister As a grid operator I want to be able to read the alarm register from a meter via a bundle request - Background: + Scenario Outline: Retrieve read alarm register response of a device in a bundle request for Given a dlms device - | DeviceIdentification | TEST1024000000001 | - | DeviceType | SMART_METER_E | - - Scenario: Retrieve events of a device in a bundle request - Given a bundle request + | DeviceIdentification | TEST1024000000001 | + | DeviceType | SMART_METER_E | + | SelectiveAccessSupported | true | + | Port | | + | Protocol | | + | ProtocolVersion | | + | Lls1active | | + | Hls5active | | + And a bundle request | DeviceIdentification | TEST1024000000001 | And the bundle request contains a read alarm register action When the bundle request is received Then the bundle response should contain a read alarm register response + Examples: + | protocol | version | port | lls1active | hls5active | + | DSMR | 2.2 | 1026 | true | false | + | DSMR | 4.2.2 | | false | true | + | SMR | 4.3 | | false | true | + | SMR | 5.0.0 | | false | true | + | SMR | 5.1 | | false | true | + | SMR | 5.2 | | false | true | + | SMR | 5.5 | | false | true | \ No newline at end of file diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/bundle/BundledSetActivityCalendar.feature b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/bundle/BundledSetActivityCalendar.feature index 8f420d70ce7..9d5e805ee5c 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/bundle/BundledSetActivityCalendar.feature +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/bundle/BundledSetActivityCalendar.feature @@ -7,14 +7,14 @@ Feature: SmartMetering Bundle - SetActivityCalendar As a grid operator I want to be able to set activity calendar on a meter via a bundle request - Background: + Scenario Outline: Set activity calendar on a device in a bundle request Given a dlms device - | DeviceIdentification | TEST1024000000001 | - | DeviceType | SMART_METER_E | - - Scenario: Set activity calendar on a device in a bundle request - Given a bundle request - | DeviceIdentification | TEST1024000000001 | + | DeviceIdentification | | + | DeviceType | SMART_METER_E | + | Protocol | | + | ProtocolVersion | | + And a bundle request + | DeviceIdentification | | And an activity calendar | ActivityCalendarName | CALENDAR | | ActivatePassiveCalendarTime | FFFFFFFEFFFFFFFFFF000000 | @@ -71,3 +71,13 @@ Feature: SmartMetering Bundle - SetActivityCalendar When the bundle request is received Then the bundle response should contain a set special days response with values | Result | OK | + + Examples: + | deviceIdentification | protocol | version | + | TEST1024000000002 | DSMR | 2.2 | + | TEST1024000000002 | DSMR | 4.2.2 | + | TEST1031000000002 | SMR | 4.3 | + | TEST1027000000002 | SMR | 5.0.0 | + | TEST1028000000002 | SMR | 5.1 | + | TEST1028000000002 | SMR | 5.2 | + | TEST1028000000002 | SMR | 5.5 | \ No newline at end of file diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/configuration/Firmware.feature b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/configuration/Firmware.feature index de91ffd4c34..2b93b46deba 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/configuration/Firmware.feature +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/configuration/Firmware.feature @@ -109,7 +109,7 @@ Feature: SmartMetering Configuration - Firmware | DeviceModelCode | MA105 | And a firmware | FirmwareFileIdentification | TEST_FW_FILE_0001 | - | FirmwareFile | 57696520646974206c656573742069732067656b | + | FirmwareFile | 0000000000230011004000310000001000020801e91effffffff500303000000000000831c9d5aa5b4ffbfd057035a8a7896a4abe7afa36687fbc48944bcee0343eed3a75aab882ec1cf57820adfd4394e262d5fa821c678e71c05c47e1c69c4bfffe1fd | | FirmwareModuleVersionComm | Telit 10.00.154 | | FirmwareModuleVersionMa | BL_012 XMX_N42_GprsV09 | | FirmwareModuleVersionFunc | M57 4836 | @@ -145,7 +145,7 @@ Feature: SmartMetering Configuration - Firmware | DeviceModelCode | MA105 | And a firmware | FirmwareFileIdentification | TEST_FW_FILE_0001 | - | FirmwareFile | 57696520646974206c656573742069732067656b | + | FirmwareFile | 0000000000230011004000310000001000020801e91effffffff500303000000000000831c9d5aa5b4ffbfd057035a8a7896a4abe7afa36687fbc48944bcee0343eed3a75aab882ec1cf57820adfd4394e262d5fa821c678e71c05c47e1c69c4bfffe1fd | | FirmwareModuleVersionComm | Telit 10.00.154 | | FirmwareModuleVersionMa | BL_012 XMX_N42_GprsV09 | | FirmwareModuleVersionFunc | M57 4836 | @@ -186,7 +186,7 @@ Feature: SmartMetering Configuration - Firmware | DeviceModelCode | MA105 | And a firmware | FirmwareFileIdentification | TEST_FW_FILE_0002 | - | FirmwareFile | 57696520646974206c656573742069732067656b | + | FirmwareFile | 0000000000230011004000310000001000020801e91effffffff500303000000000000831c9d5aa5b4ffbfd057035a8a7896a4abe7afa36687fbc48944bcee0343eed3a75aab882ec1cf57820adfd4394e262d5fa821c678e71c05c47e1c69c4bfffe1fd | | FirmwareModuleVersionComm | Telit 10.00.154 | | FirmwareModuleVersionMa | BL_012 XMX_N42_GprsV09 | | FirmwareModuleVersionFunc | M57 4836 | @@ -226,7 +226,7 @@ Feature: SmartMetering Configuration - Firmware | DeviceModelCode | MA105 | And a firmware | FirmwareFileIdentification | TEST_FW_FILE_0001 | - | FirmwareFile | 57696520646974206c656573742069732067656b | + | FirmwareFile | 0000000000230011004000310000001000020801e91effffffff500303000000000000831c9d5aa5b4ffbfd057035a8a7896a4abe7afa36687fbc48944bcee0343eed3a75aab882ec1cf57820adfd4394e262d5fa821c678e71c05c47e1c69c4bfffe1fd | | FirmwareModuleVersionComm | Telit 10.00.154 | | FirmwareModuleVersionMa | BL_012 XMX_N42_GprsV09 | | FirmwareModuleVersionFunc | M57 4836 | @@ -293,4 +293,3 @@ Feature: SmartMetering Configuration - Firmware | DeviceIdentification | GTEST102400000002 | And the database should not be updated with the new device firmware | DeviceIdentification | GTEST102400000002 | - \ No newline at end of file diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/configuration/SetActivityCalendar.feature b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/configuration/SetActivityCalendar.feature index 25722bc2888..c2d902060bd 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/configuration/SetActivityCalendar.feature +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/configuration/SetActivityCalendar.feature @@ -8,11 +8,23 @@ Feature: SmartMetering Configuration - Set Activity Calendar I want to be able to set the activity calendar on a device In order to ensure proper tarriffication on the device - Scenario: Use wildcards for set activity calendar + Scenario Outline: Use wildcards for set activity calendar Given a dlms device - | DeviceIdentification | TEST1024000000001 | - | DeviceType | SMART_METER_E | + | DeviceIdentification | | + | DeviceType | SMART_METER_E | + | Protocol | | + | ProtocolVersion | | When the set activity calendar request is received - | DeviceIdentification | TEST1024000000001 | + | DeviceIdentification | | Then the activity calendar profiles are set on the device - | DeviceIdentification | TEST1024000000001 | + | DeviceIdentification | | + + Examples: + | deviceIdentification | protocol | version | + | TEST1024000000002 | DSMR | 2.2 | + | TEST1024000000002 | DSMR | 4.2.2 | + | TEST1031000000002 | SMR | 4.3 | + | TEST1027000000002 | SMR | 5.0.0 | + | TEST1028000000002 | SMR | 5.1 | + | TEST1028000000002 | SMR | 5.2 | + | TEST1028000000002 | SMR | 5.5 | \ No newline at end of file diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/configuration/SetAlarmNotifications.feature b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/configuration/SetAlarmNotifications.feature index e7ace8f9240..a53c6f7e974 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/configuration/SetAlarmNotifications.feature +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/configuration/SetAlarmNotifications.feature @@ -8,12 +8,15 @@ Feature: SmartMetering Configuration - Set Alarm Notifications I want to be able to set alarm notifications on a device So I can control which types of alarms result in pushed notifications - Scenario: Set alarm notifications in register 1 on a DSMR 4.2.2 device (other alarms in request that are not in register 1 are ignored) + Scenario Outline: Set alarm notifications in register 1 on a device (other alarms in request that are not in register 1 are ignored) Given a dlms device | DeviceIdentification | TEST1024000000001 | | DeviceType | SMART_METER_E | - | Protocol | DSMR | - | ProtocolVersion | 4.2.2 | + | Protocol | | + | ProtocolVersion | | + | Lls1active | | + | Hls5active | | + | Port | | When the set alarm notifications request is received | DeviceIdentification | TEST1024000000001 | | AlarmType_1 | CLOCK_INVALID | @@ -25,12 +28,20 @@ Feature: SmartMetering Configuration - Set Alarm Notifications Then the specified alarm notifications should be set on the device | DeviceIdentification | TEST1024000000001 | - Scenario: Set alarm notifications in register 1 and 2 on a DSMR 5.2 device (other alarms in request that are not in register 1 or 2 are ignored) + Examples: + | protocol | version | lls1active | hls5active | port | + | DSMR | 2.2 | true | false | 1026 | + | DSMR | 4.2.2 | false | true | | + | SMR | 4.3 | false | true | | + | SMR | 5.0.0 | false | true | | + | SMR | 5.1 | false | true | | + + Scenario Outline: Set alarm notifications in register 1 and 2 on a device (other alarms in request that are not in register 1 or 2 are ignored) Given a dlms device | DeviceIdentification | TEST1029000000001 | | DeviceType | SMART_METER_E | - | Protocol | SMR | - | ProtocolVersion | 5.2 | + | Protocol | | + | ProtocolVersion | | When the set alarm notifications request is received | DeviceIdentification | TEST1029000000001 | | AlarmType_1 | CLOCK_INVALID | @@ -42,6 +53,11 @@ Feature: SmartMetering Configuration - Set Alarm Notifications Then the specified alarm notifications should be set on the device | DeviceIdentification | TEST1029000000001 | + Examples: + | protocol | version | + | SMR | 5.2 | + | SMR | 5.5 | + Scenario: Set alarm notifications in register 1, 2 and 3 on a SMR 5.5 device Given a dlms device | DeviceIdentification | TEST1030000000001 | @@ -60,12 +76,15 @@ Feature: SmartMetering Configuration - Set Alarm Notifications | DeviceIdentification | TEST1030000000001 | @NightlyBuildOnly - Scenario: Set all alarm notifications disabled on a DSMR 4.2.2 device + Scenario Outline: Set all alarm notifications disabled on a device Given a dlms device | DeviceIdentification | TEST1024000000001 | | DeviceType | SMART_METER_E | - | Protocol | DSMR | - | ProtocolVersion | 4.2.2 | + | Protocol | | + | ProtocolVersion | | + | Lls1active | | + | Hls5active | | + | Port | | When the set alarm notifications request is received | DeviceIdentification | TEST1024000000001 | | AlarmType_1 | CLOCK_INVALID | @@ -125,6 +144,14 @@ Feature: SmartMetering Configuration - Set Alarm Notifications Then the specified alarm notifications should be set on the device | DeviceIdentification | TEST1024000000001 | + Examples: + | protocol | version | lls1active | hls5active | port | + | DSMR | 2.2 | true | false | 1026 | + | DSMR | 4.2.2 | false | true | | + | SMR | 4.3 | false | true | | + | SMR | 5.0.0 | false | true | | + | SMR | 5.1 | false | true | | + @NightlyBuildOnly Scenario: Set all alarm notifications disabled on a SMR 5.2 device Given a dlms device @@ -163,4 +190,4 @@ Feature: SmartMetering Configuration - Set Alarm Notifications | AlarmType_2 | LAST_GASP_TEST | | AlarmTypeEnabled2 | false | Then the specified alarm notifications should be set on the device - | DeviceIdentification | TEST1030000000001 | + | DeviceIdentification | TEST1030000000001 | \ No newline at end of file diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/configuration/SetConfigurationObject.feature b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/configuration/SetConfigurationObject.feature index c097a5bbe67..f8888f74d52 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/configuration/SetConfigurationObject.feature +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/configuration/SetConfigurationObject.feature @@ -2,136 +2,115 @@ # # SPDX-License-Identifier: Apache-2.0 -@SmartMetering @Platform @SmartMeteringConfiguration -Feature: SmartMetering Configuration +@SmartMetering @Platform @SmartMeteringConfiguration @NightlyBuildOnly +Feature: SmartMetering Configuration - SetConfigurationObject As a grid operator I want to be able to set elements of the Configuration Object on a device In order to configure how the device can be communicated with - Background: + Scenario Outline: Set configuration object on a device Given a dlms device - | DeviceIdentification | TEST1024000000001 | - | DeviceType | SMART_METER_E | - And device simulation of "TEST1024000000001" with configuration object - | GprsOperationModeType | ALWAYS_ON | - | ConfigurationFlagCount | 10 | - | ConfigurationFlagType_1 | DISCOVER_ON_OPEN_COVER | - | ConfigurationFlagEnabled_1 | false | - | ConfigurationFlagType_2 | DISCOVER_ON_POWER_ON | - | ConfigurationFlagEnabled_2 | true | - | ConfigurationFlagType_3 | DYNAMIC_MBUS_ADDRESS | - | ConfigurationFlagEnabled_3 | false | - | ConfigurationFlagType_4 | PO_ENABLE | - | ConfigurationFlagEnabled_4 | false | - | ConfigurationFlagType_5 | HLS_3_ON_P_3_ENABLE | - | ConfigurationFlagEnabled_5 | false | - | ConfigurationFlagType_6 | HLS_4_ON_P_3_ENABLE | - | ConfigurationFlagEnabled_6 | false | - | ConfigurationFlagType_7 | HLS_5_ON_P_3_ENABLE | - | ConfigurationFlagEnabled_7 | true | - | ConfigurationFlagType_8 | HLS_3_ON_PO_ENABLE | - | ConfigurationFlagEnabled_8 | false | - | ConfigurationFlagType_9 | HLS_4_ON_PO_ENABLE | - | ConfigurationFlagEnabled_9 | false | - | ConfigurationFlagType_10 | HLS_5_ON_PO_ENABLE | - | ConfigurationFlagEnabled_10 | false | - - Scenario: Set configuration object on a device + | DeviceIdentification | | + | DeviceType | SMART_METER_E | + | Protocol | | + | ProtocolVersion | | + And device simulation of "" with configuration object values in type value attribute + | GprsOperationModeType | | + | ConfigurationFlagCount | | + | ConfigurationFlagType_1 | DISCOVER_ON_OPEN_COVER | + | ConfigurationFlagEnabled_1 | false | + | ConfigurationFlagType_2 | DISCOVER_ON_POWER_ON | + | ConfigurationFlagEnabled_2 | | + | ConfigurationFlagType_3 | DYNAMIC_MBUS_ADDRESS | + | ConfigurationFlagEnabled_3 | false | + | ConfigurationFlagType_4 | PO_ENABLE | + | ConfigurationFlagEnabled_4 | | + | ConfigurationFlagType_5 | HLS_3_ON_P3_ENABLE | + | ConfigurationFlagEnabled_5 | false | + | ConfigurationFlagType_6 | HLS_4_ON_P3_ENABLE | + | ConfigurationFlagEnabled_6 | false | + | ConfigurationFlagType_7 | HLS_5_ON_P3_ENABLE | + | ConfigurationFlagEnabled_7 | false | + | ConfigurationFlagType_8 | HLS_3_ON_P0_ENABLE | + | ConfigurationFlagEnabled_8 | false | + | ConfigurationFlagType_9 | HLS_4_ON_P0_ENABLE | + | ConfigurationFlagEnabled_9 | false | + | ConfigurationFlagType_10 | HLS_5_ON_P0_ENABLE | + | ConfigurationFlagEnabled_10 | false | + | ConfigurationFlagType_11 | DIRECT_ATTACH_AT_POWER_ON | + | ConfigurationFlagEnabled_11 | | + | ConfigurationFlagType_12 | HLS_6_ON_P3_ENABLE | + | ConfigurationFlagEnabled_12 | | + | ConfigurationFlagType_13 | HLS_7_ON_P3_ENABLE | + | ConfigurationFlagEnabled_13 | false | + | ConfigurationFlagType_14 | HLS_6_ON_P0_ENABLE | + | ConfigurationFlagEnabled_14 | false | + | ConfigurationFlagType_15 | HLS_7_ON_P0_ENABLE | + | ConfigurationFlagEnabled_15 | false | When the set configuration object request is received - | DeviceIdentification | TEST1024000000001 | - | ConfigurationFlagCount | 3 | - | ConfigurationFlagType_1 | DISCOVER_ON_OPEN_COVER | - | ConfigurationFlagEnabled_1 | true | - | ConfigurationFlagType_2 | DISCOVER_ON_POWER_ON | - | ConfigurationFlagEnabled_2 | true | - | ConfigurationFlagType_3 | DYNAMIC_MBUS_ADDRESS | - | ConfigurationFlagEnabled_3 | false | - | GprsOperationModeType | ALWAYS_ON | + | DeviceIdentification | | + | ConfigurationFlagCount | 4 | + | ConfigurationFlagType_1 | DISCOVER_ON_POWER_ON | + | ConfigurationFlagEnabled_1 | | + | ConfigurationFlagType_2 | PO_ENABLE | + | ConfigurationFlagEnabled_2 | | + | ConfigurationFlagType_3 | DIRECT_ATTACH_AT_POWER_ON | + | ConfigurationFlagEnabled_3 | | + | ConfigurationFlagType_4 | HLS_6_ON_P3_ENABLE | + | ConfigurationFlagEnabled_4 | | + | GprsOperationModeType | | Then the configuration object should be set on the device - | DeviceIdentification | TEST1024000000001 | - And device simulation of "TEST1024000000001" should be with configuration object - | GprsOperationModeType | ALWAYS_ON | - | ConfigurationFlagCount | 10 | - | ConfigurationFlagType_1 | DISCOVER_ON_OPEN_COVER | - | ConfigurationFlagEnabled_1 | true | - | ConfigurationFlagType_2 | DISCOVER_ON_POWER_ON | - | ConfigurationFlagEnabled_2 | true | - | ConfigurationFlagType_3 | DYNAMIC_MBUS_ADDRESS | - | ConfigurationFlagEnabled_3 | false | - | ConfigurationFlagType_4 | PO_ENABLE | - | ConfigurationFlagEnabled_4 | false | - | ConfigurationFlagType_5 | HLS_3_ON_P_3_ENABLE | - | ConfigurationFlagEnabled_5 | false | - | ConfigurationFlagType_6 | HLS_4_ON_P_3_ENABLE | - | ConfigurationFlagEnabled_6 | false | - | ConfigurationFlagType_7 | HLS_5_ON_P_3_ENABLE | - | ConfigurationFlagEnabled_7 | true | - | ConfigurationFlagType_8 | HLS_3_ON_PO_ENABLE | - | ConfigurationFlagEnabled_8 | false | - | ConfigurationFlagType_9 | HLS_4_ON_PO_ENABLE | - | ConfigurationFlagEnabled_9 | false | - | ConfigurationFlagType_10 | HLS_5_ON_PO_ENABLE | - | ConfigurationFlagEnabled_10 | false | + | DeviceIdentification | | + And device simulation should have values in a type value attribute of the configuration object + | GprsOperationModeType | | + | ConfigurationFlagCount | 15 | + | ConfigurationFlagType_1 | DISCOVER_ON_OPEN_COVER | + | ConfigurationFlagEnabled_1 | false | + | ConfigurationFlagType_2 | DISCOVER_ON_POWER_ON | + | ConfigurationFlagEnabled_2 | | + | ConfigurationFlagType_3 | DYNAMIC_MBUS_ADDRESS | + | ConfigurationFlagEnabled_3 | false | + | ConfigurationFlagType_4 | PO_ENABLE | + | ConfigurationFlagEnabled_4 | | + | ConfigurationFlagType_5 | HLS_3_ON_P3_ENABLE | + | ConfigurationFlagEnabled_5 | false | + | ConfigurationFlagType_6 | HLS_4_ON_P3_ENABLE | + | ConfigurationFlagEnabled_6 | false | + | ConfigurationFlagType_7 | HLS_5_ON_P3_ENABLE | + | ConfigurationFlagEnabled_7 | false | + | ConfigurationFlagType_8 | HLS_3_ON_P0_ENABLE | + | ConfigurationFlagEnabled_8 | false | + | ConfigurationFlagType_9 | HLS_4_ON_P0_ENABLE | + | ConfigurationFlagEnabled_9 | false | + | ConfigurationFlagType_10 | HLS_5_ON_P0_ENABLE | + | ConfigurationFlagEnabled_10 | false | + | ConfigurationFlagType_11 | DIRECT_ATTACH_AT_POWER_ON | + | ConfigurationFlagEnabled_11 | | + | ConfigurationFlagType_12 | HLS_6_ON_P3_ENABLE | + | ConfigurationFlagEnabled_12 | | + | ConfigurationFlagType_13 | HLS_7_ON_P3_ENABLE | + | ConfigurationFlagEnabled_13 | false | + | ConfigurationFlagType_14 | HLS_6_ON_P0_ENABLE | + | ConfigurationFlagEnabled_14 | false | + | ConfigurationFlagType_15 | HLS_7_ON_P0_ENABLE | + | ConfigurationFlagEnabled_15 | false | + Examples: + | deviceIdentification | protocol | version | valueType | flagsInitiallyOnSim | OPMO | OPMO_r | OPMO_1 | DOPO | DOPO_r | DOPO_1 | P0EN | P0EN_r | P0EN_1 | DAPO | DAPO_r | DAPO_1 | H6P3 | H6P3_r | H6P3_1 | + | TEST1024000000001 | DSMR | 4.2.2 | structure | 10 | ALWAYS_ON | TRIGGERED | TRIGGERED | true | true | true | false | false | false | false | | false | false | | false | + | TEST1024000000001 | DSMR | 4.2.2 | structure | 10 | ALWAYS_ON | TRIGGERED | TRIGGERED | true | | true | false | | false | false | | false | false | | false | + | TEST1024000000001 | DSMR | 4.2.2 | structure | 10 | ALWAYS_ON | | ALWAYS_ON | true | true | true | false | false | false | false | | false | false | | false | + | TEST1031000000001 | SMR | 4.3 | structure | 11 | TRIGGERED | ALWAYS_ON | ALWAYS_ON | true | true | true | false | false | false | false | true | true | false | | false | + | TEST1027000000001 | SMR | 5.0.0 | bitstring | 15 | | | | false | | false | true | true | true | true | true | true | true | false | false | + | TEST1028000000001 | SMR | 5.1 | bitstring | 15 | | | | false | | false | true | true | true | false | | false | false | true | true | - @NightlyBuildOnly - Scenario: Set configuration object on a device without GPRS operation mode - When the set configuration object request is received - | DeviceIdentification | TEST1024000000001 | - | ConfigurationFlagCount | 1 | - | ConfigurationFlagType_1 | DISCOVER_ON_POWER_ON | - | ConfigurationFlagEnabled_1 | true | - Then the configuration object should be set on the device - | DeviceIdentification | TEST1024000000001 | - And device simulation of "TEST1024000000001" should be with configuration object - | GprsOperationModeType | ALWAYS_ON | - | ConfigurationFlagCount | 10 | - | ConfigurationFlagType_1 | DISCOVER_ON_OPEN_COVER | - | ConfigurationFlagEnabled_1 | false | - | ConfigurationFlagType_2 | DISCOVER_ON_POWER_ON | - | ConfigurationFlagEnabled_2 | true | - | ConfigurationFlagType_3 | DYNAMIC_MBUS_ADDRESS | - | ConfigurationFlagEnabled_3 | false | - | ConfigurationFlagType_4 | PO_ENABLE | - | ConfigurationFlagEnabled_4 | false | - | ConfigurationFlagType_5 | HLS_3_ON_P_3_ENABLE | - | ConfigurationFlagEnabled_5 | false | - | ConfigurationFlagType_6 | HLS_4_ON_P_3_ENABLE | - | ConfigurationFlagEnabled_6 | false | - | ConfigurationFlagType_7 | HLS_5_ON_P_3_ENABLE | - | ConfigurationFlagEnabled_7 | true | - | ConfigurationFlagType_8 | HLS_3_ON_PO_ENABLE | - | ConfigurationFlagEnabled_8 | false | - | ConfigurationFlagType_9 | HLS_4_ON_PO_ENABLE | - | ConfigurationFlagEnabled_9 | false | - | ConfigurationFlagType_10 | HLS_5_ON_PO_ENABLE | - | ConfigurationFlagEnabled_10 | false | - @NightlyBuildOnly - Scenario: Set configuration object on a device without configuration flags + Scenario: Set configuration object not on a DSMR 2.2 device + Given a dlms device + | DeviceIdentification | TEST1022000000001 | + | DeviceType | SMART_METER_E | + | Protocol | DSMR | + | ProtocolVersion | 2.2 | When the set configuration object request is received - | DeviceIdentification | TEST1024000000001 | - | GprsOperationModeType | TRIGGERED | - Then the configuration object should be set on the device - | DeviceIdentification | TEST1024000000001 | - And device simulation of "TEST1024000000001" should be with configuration object - | GprsOperationModeType | TRIGGERED | - | ConfigurationFlagCount | 10 | - | ConfigurationFlagType_1 | DISCOVER_ON_OPEN_COVER | - | ConfigurationFlagEnabled_1 | false | - | ConfigurationFlagType_2 | DISCOVER_ON_POWER_ON | - | ConfigurationFlagEnabled_2 | true | - | ConfigurationFlagType_3 | DYNAMIC_MBUS_ADDRESS | - | ConfigurationFlagEnabled_3 | false | - | ConfigurationFlagType_4 | PO_ENABLE | - | ConfigurationFlagEnabled_4 | false | - | ConfigurationFlagType_5 | HLS_3_ON_P_3_ENABLE | - | ConfigurationFlagEnabled_5 | false | - | ConfigurationFlagType_6 | HLS_4_ON_P_3_ENABLE | - | ConfigurationFlagEnabled_6 | false | - | ConfigurationFlagType_7 | HLS_5_ON_P_3_ENABLE | - | ConfigurationFlagEnabled_7 | true | - | ConfigurationFlagType_8 | HLS_3_ON_PO_ENABLE | - | ConfigurationFlagEnabled_8 | false | - | ConfigurationFlagType_9 | HLS_4_ON_PO_ENABLE | - | ConfigurationFlagEnabled_9 | false | - | ConfigurationFlagType_10 | HLS_5_ON_PO_ENABLE | - | ConfigurationFlagEnabled_10 | false | + | DeviceIdentification | TEST1022000000001 | + | GprsOperationModeType | TRIGGERED | + Then the configuration object should not be set on the device + | DeviceIdentification | TEST1022000000001 | \ No newline at end of file diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/configuration/SetRandomisationSettings.feature b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/configuration/SetRandomisationSettings.feature index 03a5d802c51..f2d64a1abb3 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/configuration/SetRandomisationSettings.feature +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/configuration/SetRandomisationSettings.feature @@ -7,47 +7,26 @@ Feature: SmartMetering Configuration - SetRandomisationSettings As a grid operator I want to be able to set randomisation settings on a device - Scenario: Set direct attach on a SMR5 device + Scenario Outline: Set randomisation settings on a device with direct attach Given a dlms device - | DeviceIdentification | TEST1027000000001 | - | DeviceType | SMART_METER_E | - | Protocol | SMR | - | ProtocolVersion | 5.1 | - | Port | 1027 | + | DeviceIdentification | | + | DeviceType | SMART_METER_E | + | Protocol | | + | ProtocolVersion | | When the set randomisation settings request is received - | DeviceIdentification | TEST1027000000001 | - | directAttach | 1 | - | randomisationStartWindow | 1 | - | multiplicationFactor | 1 | - | numberOfRetries | 1 | - Then the randomisation settings should be set on the device - - Scenario: Set randomisation settings on a SMR5 device - Given a dlms device - | DeviceIdentification | TEST1027000000001 | - | DeviceType | SMART_METER_E | - | Protocol | SMR | - | ProtocolVersion | 5.1 | - | Port | 1027 | - When the set randomisation settings request is received - | DeviceIdentification | TEST1027000000001 | - | directAttach | 0 | - | randomisationStartWindow | 5 | - | multiplicationFactor | 3 | - | numberOfRetries | 1 | - Then the randomisation settings should be set on the device - - Scenario: Set randomisation settings on a DSMR4 device - Given a dlms device - | DeviceIdentification | TEST1024000000001 | - | DeviceType | SMART_METER_E | - | Protocol | DSMR | - | ProtocolVersion | 4.2.2 | - | Port | 1024 | - When the set randomisation settings request is received - | DeviceIdentification | TEST1024000000001 | - | directAttach | 0 | - | randomisationStartWindow | 10 | - | multiplicationFactor | 4 | - | numberOfRetries | 1 | - Then the randomisation settings should be set on the device + | DeviceIdentification | | + | directAttach | | + | randomisationStartWindow | | + | multiplicationFactor | | + | numberOfRetries | | + Then the randomisation settings on the device + Examples: + | deviceIdentification | protocol | version | da | rsw | mf | nor | shouldBeSetOrNot | + | TEST1028000000001 | SMR | 5.1 | 1 | 1 | 1 | 1 | should be set | + | TEST1028000000001 | SMR | 5.1 | 0 | 5 | 3 | 1 | should be set | + | TEST1027000000001 | SMR | 5.0.0 | 1 | 1 | 1 | 1 | should be set | + | TEST1027000000001 | SMR | 5.0.0 | 0 | 5 | 3 | 1 | should be set | + | TEST1024000000001 | DSMR | 4.2.2 | 1 | 1 | 1 | 1 | should not be set | + | TEST1024000000001 | DSMR | 4.2.2 | 0 | 10 | 4 | 1 | should be set | + | TEST1022000000001 | DSMR | 2.2 | 1 | 1 | 1 | 1 | should not be set | + | TEST1022000000001 | DSMR | 2.2 | 0 | 10 | 4 | 1 | should not be set | diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/installation/AddSmartMeter.feature b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/installation/AddSmartMeter.feature index 80d9f645c0c..03217d1e00d 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/installation/AddSmartMeter.feature +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/installation/AddSmartMeter.feature @@ -17,6 +17,7 @@ Feature: SmartMetering Installation - Add smart meter | protocolName | DSMR | | protocolVersion | 4.2.2 | | Supplier | Kaifa | + | LLS1_active | false | | HLS3_active | false | | HLS4_active | false | | HLS5_active | true | @@ -34,6 +35,7 @@ Feature: SmartMetering Installation - Add smart meter | ModelCode | Test | And the dlms device with identification "TEST1024000000001" exists with properties | DlmsDeviceTimezone | | + | Lls1active | false | And a request to the device can be performed after activation And the new keys are stored in the database in another encryption then the encryption of the keys received in the SOAP request @@ -53,6 +55,7 @@ Feature: SmartMetering Installation - Add smart meter | protocolName | DSMR | | protocolVersion | 4.2.2 | | Supplier | Kaifa | + | LLS1_active | false | | HLS3_active | false | | HLS4_active | false | | HLS5_active | true | diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/management/ClearMBusStatusOnAllChannels.feature b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/management/ClearMBusStatusOnAllChannels.feature index 8f79cfd4204..f92f08e37f9 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/management/ClearMBusStatusOnAllChannels.feature +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/management/ClearMBusStatusOnAllChannels.feature @@ -7,13 +7,38 @@ Feature: SmartMetering Management - Clear M-Bus alarm status on all channels of As a grid operator I want to be able to clear the M-Bus alarm status on all channels of a E meter - Scenario: Clear M-Bus alarm status on all channels of a E-meter + Scenario Outline: Clear M-Bus alarm status on all channels of a E-meter for protocol and check result OK Given a dlms device - | DeviceIdentification | TEST1028000000001 | + | DeviceIdentification | | | DeviceType | SMART_METER_E | - | Protocol | SMR | - | ProtocolVersion | 5.1 | - | Port | 1028 | + | Protocol | | + | ProtocolVersion | | When the clear M-Bus status on all channels request is received - | DeviceIdentification | TEST1028000000001 | + | DeviceIdentification | | Then the clear M-Bus status on all channels response is "OK" + + Examples: + | deviceIdentification | protocol | version | + | TEST1028000000001 | SMR | 5.1 | + | TEST1029000000001 | SMR | 5.2 | + | TEST1030000000001 | SMR | 5.5 | + + @SMHE-1695 + Scenario Outline: Clear M-Bus alarm status on all channels of a E-meter for protocol and check result NOT_OK + Given a dlms device + | DeviceIdentification | | + | DeviceType | SMART_METER_E | + | Protocol | | + | ProtocolVersion | | + When the clear M-Bus status on all channels request is received + | DeviceIdentification | | + Then check notification + | result | NOT_OK | + | message | | + + Examples: + | deviceIdentification | protocol | version | message | + | TEST1024000000001 | DSMR | 2.2 | Did not find READ_MBUS_STATUS object for device 24000000001 for channel 1 | + | TEST1024000000001 | DSMR | 4.2.2 | Did not find READ_MBUS_STATUS object for device 24000000001 for channel 1 | + | TEST1031000000001 | SMR | 4.3 | Did not find READ_MBUS_STATUS object for device 31000000001 for channel 1 | + | TEST1027000000001 | SMR | 5.0.0 | Did not find CLEAR_MBUS_STATUS object for device 27000000001 for channel 1 | diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/management/GetGsmDiagnostic.feature b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/management/GetGsmDiagnostic.feature index 70c42c48148..f7c115dd805 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/management/GetGsmDiagnostic.feature +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/management/GetGsmDiagnostic.feature @@ -7,7 +7,7 @@ Feature: SmartMetering Management - Get GSM Diagnostic As a grid operator I want to be able to get the GSM Diagnostic of a smart meter - Scenario Outline: Get the gsm diagnostic of an E-Meter + Scenario Outline: Get the gsm diagnostic of an E-Meter for Given Given a manufacturer | ManufacturerCode | KAI | @@ -32,7 +32,7 @@ Feature: SmartMetering Management - Get GSM Diagnostic | cellId | 77 | | locationId | 2230 | | signalQuality | MINUS_87_DBM | - | bitErrorRate | RXQUAL_6 | + | bitErrorRate | | | mobileCountryCode | 66 | | mobileNetworkCode | 204 | | channelNumber | 107 | @@ -41,6 +41,10 @@ Feature: SmartMetering Management - Get GSM Diagnostic # Reading of captureTime is disabled for now # | captureTime | 2021-04-13T08:45:00.000Z | Examples: - | DeviceIdentification | Port | Protocol | ProtocolVersion | CommunicationMethod | ModelCode | - | TEST1028000000001 | 1028 | SMR | 5.1 | GPRS | MA105 | - | TEST1031000000001 | 1031 | SMR | 4.3 | CDMA | MA105A | + | DeviceIdentification | Port | Protocol | ProtocolVersion | CommunicationMethod | ModelCode | BitErrorRate | + | TEST1031000000001 | 1031 | SMR | 4.3 | CDMA | MA105A | 6 | + | TEST1027000000001 | 1027 | SMR | 5.0.0 | CDMA | MA105A | 6 | + | TEST1027000000001 | 1027 | SMR | 5.0.0 | GPRS | MA105 | 6 | + | TEST1029000000001 | 1029 | SMR | 5.2 | CDMA | MA105A | 6 | + | TEST1029000000001 | 1029 | SMR | 5.2 | GPRS | MA105 | 6 | + | TEST1029000000001 | 1029 | SMR | 5.2 | LTE | MA105A | 6 | diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/monitoring/AlarmRegister.feature b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/monitoring/ClearAlarmRegister.feature similarity index 69% rename from integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/monitoring/AlarmRegister.feature rename to integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/monitoring/ClearAlarmRegister.feature index 679be8976db..b9004c40bc5 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/monitoring/AlarmRegister.feature +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/monitoring/ClearAlarmRegister.feature @@ -11,45 +11,49 @@ Feature: SmartMetering Monitoring - Alarm Register Background: Given a dlms device - | DeviceIdentification | TEST1024000000001 | + | DeviceIdentification | TEST1027000000001 | | DeviceType | SMART_METER_E | - | SelectiveAccessSupported | true | | Protocol | SMR | | ProtocolVersion | 5.0.0 | Scenario: Read the alarm register from a device - Given device "TEST1024000000001" has alarm register "1" with some value + Given device "TEST1027000000001" has alarm register "1" with some value When the get read alarm register request is received - | DeviceIdentification | TEST1024000000001 | + | DeviceIdentification | TEST1027000000001 | Then the alarm register should be returned - | DeviceIdentification | TEST1024000000001 | + | DeviceIdentification | TEST1027000000001 | + + Scenario Outline: Clear only alarm register 1 for protocol on device - Scenario: Clear alarm register SMR 5.1 Given a dlms device - | DeviceIdentification | TEST1028000000002 | + | DeviceIdentification | | | DeviceType | SMART_METER_E | - | SelectiveAccessSupported | true | - | Protocol | SMR | - | ProtocolVersion | 5.1 | - | Port | 1028 | - And device "TEST1028000000002" has alarm register "1" with some value - And device "TEST1028000000002" has alarm register "2" with some value + | Protocol | | + | ProtocolVersion | | + And device "" has alarm register "1" with some value + And device "" has alarm register "2" with some value When the Clear Alarm Code request is received - | DeviceIdentification | TEST1028000000002 | + | DeviceIdentification | | Then the Clear Alarm Code response should be returned - | DeviceIdentification | TEST1028000000002 | + | DeviceIdentification | | | Result | OK | - And alarm register "1" of device "TEST1028000000002" has been cleared - And alarm register "2" of device "TEST1028000000002" has not been cleared + And alarm register "1" of device "" has been cleared + And alarm register "2" of device "" has not been cleared + Examples: + + | deviceIdentification | protocol | version | + | TEST1024000000002 | DSMR | 2.2 | + | TEST1024000000002 | DSMR | 4.2.2 | + | TEST1031000000002 | SMR | 4.3 | + | TEST1027000000002 | SMR | 5.0.0 | + | TEST1028000000002 | SMR | 5.1 | Scenario: Clear both alarm registers with SMR 5.2 Given a dlms device | DeviceIdentification | TEST1029000000001 | | DeviceType | SMART_METER_E | - | SelectiveAccessSupported | true | | Protocol | SMR | | ProtocolVersion | 5.2 | - | Port | 1029 | And device "TEST1029000000001" has alarm register "1" with some value And device "TEST1029000000001" has alarm register "2" with some value When the Clear Alarm Code request is received @@ -64,10 +68,8 @@ Feature: SmartMetering Monitoring - Alarm Register Given a dlms device | DeviceIdentification | TEST1030000000001 | | DeviceType | SMART_METER_E | - | SelectiveAccessSupported | true | | Protocol | SMR | | ProtocolVersion | 5.5 | - | Port | 1030 | And device "TEST1030000000001" has alarm register "1" with some value And device "TEST1030000000001" has alarm register "2" with some value And device "TEST1030000000001" has alarm register "3" with some value diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/monitoring/GetActualPowerQuality.feature b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/monitoring/GetActualPowerQuality.feature index df357deb8d9..e069d843db4 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/monitoring/GetActualPowerQuality.feature +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/monitoring/GetActualPowerQuality.feature @@ -10,13 +10,14 @@ Feature: SmartMetering Monitoring - Get Actual Power Quality Scenario Outline: Get the actual power quality public from a device for a polyphase meter Given a dlms device - | DeviceIdentification | | - | DeviceType | SMART_METER_E | - | Protocol | | - | ProtocolVersion | | - | Polyphase | true | - | Lls1active | | - | Hls5active | | + | DeviceIdentification | | + | DeviceType | SMART_METER_E | + | Protocol | | + | ProtocolVersion | | + | Port | | + | Polyphase | true | + | Lls1active | | + | Hls5active | | When the get actual power quality request is received | DeviceIdentification | | | ProfileType | PUBLIC | @@ -46,10 +47,10 @@ Feature: SmartMetering Monitoring - Get Actual Power Quality | PowerQualityObject_Name_15 | NUMBER_OF_VOLTAGE_SWELLS_FOR_L3 | Examples: - | DeviceId | Protocol | ProtocolVersion | Lls1active | Hls5active | - | KTEST10260000001 | DSMR | 2.2 | true | false | - | TEST1024000000001 | DSMR | 4.2.2 | false | true | - | TEST1027000000001 | SMR | 5.0.0 | false | true | + | DeviceId | Protocol | ProtocolVersion | Port | Lls1active | Hls5active | + | KTEST10260000001 | DSMR | 2.2 | 1026 | true | false | + | TEST1024000000001 | DSMR | 4.2.2 | | false | true | + | TEST1027000000001 | SMR | 5.0.0 | | false | true | Scenario Outline: Get the actual power quality public from a device for a single phase meter Given a dlms device @@ -57,6 +58,7 @@ Feature: SmartMetering Monitoring - Get Actual Power Quality | DeviceType | SMART_METER_E | | Protocol | | | ProtocolVersion | | + | Port | | | Polyphase | false | | Lls1active | | | Hls5active | | @@ -77,10 +79,10 @@ Feature: SmartMetering Monitoring - Get Actual Power Quality | PowerQualityObject_Name_7 | NUMBER_OF_VOLTAGE_SWELLS_FOR_L1 | Examples: - | DeviceId | Protocol | ProtocolVersion | Lls1active | Hls5active | - | KTEST10260000001 | DSMR | 2.2 | true | false | - | TEST1024000000001 | DSMR | 4.2.2 | false | true | - | TEST1027000000001 | SMR | 5.0.0 | false | true | + | DeviceId | Protocol | ProtocolVersion | Port | Lls1active | Hls5active | + | KTEST10260000001 | DSMR | 2.2 | 1026 | true | false | + | TEST1024000000001 | DSMR | 4.2.2 | | false | true | + | TEST1027000000001 | SMR | 5.0.0 | | false | true | Scenario Outline: Get the actual power quality private from a device for a polyphase meter Given a dlms device @@ -88,6 +90,7 @@ Feature: SmartMetering Monitoring - Get Actual Power Quality | DeviceType | SMART_METER_E | | Protocol | | | ProtocolVersion | | + | Port | | | Polyphase | true | | Lls1active | | | Hls5active | | @@ -100,16 +103,16 @@ Feature: SmartMetering Monitoring - Get Actual Power Quality # Only for the expectedNumber of objects is checked if a value is present in the response, # the rest of the list below will be ignored. | PowerQualityObject_Name_1 | CLOCK | - | PowerQualityObject_Name_2 | INSTANTANEOUS_ACTIVE_POWER_IMPORT | - | PowerQualityObject_Unit_2 | W | - | PowerQualityObject_Name_3 | INSTANTANEOUS_ACTIVE_CURRENT_TOTAL_OVER_ALL_PHASES | + | PowerQualityObject_Name_2 | INSTANTANEOUS_ACTIVE_CURRENT_TOTAL_OVER_ALL_PHASES | + | PowerQualityObject_Unit_2 | AMP | + | PowerQualityObject_Name_3 | INSTANTANEOUS_CURRENT_L1 | | PowerQualityObject_Unit_3 | AMP | - | PowerQualityObject_Name_4 | INSTANTANEOUS_CURRENT_L1 | + | PowerQualityObject_Name_4 | INSTANTANEOUS_CURRENT_L2 | | PowerQualityObject_Unit_4 | AMP | - | PowerQualityObject_Name_5 | INSTANTANEOUS_CURRENT_L2 | + | PowerQualityObject_Name_5 | INSTANTANEOUS_CURRENT_L3 | | PowerQualityObject_Unit_5 | AMP | - | PowerQualityObject_Name_6 | INSTANTANEOUS_CURRENT_L3 | - | PowerQualityObject_Unit_6 | AMP | + | PowerQualityObject_Name_6 | INSTANTANEOUS_ACTIVE_POWER_IMPORT | + | PowerQualityObject_Unit_6 | W | | PowerQualityObject_Name_7 | INSTANTANEOUS_ACTIVE_POWER_EXPORT | | PowerQualityObject_Unit_7 | W | | PowerQualityObject_Name_8 | INSTANTANEOUS_ACTIVE_POWER_IMPORT_L1 | @@ -156,20 +159,21 @@ Feature: SmartMetering Monitoring - Get Actual Power Quality | PowerQualityObject_Unit_28 | AMP | Examples: - | DeviceId | Protocol | ProtocolVersion | Lls1active | Hls5active | ExpectedNumber | - | KTEST10260000001 | DSMR | 2.2 | true | false | 6 | - | TEST1024000000001 | DSMR | 4.2.2 | false | true | 28 | - | TEST1027000000001 | SMR | 5.0.0 | false | true | 28 | + | DeviceId | Protocol | ProtocolVersion | Port | Lls1active | Hls5active | ExpectedNumber | + | KTEST10260000001 | DSMR | 2.2 | 1026 | true | false | 5 | + | TEST1024000000001 | DSMR | 4.2.2 | | false | true | 28 | + | TEST1027000000001 | SMR | 5.0.0 | | false | true | 28 | Scenario Outline: Get the actual power quality private from a device for a single phase meter Given a dlms device - | DeviceIdentification | | - | DeviceType | SMART_METER_E | - | Protocol | | - | ProtocolVersion | | - | Polyphase | false | - | Lls1active | | - | Hls5active | | + | DeviceIdentification | | + | DeviceType | SMART_METER_E | + | Protocol | | + | ProtocolVersion | | + | Port | | + | Polyphase | false | + | Lls1active | | + | Hls5active | | When the get actual power quality request is received | DeviceIdentification | | | ProfileType | PRIVATE | @@ -179,12 +183,12 @@ Feature: SmartMetering Monitoring - Get Actual Power Quality # Only for the expectedNumber of objects is checked if a value is present in the response, # the rest of the list below will be ignored. | PowerQualityObject_Name_1 | CLOCK | - | PowerQualityObject_Name_2 | INSTANTANEOUS_ACTIVE_POWER_IMPORT | - | PowerQualityObject_Unit_2 | W | - | PowerQualityObject_Name_3 | INSTANTANEOUS_CURRENT_L1 | + | PowerQualityObject_Name_2 | INSTANTANEOUS_CURRENT_L1 | + | PowerQualityObject_Unit_2 | AMP | + | PowerQualityObject_Name_3 | INSTANTANEOUS_ACTIVE_CURRENT_TOTAL_OVER_ALL_PHASES | | PowerQualityObject_Unit_3 | AMP | - | PowerQualityObject_Name_4 | INSTANTANEOUS_ACTIVE_CURRENT_TOTAL_OVER_ALL_PHASES | - | PowerQualityObject_Unit_4 | AMP | + | PowerQualityObject_Name_4 | INSTANTANEOUS_ACTIVE_POWER_IMPORT | + | PowerQualityObject_Unit_4 | W | | PowerQualityObject_Name_5 | INSTANTANEOUS_ACTIVE_POWER_EXPORT | | PowerQualityObject_Unit_5 | W | | PowerQualityObject_Name_6 | INSTANTANEOUS_ACTIVE_POWER_IMPORT_L1 | @@ -203,10 +207,10 @@ Feature: SmartMetering Monitoring - Get Actual Power Quality | PowerQualityObject_Unit_12 | AMP | Examples: - | DeviceId | Protocol | ProtocolVersion | Lls1active | Hls5active | ExpectedNumber | - | KTEST10260000001 | DSMR | 2.2 | true | false | 3 | - | TEST1024000000001 | DSMR | 4.2.2 | false | true | 12 | - | TEST1027000000001 | SMR | 5.0.0 | false | true | 12 | + | DeviceId | Protocol | ProtocolVersion | Port | Lls1active | Hls5active | ExpectedNumber | + | KTEST10260000001 | DSMR | 2.2 | 1026 | true | false | 3 | + | TEST1024000000001 | DSMR | 4.2.2 | | false | true | 12 | + | TEST1027000000001 | SMR | 5.0.0 | | false | true | 12 | Scenario: Do not refuse an operation with an inactive device Given a dlms device diff --git a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/monitoring/GetPeriodicMeterReads.feature b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/monitoring/GetPeriodicMeterReads.feature index 759ec5dc602..417f84c4a74 100644 --- a/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/monitoring/GetPeriodicMeterReads.feature +++ b/integration-tests/cucumber-tests-platform-smartmetering/src/test/resources/features/osgp-adapter-ws-smartmetering/monitoring/GetPeriodicMeterReads.feature @@ -14,7 +14,6 @@ Feature: SmartMetering Monitoring - Get Periodic Meter Reads | DeviceType | SMART_METER_E | | Protocol | | | ProtocolVersion | | - | Port | | When the get "" meter reads request is received | DeviceIdentification | | | PeriodType | | @@ -24,13 +23,16 @@ Feature: SmartMetering Monitoring - Get Periodic Meter Reads | DeviceIdentification | | Examples: - | PeriodType | BeginDate | EndDate | DeviceId | Protocol | ProtocolVersion | Port | - | INTERVAL | 2015-09-01T00:00:00.000Z | 2015-10-01T00:00:00.000Z | TEST1024000000001 | DSMR | 4.2.2 | 1024 | - | MONTHLY | 2016-01-01T00:00:00.000Z | 2016-09-01T00:00:00.000Z | TEST1024000000001 | DSMR | 4.2.2 | 1024 | - | DAILY | 2022-05-02T00:00:00.000Z | 2022-05-02T00:00:00.000Z | TEST1024000000001 | DSMR | 4.2.2 | 1024 | - | INTERVAL | 2015-09-01T00:00:00.000Z | 2015-10-01T00:00:00.000Z | TEST1027000000001 | SMR | 5.0.0 | 1027 | - | MONTHLY | 2016-01-01T00:00:00.000Z | 2016-09-01T00:00:00.000Z | TEST1027000000001 | SMR | 5.0.0 | 1027 | - | DAILY | 2022-05-02T00:00:00.000Z | 2022-05-02T00:00:00.000Z | TEST1027000000001 | SMR | 5.0.0 | 1027 | + | PeriodType | BeginDate | EndDate | DeviceId | Protocol | ProtocolVersion | + | INTERVAL | 2015-09-01T00:00:00.000Z | 2015-10-01T00:00:00.000Z | TEST1026000000001 | DSMR | 2.2 | + | MONTHLY | 2016-01-01T00:00:00.000Z | 2016-09-01T00:00:00.000Z | TEST1026000000001 | DSMR | 2.2 | + | DAILY | 2022-05-02T00:00:00.000Z | 2022-05-02T00:00:00.000Z | TEST1026000000001 | DSMR | 2.2 | + | INTERVAL | 2015-09-01T00:00:00.000Z | 2015-10-01T00:00:00.000Z | TEST1024000000001 | DSMR | 4.2.2 | + | MONTHLY | 2016-01-01T00:00:00.000Z | 2016-09-01T00:00:00.000Z | TEST1024000000001 | DSMR | 4.2.2 | + | DAILY | 2022-05-02T00:00:00.000Z | 2022-05-02T00:00:00.000Z | TEST1024000000001 | DSMR | 4.2.2 | + | INTERVAL | 2015-09-01T00:00:00.000Z | 2015-10-01T00:00:00.000Z | TEST1027000000001 | SMR | 5.0.0 | + | MONTHLY | 2016-01-01T00:00:00.000Z | 2016-09-01T00:00:00.000Z | TEST1027000000001 | SMR | 5.0.0 | + | DAILY | 2022-05-02T00:00:00.000Z | 2022-05-02T00:00:00.000Z | TEST1027000000001 | SMR | 5.0.0 | Scenario Outline: Get the periodic meter reads from a G-meter Given a dlms device @@ -38,7 +40,6 @@ Feature: SmartMetering Monitoring - Get Periodic Meter Reads | DeviceType | SMART_METER_E | | Protocol | | | ProtocolVersion | | - | Port | | And a dlms device | DeviceIdentification | | | DeviceType | SMART_METER_G | @@ -53,10 +54,25 @@ Feature: SmartMetering Monitoring - Get Periodic Meter Reads | DeviceIdentification | | Examples: - | PeriodType | BeginDate | EndDate | MBusId | DeviceId | Protocol | ProtocolVersion | Port | - | INTERVAL | 2015-09-01T00:00:00.000Z | 2015-10-01T00:00:00.000Z | TESTG102400000001 | TEST1024000000001 | DSMR | 4.2.2 | 1024 | - | MONTHLY | 2016-01-01T00:00:00.000Z | 2016-09-01T00:00:00.000Z | TESTG102400000001 | TEST1024000000001 | DSMR | 4.2.2 | 1024 | - | DAILY | 2022-05-02T00:00:00.000Z | 2022-05-02T00:00:00.000Z | TESTG102400000001 | TEST1024000000001 | DSMR | 4.2.2 | 1024 | - | INTERVAL | 2015-09-01T00:00:00.000Z | 2015-10-01T00:00:00.000Z | TESTG102700000001 | TEST1027000000001 | SMR | 5.0.0 | 1027 | - | MONTHLY | 2016-01-01T00:00:00.000Z | 2016-09-01T00:00:00.000Z | TESTG102700000001 | TEST1027000000001 | SMR | 5.0.0 | 1027 | - | DAILY | 2022-05-02T00:00:00.000Z | 2022-05-02T00:00:00.000Z | TESTG102700000001 | TEST1027000000001 | SMR | 5.0.0 | 1027 | \ No newline at end of file + | PeriodType | BeginDate | EndDate | MBusId | DeviceId | Protocol | ProtocolVersion | + | INTERVAL | 2015-09-01T00:00:00.000Z | 2015-10-01T00:00:00.000Z | TESTG102600000001 | TEST1026000000001 | DSMR | 2.2 | + | MONTHLY | 2016-01-01T00:00:00.000Z | 2016-09-01T00:00:00.000Z | TESTG102600000001 | TEST1026000000001 | DSMR | 2.2 | + | DAILY | 2022-05-02T00:00:00.000Z | 2022-05-02T00:00:00.000Z | TESTG102600000001 | TEST1026000000001 | DSMR | 2.2 | + | INTERVAL | 2015-09-01T00:00:00.000Z | 2015-10-01T00:00:00.000Z | TESTG102400000001 | TEST1024000000001 | DSMR | 4.2.2 | + | MONTHLY | 2016-01-01T00:00:00.000Z | 2016-09-01T00:00:00.000Z | TESTG102400000001 | TEST1024000000001 | DSMR | 4.2.2 | + | DAILY | 2022-05-02T00:00:00.000Z | 2022-05-02T00:00:00.000Z | TESTG102400000001 | TEST1024000000001 | DSMR | 4.2.2 | + | INTERVAL | 2015-09-01T00:00:00.000Z | 2015-10-01T00:00:00.000Z | TESTG103100000001 | TEST1031000000001 | SMR | 4.3 | + | MONTHLY | 2016-01-01T00:00:00.000Z | 2016-09-01T00:00:00.000Z | TESTG103100000001 | TEST1031000000001 | SMR | 4.3 | + | DAILY | 2022-05-02T00:00:00.000Z | 2022-05-02T00:00:00.000Z | TESTG103100000001 | TEST1031000000001 | SMR | 4.3 | + | INTERVAL | 2015-09-01T00:00:00.000Z | 2015-10-01T00:00:00.000Z | TESTG102700000001 | TEST1027000000001 | SMR | 5.0.0 | + | MONTHLY | 2016-01-01T00:00:00.000Z | 2016-09-01T00:00:00.000Z | TESTG102700000001 | TEST1027000000001 | SMR | 5.0.0 | + | DAILY | 2022-05-02T00:00:00.000Z | 2022-05-02T00:00:00.000Z | TESTG102700000001 | TEST1027000000001 | SMR | 5.0.0 | + | INTERVAL | 2015-09-01T00:00:00.000Z | 2015-10-01T00:00:00.000Z | TESTG102800000001 | TEST1028000000001 | SMR | 5.1 | + | MONTHLY | 2016-01-01T00:00:00.000Z | 2016-09-01T00:00:00.000Z | TESTG102800000001 | TEST1028000000001 | SMR | 5.1 | + | DAILY | 2022-05-02T00:00:00.000Z | 2022-05-02T00:00:00.000Z | TESTG102800000001 | TEST1028000000001 | SMR | 5.1 | + | INTERVAL | 2015-09-01T00:00:00.000Z | 2015-10-01T00:00:00.000Z | TESTG102900000001 | TEST1029000000001 | SMR | 5.2 | + | MONTHLY | 2016-01-01T00:00:00.000Z | 2016-09-01T00:00:00.000Z | TESTG102900000001 | TEST1029000000001 | SMR | 5.2 | + | DAILY | 2022-05-02T00:00:00.000Z | 2022-05-02T00:00:00.000Z | TESTG102900000001 | TEST1029000000001 | SMR | 5.2 | + | INTERVAL | 2015-09-01T00:00:00.000Z | 2015-10-01T00:00:00.000Z | TESTG103000000001 | TEST1030000000001 | SMR | 5.5 | + | MONTHLY | 2016-01-01T00:00:00.000Z | 2016-09-01T00:00:00.000Z | TESTG103000000001 | TEST1030000000001 | SMR | 5.5 | + | DAILY | 2022-05-02T00:00:00.000Z | 2022-05-02T00:00:00.000Z | TESTG103000000001 | TEST1030000000001 | SMR | 5.5 | diff --git a/integration-tests/cucumber-tests-platform/pom.xml b/integration-tests/cucumber-tests-platform/pom.xml index 76b8965a503..14cf616c87b 100644 --- a/integration-tests/cucumber-tests-platform/pom.xml +++ b/integration-tests/cucumber-tests-platform/pom.xml @@ -12,7 +12,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-integration-tests - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-integration-tests/pom.xml diff --git a/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/PlatformDefaults.java b/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/PlatformDefaults.java index 1ea1d13d72f..849aac91bdb 100644 --- a/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/PlatformDefaults.java +++ b/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/PlatformDefaults.java @@ -5,7 +5,6 @@ package org.opensmartgridplatform.cucumber.platform; import java.time.ZonedDateTime; -import org.joda.time.DateTime; import org.opensmartgridplatform.domain.core.valueobjects.DeviceLifecycleStatus; import org.opensmartgridplatform.domain.core.valueobjects.RelayType; @@ -124,7 +123,8 @@ public class PlatformDefaults { public static final String DEFAULT_SMART_METER_DEVICE_IDENTIFICATION = "TEST1024000000001"; public static final String DEFAULT_SMART_METER_GAS_DEVICE_IDENTIFICATION = "TESTG102400000001"; public static final String DEFAULT_SUPPLIER = "Kaifa"; - public static final DateTime DEFAULT_TECHNICAL_INSTALLATION_DATE = DateTime.now().minusDays(1); + public static final ZonedDateTime DEFAULT_TECHNICAL_INSTALLATION_DATE = + ZonedDateTime.now().minusDays(1); public static final ZonedDateTime DEFAULT_TECHNICAL_INSTALLATION_DATE_ZONED = ZonedDateTime.now().minusDays(1); public static final Integer DEFAULT_TOTAL_LIGHTING_HOURS = 144; @@ -136,6 +136,7 @@ public class PlatformDefaults { public static final String DLMS_DEFAULT_COMMUNICATION_METHOD = "GPRS"; public static final String DLMS_DEFAULT_DEVICE_TYPE = "SMART_METER_E"; + public static final Boolean DLMS_DEFAULT_LLS1_ACTIVE = false; public static final Boolean DLMS_DEFAULT_HSL3_ACTIVE = false; public static final Boolean DLMS_DEFAULT_HSL4_ACTIVE = false; public static final Boolean DLMS_DEFAULT_HSL5_ACTIVE = true; @@ -148,7 +149,7 @@ public class PlatformDefaults { public static final String EMAIL = "someone@somewhere.nl"; public static final Boolean EVENTS_NODELIST_EXPECTED = false; public static final String EXPECTED_RESULT_OK = "OK"; - public static final DateTime EXPIRYDATECONTRACT = DateTime.now().plusWeeks(1); + public static final ZonedDateTime EXPIRYDATECONTRACT = ZonedDateTime.now().plusWeeks(1); public static final String PHONENUMBER = "+31 43 1234567"; public static final org.opensmartgridplatform.domain.core.valueobjects.PlatformFunctionGroup PLATFORM_FUNCTION_GROUP = @@ -206,7 +207,7 @@ public class PlatformDefaults { public static final Boolean LAST_SWITCHING_EVENT_STATE = false; public static final Boolean LAST_KNOWN_STATE = false; - public static final DateTime DATE_NOW = DateTime.now(); + public static final ZonedDateTime DATE_NOW = ZonedDateTime.now(); public static final String TODAY = "today"; public static final String DEVICE_UID = "dGVzdDEyMzQ1Njc4"; diff --git a/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/PlatformKeys.java b/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/PlatformKeys.java index fdd23863e65..33abb75e8da 100644 --- a/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/PlatformKeys.java +++ b/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/PlatformKeys.java @@ -92,6 +92,7 @@ public class PlatformKeys extends Keys { public static final String KEY_DEVICE_PROTOCOL_VARIANT = "protocolVariant"; public static final String KEY_DEVICE_EXTERNAL_MANAGED = "DeviceExternalManaged"; public static final String KEY_DEVICE_FUNCTION_GROUP = "DeviceFunctionGroup"; + public static final String KEY_DEVICE_LLS1ACTIVE = "LLS1_active"; public static final String KEY_DEVICE_HLS3ACTIVE = "HLS3_active"; public static final String KEY_DEVICE_HLS4ACTIVE = "HLS4_active"; public static final String KEY_DEVICE_HLS5ACTIVE = "HLS5_active"; @@ -299,7 +300,7 @@ public class PlatformKeys extends Keys { public static final String HOSTNAME = "Hostname"; public static final String PORT = "Port"; - public static final String IP_ADDRESS = "IpAddress"; + public static final String NETWORK_ADDRESS = "NetworkAddress"; public static final String BTS_ID = "BtsId"; public static final String CELL_ID = "CellId"; diff --git a/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/core/builders/DeviceFirmwareFileBuilder.java b/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/core/builders/DeviceFirmwareFileBuilder.java index ea2b92106fc..2a146903a63 100644 --- a/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/core/builders/DeviceFirmwareFileBuilder.java +++ b/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/core/builders/DeviceFirmwareFileBuilder.java @@ -4,23 +4,24 @@ package org.opensmartgridplatform.cucumber.platform.core.builders; -import java.util.Date; +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.util.Map; import org.opensmartgridplatform.cucumber.platform.PlatformKeys; -import org.opensmartgridplatform.cucumber.platform.helpers.UtcDateHelper; -import org.opensmartgridplatform.cucumber.platform.inputparsers.DateInputParser; import org.opensmartgridplatform.domain.core.entities.Device; import org.opensmartgridplatform.domain.core.entities.DeviceFirmwareFile; import org.opensmartgridplatform.domain.core.entities.FirmwareFile; +import org.opensmartgridplatform.shared.utils.JavaTimeHelpers; public class DeviceFirmwareFileBuilder implements CucumberBuilder { - private Date installationDate = UtcDateHelper.getUtcDate(); + private Instant installationDate = ZonedDateTime.now(ZoneId.of("UTC")).toInstant(); private String installedBy = "test-org"; private FirmwareFile firmwareFile; private Device device; - public DeviceFirmwareFileBuilder withInstallationDate(final Date installationDate) { + public DeviceFirmwareFileBuilder withInstallationDate(final Instant installationDate) { this.installationDate = installationDate; return this; } @@ -50,7 +51,9 @@ public DeviceFirmwareFile build() { public DeviceFirmwareFileBuilder withSettings(final Map inputSettings) { if (inputSettings.containsKey(PlatformKeys.DEVICEFIRMWARE_INSTALLATIONDATE)) { this.withInstallationDate( - DateInputParser.parse(inputSettings.get(PlatformKeys.DEVICEFIRMWARE_INSTALLATIONDATE))); + JavaTimeHelpers.parseToZonedDateTime( + inputSettings.get(PlatformKeys.DEVICEFIRMWARE_INSTALLATIONDATE)) + .toInstant()); } if (inputSettings.containsKey(PlatformKeys.DEVICEFIRMWARE_INSTALLED_BY)) { diff --git a/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/core/factories/RelayStatusFactory.java b/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/core/factories/RelayStatusFactory.java index e22e04c6a1d..c60369290ad 100644 --- a/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/core/factories/RelayStatusFactory.java +++ b/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/core/factories/RelayStatusFactory.java @@ -8,8 +8,8 @@ import static org.opensmartgridplatform.cucumber.core.ReadSettingsHelper.getInteger; import static org.opensmartgridplatform.cucumber.core.ReadSettingsHelper.getString; +import java.time.ZonedDateTime; import java.util.Map; -import org.joda.time.DateTime; import org.opensmartgridplatform.cucumber.platform.PlatformKeys; import org.opensmartgridplatform.domain.core.entities.RelayStatus; import org.opensmartgridplatform.domain.core.entities.Ssld; @@ -30,15 +30,16 @@ public RelayStatus fromMap(final Ssld ssld, final Map settings) final Integer index = getInteger(settings, PlatformKeys.KEY_INDEX); final boolean lastSwitchingEventState = "On".equals(getString(settings, PlatformKeys.LAST_SWITCHING_EVENT_STATE)); - final DateTime lastSwitchingEventTime = + final ZonedDateTime lastSwitchingEventTime = getDate(settings, PlatformKeys.LAST_SWITCHING_EVENT_TIME); final boolean lastKnownState = "On".equals(getString(settings, PlatformKeys.LAST_KNOWN_STATE)); - final DateTime lastKnownStateTime = getDate(settings, PlatformKeys.LAST_KNOWN_STATE_TIME); + final ZonedDateTime lastKnownStateTime = getDate(settings, PlatformKeys.LAST_KNOWN_STATE_TIME); final RelayStatus relayStatus = new RelayStatus.Builder(ssld, index) - .withLastKnownState(lastKnownState, lastKnownStateTime.toDate()) - .withLastSwitchingEventState(lastSwitchingEventState, lastSwitchingEventTime.toDate()) + .withLastKnownState(lastKnownState, lastKnownStateTime.toInstant()) + .withLastSwitchingEventState( + lastSwitchingEventState, lastSwitchingEventTime.toInstant()) .build(); return relayStatus; @@ -50,18 +51,19 @@ public RelayStatus fromMap(final Map settings) { final RelayStatus.Builder builder = new RelayStatus.Builder(index); final String eventState = getString(settings, PlatformKeys.LAST_SWITCHING_EVENT_STATE); - final DateTime lastSwitchingEventTime = + final ZonedDateTime lastSwitchingEventTime = getDate(settings, PlatformKeys.LAST_SWITCHING_EVENT_TIME); if (eventState != null && lastSwitchingEventTime != null) { final boolean lastSwitchingEventState = "On".equals(eventState); - builder.withLastSwitchingEventState(lastSwitchingEventState, lastSwitchingEventTime.toDate()); + builder.withLastSwitchingEventState( + lastSwitchingEventState, lastSwitchingEventTime.toInstant()); } final String knownState = getString(settings, PlatformKeys.LAST_KNOWN_STATE); - final DateTime lastKnownStateTime = getDate(settings, PlatformKeys.LAST_KNOWN_STATE_TIME); + final ZonedDateTime lastKnownStateTime = getDate(settings, PlatformKeys.LAST_KNOWN_STATE_TIME); if (knownState != null && lastKnownStateTime != null) { final boolean lastKnownState = "On".equals(knownState); - builder.withLastKnownState(lastKnownState, lastKnownStateTime.toDate()); + builder.withLastKnownState(lastKnownState, lastKnownStateTime.toInstant()); } return builder.build(); diff --git a/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/BaseDeviceSteps.java b/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/BaseDeviceSteps.java index ecb2ece1228..15c76febb12 100644 --- a/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/BaseDeviceSteps.java +++ b/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/BaseDeviceSteps.java @@ -71,7 +71,7 @@ public Device updateDevice(Device device, final Map settings) { if (settings.containsKey(PlatformKeys.KEY_TECHNICAL_INSTALLATION_DATE) && StringUtils.isNotBlank(settings.get(PlatformKeys.KEY_TECHNICAL_INSTALLATION_DATE))) { device.setTechnicalInstallationDate( - getDate(settings, PlatformKeys.KEY_TECHNICAL_INSTALLATION_DATE).toDate()); + getDate(settings, PlatformKeys.KEY_TECHNICAL_INSTALLATION_DATE).toInstant()); } /* @@ -108,7 +108,9 @@ public Device updateDevice(Device device, final Map settings) { inetAddress = InetAddress.getByName( getString( - settings, PlatformKeys.IP_ADDRESS, this.configuration.getDeviceNetworkAddress())); + settings, + PlatformKeys.NETWORK_ADDRESS, + this.configuration.getDeviceNetworkAddress())); } catch (final UnknownHostException e) { inetAddress = InetAddress.getLoopbackAddress(); } @@ -117,7 +119,7 @@ public Device updateDevice(Device device, final Map settings) { device.setCellId(getInteger(settings, PlatformKeys.CELL_ID, null)); device.updateRegistrationData( - inetAddress, + inetAddress.getHostAddress(), getString(settings, PlatformKeys.KEY_DEVICE_TYPE, PlatformDefaults.DEFAULT_DEVICE_TYPE)); device.updateInMaintenance( diff --git a/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/DeviceFirmwareFileSteps.java b/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/DeviceFirmwareFileSteps.java index c858b0668c8..fe16c8c10aa 100644 --- a/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/DeviceFirmwareFileSteps.java +++ b/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/DeviceFirmwareFileSteps.java @@ -10,11 +10,11 @@ import io.cucumber.java.en.Given; import io.cucumber.java.en.Then; -import java.util.Date; +import java.time.Instant; +import java.time.ZonedDateTime; import java.util.List; import java.util.Map; import org.apache.commons.lang3.StringUtils; -import org.joda.time.DateTime; import org.opensmartgridplatform.cucumber.core.Wait; import org.opensmartgridplatform.cucumber.platform.PlatformDefaults; import org.opensmartgridplatform.cucumber.platform.PlatformKeys; @@ -54,9 +54,10 @@ public void aDeviceFirmware(final Map settings) { final FirmwareFile firmwareFile = this.getFirmwareFile(getString(settings, PlatformKeys.FIRMWARE_FILE_FILENAME)); - final Date installationDate = - getDateTime2(getString(settings, PlatformKeys.FIRMWARE_INSTALLATION_DATE), DateTime.now()) - .toDate(); + final Instant installationDate = + getDateTime2( + getString(settings, PlatformKeys.FIRMWARE_INSTALLATION_DATE), ZonedDateTime.now()) + .toInstant(); final String installedBy = getString( settings, PlatformKeys.FIRMWARE_INSTALLED_BY, PlatformDefaults.FIRMWARE_INSTALLED_BY); @@ -67,7 +68,7 @@ public void aDeviceFirmware(final Map settings) { } private FirmwareFile getFirmwareFile(final String firmwareFileName) { - FirmwareFile firmwareFile; + final FirmwareFile firmwareFile; if (StringUtils.isEmpty(firmwareFileName)) { final List firmwareFiles = this.firmwareFileRepository.findAll(); firmwareFile = firmwareFiles.get(firmwareFiles.size() - 1); diff --git a/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/DeviceOutputSettingsSteps.java b/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/DeviceOutputSettingsSteps.java index cb9bea967fa..ce49e529fa7 100644 --- a/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/DeviceOutputSettingsSteps.java +++ b/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/DeviceOutputSettingsSteps.java @@ -9,8 +9,8 @@ import static org.opensmartgridplatform.cucumber.core.ReadSettingsHelper.getString; import io.cucumber.java.en.Given; +import java.time.Instant; import java.util.ArrayList; -import java.util.Date; import java.util.List; import java.util.Map; import org.opensmartgridplatform.cucumber.platform.PlatformDefaults; @@ -146,7 +146,7 @@ private void saveDeviceOutputSettingsAndRelayStatuses( for (final DeviceOutputSetting deviceOutputSetting : deviceOutputSettings) { final RelayStatus relayStatus = new RelayStatus.Builder(device, deviceOutputSetting.getExternalId()) - .withLastSwitchingEventState(false, new Date()) + .withLastSwitchingEventState(false, Instant.now()) .build(); this.relayStatusRepository.save(relayStatus); diff --git a/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/DeviceSteps.java b/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/DeviceSteps.java index 5b6df0d27e3..39ae699e15c 100644 --- a/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/DeviceSteps.java +++ b/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/DeviceSteps.java @@ -356,9 +356,9 @@ public void theDeviceContains(final Map expectedEntity) { this.deviceRepository.findByDeviceIdentification( getString(expectedEntity, PlatformKeys.KEY_DEVICE_IDENTIFICATION)); - assertThat(device.getIpAddress()) + assertThat(device.getNetworkAddress()) .as("IP address does not match") - .isEqualTo(getString(expectedEntity, PlatformKeys.IP_ADDRESS)); + .isEqualTo(getString(expectedEntity, PlatformKeys.NETWORK_ADDRESS)); }); } } diff --git a/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/EventSteps.java b/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/EventSteps.java index dd423331e8f..49b0ccc26a1 100644 --- a/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/EventSteps.java +++ b/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/EventSteps.java @@ -12,12 +12,12 @@ import io.cucumber.java.en.Given; import io.cucumber.java.en.Then; +import java.time.Instant; +import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.Arrays; -import java.util.Date; import java.util.List; import java.util.Map; -import org.joda.time.DateTime; import org.opensmartgridplatform.cucumber.core.Wait; import org.opensmartgridplatform.cucumber.platform.PlatformDefaults; import org.opensmartgridplatform.cucumber.platform.PlatformKeys; @@ -38,7 +38,8 @@ public class EventSteps { @Given("^an event$") public void anEvent(final Map data) { final String deviceIdentification = getString(data, PlatformKeys.KEY_DEVICE_IDENTIFICATION); - final Date date = getDateTime2(getString(data, PlatformKeys.DATE), DateTime.now()).toDate(); + final Instant date = + getDateTime2(getString(data, PlatformKeys.DATE), ZonedDateTime.now()).toInstant(); final EventType eventType = getEnum(data, PlatformKeys.EVENT_TYPE, EventType.class, EventType.DIAG_EVENTS_GENERAL); final String description = getString(data, PlatformKeys.KEY_DESCRIPTION, ""); diff --git a/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/FirmwareFileSteps.java b/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/FirmwareFileSteps.java index 92773d9f336..aebbb2d108e 100644 --- a/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/FirmwareFileSteps.java +++ b/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/FirmwareFileSteps.java @@ -15,7 +15,7 @@ import io.cucumber.java.en.Then; import java.io.File; import java.io.IOException; -import java.util.Date; +import java.time.Instant; import java.util.List; import java.util.Map; import java.util.UUID; @@ -214,7 +214,7 @@ public void anInstalledFirmwareFileForAnSsld(final Map settings) getString( settings, PlatformKeys.FIRMWARE_FILE_FILENAME, PlatformDefaults.FIRMWARE_FILENAME)); - final Date installationDate = new Date(); + final Instant installationDate = Instant.now(); final String installedByUser = "installed by test code"; @@ -325,7 +325,7 @@ private byte[] getFirmwareFileBytes(final String filename) throws IOException { } private String getFirmwareFilepath(final String filename) { - String path; + final String path; if (StringUtils.endsWith(this.firmwareFilePath, File.separator)) { path = this.firmwareFilePath + filename; } else { diff --git a/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/LightMeasurementDeviceSteps.java b/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/LightMeasurementDeviceSteps.java index 06969e2f16b..0fe3218dc9f 100644 --- a/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/LightMeasurementDeviceSteps.java +++ b/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/LightMeasurementDeviceSteps.java @@ -17,14 +17,12 @@ import java.net.InetAddress; import java.net.UnknownHostException; import java.time.Instant; +import java.time.ZoneId; import java.time.ZoneOffset; import java.time.ZonedDateTime; -import java.util.Date; import java.util.List; import java.util.Map; import org.apache.commons.lang3.StringUtils; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; import org.opensmartgridplatform.cucumber.core.Wait; import org.opensmartgridplatform.cucumber.platform.PlatformDefaults; import org.opensmartgridplatform.cucumber.platform.PlatformKeys; @@ -147,12 +145,13 @@ public LightMeasurementDevice aLightMeasurementDevice(final Map InetAddress.getByName( getString( settings, - PlatformKeys.IP_ADDRESS, + PlatformKeys.NETWORK_ADDRESS, this.configuration.getDeviceNetworkAddress())); } catch (final UnknownHostException e) { inetAddress = InetAddress.getLoopbackAddress(); } - lmd.updateRegistrationData(inetAddress, getString(settings, PlatformKeys.KEY_DEVICE_TYPE)); + lmd.updateRegistrationData( + inetAddress.getHostAddress(), getString(settings, PlatformKeys.KEY_DEVICE_TYPE)); } lmd.updateMetaData( getString(settings, PlatformKeys.ALIAS, PlatformDefaults.DEFAULT_ALIAS), @@ -255,20 +254,20 @@ public LightMeasurementDevice createLightMeasurementDevice( final String deviceType = "LMD"; final InetAddress networkAddress = InetAddress.getLoopbackAddress(); - final Date technicalInstallationDate = DateTime.now().withZone(DateTimeZone.UTC).toDate(); + final Instant technicalInstallationDate = ZonedDateTime.now(ZoneId.of("UTC")).toInstant(); final ProtocolInfo protocolInfo = this.protocolInfoRepository.findByProtocolAndProtocolVersion("IEC61850", "1.0"); final LightMeasurementDevice lightMeasurementDevice = new LightMeasurementDevice(deviceIdentification); lightMeasurementDevice.setTechnicalInstallationDate(technicalInstallationDate); - lightMeasurementDevice.updateRegistrationData(networkAddress, deviceType); + lightMeasurementDevice.updateRegistrationData(networkAddress.getHostAddress(), deviceType); lightMeasurementDevice.updateProtocol(protocolInfo); lightMeasurementDevice.updateInMaintenance(false); lightMeasurementDevice.setDescription(deviceIdentification); lightMeasurementDevice.setCode(code); lightMeasurementDevice.setColor(color); - lightMeasurementDevice.setLastCommunicationTime(technicalInstallationDate.toInstant()); + lightMeasurementDevice.setLastCommunicationTime(technicalInstallationDate); lightMeasurementDevice.setDigitalInput(digitalInput); // Both creates the device and adds the device authorization as owner for the identified diff --git a/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/RelayStatusSteps.java b/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/RelayStatusSteps.java index 4fe9158f737..974ac95ba7a 100644 --- a/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/RelayStatusSteps.java +++ b/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/RelayStatusSteps.java @@ -9,9 +9,9 @@ import io.cucumber.java.en.Given; import io.cucumber.java.en.Then; import java.sql.Timestamp; -import java.util.Date; +import java.time.Instant; +import java.time.ZonedDateTime; import java.util.Map; -import org.joda.time.DateTime; import org.opensmartgridplatform.cucumber.core.Wait; import org.opensmartgridplatform.cucumber.platform.core.factories.RelayStatusFactory; import org.opensmartgridplatform.domain.core.entities.RelayStatus; @@ -58,8 +58,8 @@ public void thereIsADeviceRelayStatusWithARecentLastKnownTime( // Check if the last known state time is at most 3 minutes in the // past - final Date startDate = DateTime.now().minusMinutes(3).toDate(); - assertThat(actual.getLastKnownStateTime().after(startDate)).isTrue(); + final Instant startDate = ZonedDateTime.now().minusMinutes(3).toInstant(); + assertThat(actual.getLastKnownStateTime().isAfter(startDate)).isTrue(); assertThat(actual.isLastKnownState()).isEqualTo(expected.isLastKnownState()); }); } @@ -69,8 +69,9 @@ private void assertLastSwitchingEventEquals( if (expected != null && expected.getLastSwitchingEventTime() != null) { assertThat(actual).isNotNull(); - final Timestamp timestamp = new Timestamp(expected.getLastSwitchingEventTime().getTime()); - assertThat(actual.getLastSwitchingEventTime()).isEqualTo(timestamp); + final Timestamp timestamp = + new Timestamp(expected.getLastSwitchingEventTime().toEpochMilli()); + assertThat(actual.getLastSwitchingEventTime()).isEqualTo(timestamp.toInstant()); assertThat(actual.isLastSwitchingEventState()) .isEqualTo(expected.isLastSwitchingEventState()); } @@ -80,8 +81,8 @@ private void assertLastKnownStateEquals(final RelayStatus expected, final RelayS if (expected != null && expected.getLastKnownStateTime() != null) { assertThat(actual).isNotNull(); - final Timestamp timestamp = new Timestamp(expected.getLastKnownStateTime().getTime()); - assertThat(actual.getLastKnownStateTime()).isEqualTo(timestamp); + final Timestamp timestamp = new Timestamp(expected.getLastKnownStateTime().toEpochMilli()); + assertThat(actual.getLastKnownStateTime()).isEqualTo(timestamp.toInstant()); assertThat(actual.isLastKnownState()).isEqualTo(expected.isLastKnownState()); } } diff --git a/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/RtuDeviceSteps.java b/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/RtuDeviceSteps.java index c857cd0a512..690e846aec5 100644 --- a/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/RtuDeviceSteps.java +++ b/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/RtuDeviceSteps.java @@ -8,8 +8,8 @@ import static org.opensmartgridplatform.cucumber.platform.PlatformKeys.KEY_LAST_COMMUNICATION_TIME; import io.cucumber.java.en.Given; +import java.time.ZonedDateTime; import java.util.Map; -import org.joda.time.DateTime; import org.opensmartgridplatform.cucumber.core.DateTimeHelper; import org.opensmartgridplatform.cucumber.platform.PlatformDefaults; import org.opensmartgridplatform.cucumber.platform.PlatformKeys; @@ -40,7 +40,7 @@ public RtuDevice anRtuDevice(final Map settings) { this.domainInfoRepository.findByDomainAndDomainVersion( getString(settings, PlatformKeys.KEY_DOMAIN, PlatformDefaults.DOMAIN), getString(settings, PlatformKeys.KEY_DOMAIN_VERSION, PlatformDefaults.DOMAIN_VERSION))); - rtuDevice.messageReceived(this.getLastCommunicationTime(settings).toDate().toInstant()); + rtuDevice.messageReceived(this.getLastCommunicationTime(settings).toInstant()); return this.rtuDeviceRepository.save(rtuDevice); } @@ -52,10 +52,10 @@ public Device updateRtuDevice(final Map settings) { settings); } - private DateTime getLastCommunicationTime(final Map settings) { + private ZonedDateTime getLastCommunicationTime(final Map settings) { if (settings.containsKey(KEY_LAST_COMMUNICATION_TIME)) { return DateTimeHelper.getDateTime(settings.get(KEY_LAST_COMMUNICATION_TIME)); } - return DateTime.now(); + return ZonedDateTime.now(); } } diff --git a/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/ScheduledTaskSteps.java b/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/ScheduledTaskSteps.java index 05d6fd442fc..42793645a7d 100644 --- a/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/ScheduledTaskSteps.java +++ b/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/ScheduledTaskSteps.java @@ -18,6 +18,7 @@ import java.sql.Timestamp; import java.util.HashMap; import java.util.Map; +import java.util.Objects; import java.util.function.Function; import org.opensmartgridplatform.cucumber.core.DateTimeHelper; import org.opensmartgridplatform.cucumber.core.ReadSettingsHelper; @@ -53,9 +54,12 @@ private static ScheduledTask createUpdateFirmwareScheduledTask( final String messageType = MessageType.UPDATE_FIRMWARE.toString(); final int messagePriority = 4; final Long scheduleTime = - DateTimeHelper.getDateTime( - ReadSettingsHelper.getString(settings, KEY_SCHEDULED_TIME, DEFAULT_SCHEDULED_TIME)) - .getMillis(); + Objects.requireNonNull( + DateTimeHelper.getDateTime( + ReadSettingsHelper.getString( + settings, KEY_SCHEDULED_TIME, DEFAULT_SCHEDULED_TIME))) + .toInstant() + .toEpochMilli(); final MessageMetadata messageMetadata = new MessageMetadata.Builder() .withDeviceIdentification(deviceIdentification) diff --git a/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/SsldDeviceSteps.java b/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/SsldDeviceSteps.java index 0393dd6aafc..ba5f3039abf 100644 --- a/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/SsldDeviceSteps.java +++ b/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/core/SsldDeviceSteps.java @@ -14,11 +14,11 @@ import io.cucumber.java.en.Given; import io.cucumber.java.en.Then; +import java.time.Instant; +import java.time.ZonedDateTime; import java.util.ArrayList; -import java.util.Date; import java.util.List; import java.util.Map; -import org.joda.time.DateTime; import org.opensmartgridplatform.cucumber.core.Wait; import org.opensmartgridplatform.cucumber.platform.PlatformDefaults; import org.opensmartgridplatform.cucumber.platform.PlatformKeys; @@ -124,7 +124,8 @@ public void aSwitchingEventRelayStatus(final Map settings) { final String[] relayStatus = rs.split(PlatformKeys.SEPARATOR_COMMA); final int index = Integer.parseInt(relayStatus[0]); final boolean lastSwitchingEventState = Boolean.parseBoolean(relayStatus[1]); - final Date lastSwitchingEventTime = getDateTime2(relayStatus[2], DateTime.now()).toDate(); + final Instant lastSwitchingEventTime = + getDateTime2(relayStatus[2], ZonedDateTime.now()).toInstant(); final RelayStatus currentRelayStatus = ssld.getRelayStatusByIndex(index); if (currentRelayStatus == null) { @@ -198,9 +199,9 @@ private Ssld createAnSsldDevice(final Map settings) { PlatformKeys.KEY_FAILED_CONNECTION_COUNT, PlatformDefaults.DEFAULT_FAILED_CONNECTION_COUNT)); - final DateTime lastSuccessfulConnectionTimestamp = - getDate(settings, PlatformKeys.KEY_LAST_COMMUNICATION_TIME, DateTime.now()); - ssld.setLastSuccessfulConnectionTimestamp(lastSuccessfulConnectionTimestamp.toDate()); + final ZonedDateTime lastSuccessfulConnectionTimestamp = + getDate(settings, PlatformKeys.KEY_LAST_COMMUNICATION_TIME, ZonedDateTime.now()); + ssld.setLastSuccessfulConnectionTimestamp(lastSuccessfulConnectionTimestamp.toInstant()); if (settings.containsKey(PlatformKeys.KEY_LIGHTMEASUREMENT_DEVICE_IDENTIFICATION)) { final LightMeasurementDevice lmd = diff --git a/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/logging/DeviceLogItemSteps.java b/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/logging/DeviceLogItemSteps.java index 1563df79aa7..cc245c0b196 100644 --- a/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/logging/DeviceLogItemSteps.java +++ b/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/logging/DeviceLogItemSteps.java @@ -10,7 +10,6 @@ import io.cucumber.java.en.Given; import io.cucumber.java.en.Then; import java.time.ZonedDateTime; -import java.util.Date; import java.util.List; import java.util.Map; import org.opensmartgridplatform.cucumber.platform.PlatformDefaults; @@ -75,7 +74,7 @@ private void updateModificationTime( final long deviceLogItemId, final ZonedDateTime modificationTime) { if (modificationTime != null) { this.deviceLogItemRepository.setModificationTime( - deviceLogItemId, Date.from(modificationTime.toInstant())); + deviceLogItemId, modificationTime.toInstant()); } } diff --git a/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/ws/ResponseUrlDataSteps.java b/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/ws/ResponseUrlDataSteps.java index 791087d8b80..85bd0e3a254 100644 --- a/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/ws/ResponseUrlDataSteps.java +++ b/integration-tests/cucumber-tests-platform/src/test/java/org/opensmartgridplatform/cucumber/platform/glue/steps/database/ws/ResponseUrlDataSteps.java @@ -39,7 +39,7 @@ public void aResponseUrlDataRecord(final Map settings) throws Th fld.setAccessible(true); fld.set( responseUrlData, - DateTimeHelper.getDateTime(settings.get(PlatformKeys.KEY_CREATION_TIME)).toDate()); + DateTimeHelper.getDateTime(settings.get(PlatformKeys.KEY_CREATION_TIME)).toInstant()); this.responseUrlDataRepository.saveAndFlush(responseUrlData); } } diff --git a/integration-tests/cucumber-tests-protocol-iec60870/pom.xml b/integration-tests/cucumber-tests-protocol-iec60870/pom.xml index 7889f3fc15e..367dba7d27e 100644 --- a/integration-tests/cucumber-tests-protocol-iec60870/pom.xml +++ b/integration-tests/cucumber-tests-protocol-iec60870/pom.xml @@ -12,7 +12,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-integration-tests - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-integration-tests/pom.xml diff --git a/integration-tests/parent-integration-tests/pom.xml b/integration-tests/parent-integration-tests/pom.xml index 36a269c5927..541a1135779 100644 --- a/integration-tests/parent-integration-tests/pom.xml +++ b/integration-tests/parent-integration-tests/pom.xml @@ -17,7 +17,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform super-osgp - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../../super/pom.xml diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index 3af3724eda7..25a5eceeaff 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -11,7 +11,7 @@ SPDX-License-Identifier: Apache-2.0 4.0.0 org.opensmartgridplatform integration-tests - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT pom diff --git a/osgp/platform/osgp-adapter-domain-admin/pom.xml b/osgp/platform/osgp-adapter-domain-admin/pom.xml index b689ddef231..9a50ace3c84 100644 --- a/osgp/platform/osgp-adapter-domain-admin/pom.xml +++ b/osgp/platform/osgp-adapter-domain-admin/pom.xml @@ -17,7 +17,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-platform - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-platform/pom.xml diff --git a/osgp/platform/osgp-adapter-domain-admin/src/main/java/org/opensmartgridplatform/adapter/domain/admin/infra/jms/core/OsgpCoreRequestMessageSender.java b/osgp/platform/osgp-adapter-domain-admin/src/main/java/org/opensmartgridplatform/adapter/domain/admin/infra/jms/core/OsgpCoreRequestMessageSender.java index efcb22bacb8..ed5335b162c 100644 --- a/osgp/platform/osgp-adapter-domain-admin/src/main/java/org/opensmartgridplatform/adapter/domain/admin/infra/jms/core/OsgpCoreRequestMessageSender.java +++ b/osgp/platform/osgp-adapter-domain-admin/src/main/java/org/opensmartgridplatform/adapter/domain/admin/infra/jms/core/OsgpCoreRequestMessageSender.java @@ -49,7 +49,7 @@ public Message createMessage(final Session session) throws JMSException { requestMessage.getOrganisationIdentification()); objectMessage.setStringProperty( Constants.DEVICE_IDENTIFICATION, requestMessage.getDeviceIdentification()); - objectMessage.setStringProperty(Constants.IP_ADDRESS, ipAddress); + objectMessage.setStringProperty(Constants.NETWORK_ADDRESS, ipAddress); if (scheduleTime != null) { objectMessage.setLongProperty(Constants.SCHEDULE_TIME, scheduleTime); } diff --git a/osgp/platform/osgp-adapter-domain-core/pom.xml b/osgp/platform/osgp-adapter-domain-core/pom.xml index cdbcbd43dca..ce69ab751b1 100644 --- a/osgp/platform/osgp-adapter-domain-core/pom.xml +++ b/osgp/platform/osgp-adapter-domain-core/pom.xml @@ -17,7 +17,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-platform - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-platform/pom.xml diff --git a/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/services/AdHocManagementService.java b/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/services/AdHocManagementService.java index 4f059973338..9608e02b8e4 100644 --- a/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/services/AdHocManagementService.java +++ b/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/services/AdHocManagementService.java @@ -47,6 +47,6 @@ public void setReboot( new RequestMessage(correlationUid, organisationIdentification, deviceIdentification, null), messageType, messagePriority, - device.getIpAddress()); + device.getNetworkAddress()); } } diff --git a/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/services/ConfigurationManagementService.java b/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/services/ConfigurationManagementService.java index d7095ecb689..247e365573b 100644 --- a/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/services/ConfigurationManagementService.java +++ b/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/services/ConfigurationManagementService.java @@ -88,7 +88,7 @@ public void setConfiguration( new RequestMessage(ids, configurationDto), messageType, messagePriority, - device.getIpAddress(), + device.getNetworkAddress(), scheduleTime); } @@ -139,7 +139,7 @@ public void getConfiguration( new RequestMessage(correlationUid, organisationIdentification, deviceIdentification, null), messageType, messagePriority, - device.getIpAddress()); + device.getNetworkAddress()); } public void handleGetConfigurationResponse( @@ -220,7 +220,7 @@ public void switchConfiguration( correlationUid, organisationIdentification, deviceIdentification, configurationBank), messageType, messagePriority, - device.getIpAddress()); + device.getNetworkAddress()); } private void replaceEmptyOutputSettings( diff --git a/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/services/DeviceInstallationService.java b/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/services/DeviceInstallationService.java index cd6f0b1ebde..66453a87d41 100644 --- a/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/services/DeviceInstallationService.java +++ b/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/services/DeviceInstallationService.java @@ -67,7 +67,7 @@ public void getStatus( new RequestMessage(correlationUid, organisationIdentification, deviceIdentification, null), actualMessageType, messagePriority, - device.getIpAddress()); + device.getNetworkAddress()); } public void handleGetStatusResponse( @@ -218,7 +218,7 @@ public void startSelfTest( new RequestMessage(correlationUid, organisationIdentification, deviceIdentification, null), messageType, messagePriority, - device.getIpAddress()); + device.getNetworkAddress()); } // === STOP DEVICE TEST === @@ -243,6 +243,6 @@ public void stopSelfTest( new RequestMessage(correlationUid, organisationIdentification, deviceIdentification, null), messageType, messagePriority, - device.getIpAddress()); + device.getNetworkAddress()); } } diff --git a/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/services/DeviceManagementService.java b/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/services/DeviceManagementService.java index 22bc89ca411..9fe9b256f62 100644 --- a/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/services/DeviceManagementService.java +++ b/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/services/DeviceManagementService.java @@ -63,7 +63,7 @@ public void setEventNotifications( eventNotificationMessageDataContainer), messageType, messagePriority, - device.getIpAddress()); + device.getNetworkAddress()); } @Transactional(value = "transactionManager") @@ -97,7 +97,7 @@ public void updateDeviceSslCertification( correlationUid, organisationIdentification, deviceIdentification, certificationDto), messageType, messagePriority, - device.getIpAddress()); + device.getNetworkAddress()); } @Transactional(value = "transactionManager") @@ -127,7 +127,7 @@ public void setDeviceVerificationKey( correlationUid, organisationIdentification, deviceIdentification, verificationKey), messageType, messagePriority, - device.getIpAddress()); + device.getNetworkAddress()); } public void setDeviceLifecycleStatus( diff --git a/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/services/FirmwareManagementService.java b/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/services/FirmwareManagementService.java index 7afef816ae3..4d65d74042f 100644 --- a/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/services/FirmwareManagementService.java +++ b/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/services/FirmwareManagementService.java @@ -5,10 +5,10 @@ package org.opensmartgridplatform.adapter.domain.core.application.services; import java.io.Serializable; +import java.time.Instant; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; -import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -117,7 +117,7 @@ public void updateFirmware( .class)), messageType, messagePriority, - device.getIpAddress(), + device.getNetworkAddress(), scheduleTime); } @@ -292,7 +292,7 @@ public void getFirmwareVersion( new RequestMessage(correlationUid, organisationIdentification, deviceIdentification, null), messageType, messagePriority, - device.getIpAddress(), + device.getNetworkAddress(), delay); } @@ -470,7 +470,7 @@ private List checkFirmwareHistoryForModuleVersionsNotCurrentlyI for (final DeviceFirmwareFile firmwareFile : deviceFirmwareFiles) { final Map fwms = firmwareFile.getFirmwareFile().getModuleVersions(); - final Date installationDate = firmwareFile.getInstallationDate(); + final Instant installationDate = firmwareFile.getInstallationDate(); for (final Map.Entry entry : fwms.entrySet()) { final String version = entry.getValue(); @@ -481,7 +481,7 @@ private List checkFirmwareHistoryForModuleVersionsNotCurrentlyI && currentlyInstalledFirmwareVersionsPerType .get(fwm.getDescription()) .getInstallationDate() - .before(installationDate)) { + .isBefore(installationDate)) { currentlyInstalledFirmwareVersionsPerType.replace( fwm.getDescription(), new FirmwareVersionWithInstallationDate( @@ -518,16 +518,16 @@ private List checkFirmwareHistoryForModuleVersionsNotCurrentlyI // Helper class to keep track of InstallationDate and FirmwareVersion private static class FirmwareVersionWithInstallationDate { - private final Date installationDate; + private final Instant installationDate; private final FirmwareVersion firmwareVersion; public FirmwareVersionWithInstallationDate( - final Date installationDate, final FirmwareVersion firmwareVersion) { + final Instant installationDate, final FirmwareVersion firmwareVersion) { this.installationDate = installationDate; this.firmwareVersion = firmwareVersion; } - public Date getInstallationDate() { + public Instant getInstallationDate() { return this.installationDate; } @@ -558,7 +558,7 @@ public void tryToAddDeviceFirmwareFile( if (firmwareFileContainsAllOfTheseModules(file, firmwareVersionsNotCurrent)) { // file found, insert a record into the history final DeviceFirmwareFile deviceFirmwareFile = - new DeviceFirmwareFile(device, file, new Date(), INSTALLER); + new DeviceFirmwareFile(device, file, Instant.now(), INSTALLER); this.deviceFirmwareFileRepository.save(deviceFirmwareFile); if (LOGGER.isInfoEnabled()) { @@ -659,6 +659,6 @@ public void switchFirmware( correlationUid, organisationIdentification, deviceIdentification, version), messageType, messagePriority, - device.getIpAddress()); + device.getNetworkAddress()); } } diff --git a/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/services/TransactionalDeviceLogItemService.java b/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/services/TransactionalDeviceLogItemService.java index 0024bbd8c9d..7d77bb04b3f 100644 --- a/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/services/TransactionalDeviceLogItemService.java +++ b/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/services/TransactionalDeviceLogItemService.java @@ -4,7 +4,7 @@ package org.opensmartgridplatform.adapter.domain.core.application.services; -import java.util.Date; +import java.time.Instant; import java.util.List; import java.util.stream.Collectors; import org.opensmartgridplatform.adapter.domain.core.application.config.PersistenceDomainLoggingConfig; @@ -31,7 +31,7 @@ public class TransactionalDeviceLogItemService { @Autowired private DeviceLogItemSlicingRepository deviceLogItemSlicingRepository; - public List findDeviceLogItemsBeforeDate(final Date date, final int pageSize) { + public List findDeviceLogItemsBeforeDate(final Instant date, final int pageSize) { final PageRequest pageRequest = PageRequest.of(0, pageSize, Sort.Direction.ASC, "id"); final Slice slice = this.deviceLogItemSlicingRepository.findByModificationTimeBefore(date, pageRequest); diff --git a/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/services/TransactionalEventService.java b/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/services/TransactionalEventService.java index 074c8d28e16..5c50d0d3fbb 100644 --- a/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/services/TransactionalEventService.java +++ b/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/services/TransactionalEventService.java @@ -4,7 +4,7 @@ package org.opensmartgridplatform.adapter.domain.core.application.services; -import java.util.Date; +import java.time.Instant; import java.util.List; import java.util.stream.Collectors; import org.opensmartgridplatform.adapter.domain.core.application.config.PersistenceDomainCoreConfig; @@ -30,7 +30,7 @@ public class TransactionalEventService { @Autowired private EventRepository eventRepository; - public List getEventsBeforeDate(final Date date, final int pageSize) { + public List getEventsBeforeDate(final Instant date, final int pageSize) { final PageRequest pageRequest = PageRequest.of(0, pageSize, Sort.Direction.ASC, "id"); final Slice slice = this.eventRepository.findByDateTimeBefore(date, pageRequest); final List events = slice.getContent(); diff --git a/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/tasks/DeviceMessageCleanupJob.java b/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/tasks/DeviceMessageCleanupJob.java index 1789ec986d6..074ae7a7eef 100644 --- a/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/tasks/DeviceMessageCleanupJob.java +++ b/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/tasks/DeviceMessageCleanupJob.java @@ -5,13 +5,17 @@ package org.opensmartgridplatform.adapter.domain.core.application.tasks; import java.io.IOException; +import java.time.Instant; +import java.time.Period; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; -import java.util.Date; import java.util.List; -import org.joda.time.DateTime; import org.opensmartgridplatform.adapter.domain.core.application.services.TransactionalDeviceLogItemService; import org.opensmartgridplatform.logging.domain.entities.DeviceLogItem; import org.opensmartgridplatform.shared.utils.FileZipper; +import org.opensmartgridplatform.shared.utils.JavaTimeHelpers; import org.opensmartgridplatform.shared.utils.csv.CsvWriter; import org.quartz.DisallowConcurrentExecution; import org.quartz.Job; @@ -61,13 +65,13 @@ public void execute(final JobExecutionContext context) { } LOGGER.info("Quartz triggered cleanup of database - device message records."); - final DateTime start = DateTime.now(); + final ZonedDateTime start = ZonedDateTime.now(); try { - final Date retention = this.calculateRetentionDate(); + final ZonedDateTime retention = this.calculateRetentionDate(); final List oldDeviceMessages = this.transactionalDeviceLogItemService.findDeviceLogItemsBeforeDate( - retention, this.deviceMessagePageSize); + retention.toInstant(), this.deviceMessagePageSize); if (!oldDeviceMessages.isEmpty()) { this.saveDeviceMessagesToCsvFile(oldDeviceMessages); @@ -79,17 +83,17 @@ public void execute(final JobExecutionContext context) { "Exception during CSV file creation, compression or device message deletion.", e); } - final DateTime end = DateTime.now(); + final ZonedDateTime end = ZonedDateTime.now(); LOGGER.info( "Start: {}, end: {}, duration: {} milliseconds.", start, end, - end.getMillis() - start.getMillis()); + JavaTimeHelpers.getMillisFrom(end) - JavaTimeHelpers.getMillisFrom(start)); } - private Date calculateRetentionDate() { - final Date date = - DateTime.now().minusMonths(this.deviceMessageRetentionPeriodInMonths).toDate(); + private ZonedDateTime calculateRetentionDate() { + final ZonedDateTime date = + ZonedDateTime.now().minus(Period.ofMonths(this.deviceMessageRetentionPeriodInMonths)); LOGGER.info( "Determined date: {} based on device message retention period in months: {}.", date, @@ -119,6 +123,9 @@ private static final class DeviceMessageToStringArrayConverter { private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss"; + public static final DateTimeFormatter FORMATTER = + DateTimeFormatter.ofPattern(DATE_TIME_FORMAT).withZone(ZoneId.systemDefault()); + private static final int ID = 0; private static final int CREATION_TIME = 1; private static final int MODIFICATION_TIME = 2; @@ -185,8 +192,8 @@ private static String[] deviceMessageToStringArray(final DeviceLogItem deviceMes return array; } - private static String formatDate(final Date date) { - return new DateTime(date).toString(DATE_TIME_FORMAT); + private static String formatDate(final Instant date) { + return JavaTimeHelpers.formatDate(date, FORMATTER); } } } diff --git a/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/tasks/EventCleanupJob.java b/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/tasks/EventCleanupJob.java index bd1ab7e2ea9..35c108643de 100644 --- a/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/tasks/EventCleanupJob.java +++ b/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/application/tasks/EventCleanupJob.java @@ -5,13 +5,16 @@ package org.opensmartgridplatform.adapter.domain.core.application.tasks; import java.io.IOException; +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; -import java.util.Date; import java.util.List; -import org.joda.time.DateTime; import org.opensmartgridplatform.adapter.domain.core.application.services.TransactionalEventService; import org.opensmartgridplatform.domain.core.entities.Event; import org.opensmartgridplatform.shared.utils.FileZipper; +import org.opensmartgridplatform.shared.utils.JavaTimeHelpers; import org.opensmartgridplatform.shared.utils.csv.CsvWriter; import org.quartz.DisallowConcurrentExecution; import org.quartz.Job; @@ -60,12 +63,13 @@ public void execute(final JobExecutionContext context) { } LOGGER.info("Quartz triggered cleanup of database - event records."); - final DateTime start = DateTime.now(); + final ZonedDateTime start = ZonedDateTime.now(); try { - final Date retention = this.calculateRetentionDate(); + final ZonedDateTime retention = this.calculateRetentionDate(); final List oldEvents = - this.transactionalEventService.getEventsBeforeDate(retention, this.eventPageSize); + this.transactionalEventService.getEventsBeforeDate( + retention.toInstant(), this.eventPageSize); if (!oldEvents.isEmpty()) { this.saveEventsToCsvFile(oldEvents); @@ -76,16 +80,16 @@ public void execute(final JobExecutionContext context) { LOGGER.error("Exception during CSV file creation, compression or event deletion.", e); } - final DateTime end = DateTime.now(); + final ZonedDateTime end = ZonedDateTime.now(); LOGGER.info( "Start: {}, end: {}, duration: {} milliseconds.", start, end, - end.getMillis() - start.getMillis()); + JavaTimeHelpers.getMillisFrom(end) - JavaTimeHelpers.getMillisFrom(start)); } - private Date calculateRetentionDate() { - final Date date = DateTime.now().minusMonths(this.eventRetentionPeriodInMonths).toDate(); + private ZonedDateTime calculateRetentionDate() { + final ZonedDateTime date = ZonedDateTime.now().minusMonths(this.eventRetentionPeriodInMonths); LOGGER.info( "Determined date: {} based on event retention period in months: {}.", date, @@ -113,6 +117,9 @@ private static final class EventToStringArrayConverter { private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss"; + public static final DateTimeFormatter FORMATTER = + DateTimeFormatter.ofPattern(DATE_TIME_FORMAT).withZone(ZoneId.systemDefault()); + private static final int ID = 0; private static final int CREATION_TIME = 1; private static final int MODIFICATION_TIME = 2; @@ -170,8 +177,8 @@ private static String[] eventToStringArray(final Event event) { return array; } - private static String formatDate(final Date date) { - return new DateTime(date).toString(DATE_TIME_FORMAT); + private static String formatDate(final Instant date) { + return JavaTimeHelpers.formatDate(date, FORMATTER); } } } diff --git a/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/infra/jms/core/OsgpCoreRequestMessageSender.java b/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/infra/jms/core/OsgpCoreRequestMessageSender.java index 3da2a83b6e7..2352aef8f2f 100644 --- a/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/infra/jms/core/OsgpCoreRequestMessageSender.java +++ b/osgp/platform/osgp-adapter-domain-core/src/main/java/org/opensmartgridplatform/adapter/domain/core/infra/jms/core/OsgpCoreRequestMessageSender.java @@ -78,7 +78,7 @@ public Message createMessage(final Session session) throws JMSException { objectMessage.setStringProperty( Constants.ORGANISATION_IDENTIFICATION, organisationIdentification); objectMessage.setStringProperty(Constants.DEVICE_IDENTIFICATION, deviceIdentification); - objectMessage.setStringProperty(Constants.IP_ADDRESS, ipAddress); + objectMessage.setStringProperty(Constants.NETWORK_ADDRESS, ipAddress); if (scheduledTime != null) { objectMessage.setLongProperty(Constants.SCHEDULE_TIME, scheduledTime); } diff --git a/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/mapping/DomainCoreMapperTest.java b/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/mapping/DomainCoreMapperTest.java index c7d55a21e31..81133dd75ac 100644 --- a/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/mapping/DomainCoreMapperTest.java +++ b/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/mapping/DomainCoreMapperTest.java @@ -8,12 +8,14 @@ import static java.util.stream.Collectors.toList; import static org.assertj.core.api.Assertions.assertThat; +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import org.assertj.core.api.Assertions; -import org.joda.time.DateTime; import org.junit.jupiter.api.Test; import org.opensmartgridplatform.domain.core.valueobjects.Configuration; import org.opensmartgridplatform.domain.core.valueobjects.DaliConfiguration; @@ -125,8 +127,12 @@ private ConfigurationDto aConfigurationDto() { source.setSwitchingDelays(asList(142, 143)); source.setRelayLinking(asList(new RelayMatrixDto(144, true), new RelayMatrixDto(145, false))); source.setRelayRefreshing(true); - source.setSummerTimeDetails(new DateTime(146L * 24 * 60 * 60 * 1000)); - source.setWinterTimeDetails(new DateTime(147L * 24 * 60 * 60 * 1000)); + source.setSummerTimeDetails( + ZonedDateTime.ofInstant( + Instant.ofEpochMilli(146L * 24 * 60 * 60 * 1000), ZoneId.systemDefault())); + source.setWinterTimeDetails( + ZonedDateTime.ofInstant( + Instant.ofEpochMilli(147L * 24 * 60 * 60 * 1000), ZoneId.systemDefault())); return source; } diff --git a/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/services/AdHocManagementServiceTest.java b/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/services/AdHocManagementServiceTest.java index b66087e0564..0e5cb26c44e 100644 --- a/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/services/AdHocManagementServiceTest.java +++ b/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/services/AdHocManagementServiceTest.java @@ -51,7 +51,7 @@ public class AdHocManagementServiceTest { @BeforeEach public void setup() throws Exception { - when(this.device.getIpAddress()).thenReturn("127.0.0.1"); + when(this.device.getNetworkAddress()).thenReturn("127.0.0.1"); when(this.deviceDomainService.searchActiveDevice(any(String.class), any(ComponentType.class))) .thenReturn(this.device); } diff --git a/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/services/ConfigurationManagementServiceTest.java b/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/services/ConfigurationManagementServiceTest.java index fc9a444a990..edb6017b326 100644 --- a/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/services/ConfigurationManagementServiceTest.java +++ b/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/services/ConfigurationManagementServiceTest.java @@ -100,7 +100,7 @@ void testTrySetConfiguration() throws FunctionalException, UnknownEntityExceptio when(this.ssldRepository.findById(any())).thenReturn(java.util.Optional.of(this.ssld)); when(this.domainCoreMapper.map(any(), any())).thenReturn(this.configurationDto); doNothing().when(this.ssld).updateOutputSettings(any()); - when(this.device.getIpAddress()).thenReturn(IP_ADDRESS); + when(this.device.getNetworkAddress()).thenReturn(IP_ADDRESS); this.configurationManagementService.setConfiguration( this.correlationIds, this.configuration, SCHEDULE_TIME, MESSAGE_TYPE, MESSAGE_PRIORITY); @@ -159,7 +159,7 @@ void testGetConfiguration() throws UnknownEntityException, FunctionalException { when(this.organisationDomainService.searchOrganisation(any(String.class))) .thenReturn(new Organisation()); when(this.deviceDomainService.searchActiveDevice(any(), any())).thenReturn(this.device); - when(this.device.getIpAddress()).thenReturn(IP_ADDRESS); + when(this.device.getNetworkAddress()).thenReturn(IP_ADDRESS); this.configurationManagementService.getConfiguration( ORG_IDENTIFICATION, DEVICE_IDENTIFICATION, CORRELATION_UID, MESSAGE_TYPE, MESSAGE_PRIORITY); @@ -224,7 +224,7 @@ void testswitchConfiguration() throws UnknownEntityException, FunctionalExceptio when(this.organisationDomainService.searchOrganisation(any(String.class))) .thenReturn(new Organisation()); when(this.deviceDomainService.searchActiveDevice(any(), any())).thenReturn(this.device); - when(this.device.getIpAddress()).thenReturn(IP_ADDRESS); + when(this.device.getNetworkAddress()).thenReturn(IP_ADDRESS); this.configurationManagementService.switchConfiguration( ORG_IDENTIFICATION, diff --git a/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/services/DeviceInstallationServiceTest.java b/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/services/DeviceInstallationServiceTest.java index 5bdfd4a38f6..f82311aee63 100644 --- a/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/services/DeviceInstallationServiceTest.java +++ b/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/services/DeviceInstallationServiceTest.java @@ -89,7 +89,7 @@ public class DeviceInstallationServiceTest { @Test public void testGetStatusTestDeviceTypeIsNotLmdType() throws FunctionalException { final Device device = Mockito.mock(Device.class); - when(device.getIpAddress()).thenReturn(TEST_IP); + when(device.getNetworkAddress()).thenReturn(TEST_IP); when(this.deviceDomainService.searchActiveDevice(TEST_DEVICE, ComponentType.DOMAIN_CORE)) .thenReturn(device); @@ -115,7 +115,7 @@ public void testGetStatusTestDeviceTypeIsNotLmdType() throws FunctionalException public void testGetStatusTestDeviceTypeIsLmdType() throws FunctionalException { final Device device = Mockito.mock(Device.class); when(device.getDeviceType()).thenReturn("LMD"); - when(device.getIpAddress()).thenReturn(TEST_IP); + when(device.getNetworkAddress()).thenReturn(TEST_IP); when(this.deviceDomainService.searchActiveDevice(TEST_DEVICE, ComponentType.DOMAIN_CORE)) .thenReturn(device); @@ -281,7 +281,7 @@ public void testHandleGetStatusResponseOkNotLMDStatusNull() throws FunctionalExc @Test public void testStartSelfTest() throws FunctionalException { final Device device = Mockito.mock(Device.class); - when(device.getIpAddress()).thenReturn(TEST_IP); + when(device.getNetworkAddress()).thenReturn(TEST_IP); when(this.deviceDomainService.searchActiveDevice(TEST_DEVICE, ComponentType.DOMAIN_CORE)) .thenReturn(device); @@ -306,7 +306,7 @@ public void testStartSelfTest() throws FunctionalException { @Test public void testStopSelfTest() throws FunctionalException { final Device device = Mockito.mock(Device.class); - when(device.getIpAddress()).thenReturn(TEST_IP); + when(device.getNetworkAddress()).thenReturn(TEST_IP); when(this.deviceDomainService.searchActiveDevice(TEST_DEVICE, ComponentType.DOMAIN_CORE)) .thenReturn(device); diff --git a/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/services/DeviceManagementServiceTest.java b/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/services/DeviceManagementServiceTest.java index 52b4b6ad3e4..6db22c3aede 100644 --- a/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/services/DeviceManagementServiceTest.java +++ b/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/services/DeviceManagementServiceTest.java @@ -90,7 +90,7 @@ public void testSetEventNotifications() throws FunctionalException { final List eventNotifications = Arrays.asList(EventNotificationType.COMM_EVENTS, EventNotificationType.DIAG_EVENTS); final Device device = mock(Device.class); - when(device.getIpAddress()).thenReturn(TEST_IP); + when(device.getNetworkAddress()).thenReturn(TEST_IP); when(this.deviceDomainService.searchActiveDevice(TEST_DEVICE, ComponentType.DOMAIN_CORE)) .thenReturn(device); @@ -136,7 +136,7 @@ public void testUpdateDeviceSslCertificationIsNull() throws FunctionalException @Test public void testUpdateDeviceSslCertification() throws FunctionalException { final Device device = mock(Device.class); - when(device.getIpAddress()).thenReturn(TEST_IP); + when(device.getNetworkAddress()).thenReturn(TEST_IP); when(this.deviceDomainService.searchActiveDevice(TEST_DEVICE, ComponentType.DOMAIN_CORE)) .thenReturn(device); final Certification certification = new Certification("testUrl", "testDomain"); @@ -176,7 +176,7 @@ public void testSetDeviceVerificationKeyIsNull() throws FunctionalException { @Test public void testSetDeviceVerificationKey() throws FunctionalException { final Device device = mock(Device.class); - when(device.getIpAddress()).thenReturn(TEST_IP); + when(device.getNetworkAddress()).thenReturn(TEST_IP); when(this.deviceDomainService.searchActiveDevice(TEST_DEVICE, ComponentType.DOMAIN_CORE)) .thenReturn(device); this.deviceManagementService.setDeviceVerificationKey( diff --git a/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/services/FirmwareManagementServiceTest.java b/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/services/FirmwareManagementServiceTest.java index 1f9404642ba..20d5064fadf 100644 --- a/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/services/FirmwareManagementServiceTest.java +++ b/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/services/FirmwareManagementServiceTest.java @@ -18,13 +18,13 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; +import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.Date; import java.util.HashMap; import java.util.List; -import org.apache.commons.lang3.time.DateUtils; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -137,10 +137,16 @@ void setUp() { when(this.deviceRepository.findByDeviceIdentification(anyString())).thenReturn(device); final DeviceFirmwareFile deviceFirmwareFile1 = new DeviceFirmwareFile( - device, this.createFirmwareFile(VERSION_1), DateUtils.addDays(new Date(), -2), "me"); + device, + this.createFirmwareFile(VERSION_1), + Instant.now().minus(2, ChronoUnit.DAYS), + "me"); final DeviceFirmwareFile deviceFirmwareFile2 = new DeviceFirmwareFile( - device, this.createFirmwareFile(VERSION_2), DateUtils.addDays(new Date(), -1), "me"); + device, + this.createFirmwareFile(VERSION_2), + Instant.now().minus(1, ChronoUnit.DAYS), + "me"); final List deviceFirmwareFiles = Arrays.asList(deviceFirmwareFile1, deviceFirmwareFile2); when(this.deviceFirmwareFileRepository.findByDeviceOrderByInstallationDateAsc( @@ -447,7 +453,7 @@ void handlesOneSsldPendingFirmwareUpdateRetrievingFirmwareVersion() throws Excep final Ssld ssld = new Ssld(deviceIdentification); final String correlationUid = "correlation-uid-pending-firmware-update"; final SsldPendingFirmwareUpdate ssldPendingFirmwareUpdate = - this.anSsldPendingFirmwareUpdate(1L, new Date(), deviceIdentification, correlationUid); + this.anSsldPendingFirmwareUpdate(1L, Instant.now(), deviceIdentification, correlationUid); final Organisation organisation = new Organisation( ssldPendingFirmwareUpdate.getOrganisationIdentification(), @@ -488,25 +494,25 @@ void handlesMultipleSsldPendingFirmwareUpdatesWithoutFailure() throws Exception final SsldPendingFirmwareUpdate olderPendingFirmwareUpdate1 = this.anSsldPendingFirmwareUpdate( 134562345L, - new Date(mostRecentCreationMillis - 3_000_000_000L), + Instant.ofEpochMilli(mostRecentCreationMillis).minus(3_000_000_000L, ChronoUnit.MILLIS), deviceIdentification, "correlation-uid-1"); final SsldPendingFirmwareUpdate olderPendingFirmwareUpdate2 = this.anSsldPendingFirmwareUpdate( 227587L, - new Date(mostRecentCreationMillis - 604_800_000L), + Instant.ofEpochMilli(mostRecentCreationMillis).minus(604_800_000L, ChronoUnit.MILLIS), deviceIdentification, "correlation-uid-2"); final SsldPendingFirmwareUpdate olderPendingFirmwareUpdate3 = this.anSsldPendingFirmwareUpdate( 308943152L, - new Date(mostRecentCreationMillis - 123L), + Instant.ofEpochMilli(mostRecentCreationMillis).minus(123L, ChronoUnit.MILLIS), deviceIdentification, "correlation-uid-3"); final SsldPendingFirmwareUpdate mostRecentPendingFirmwareUpdate = this.anSsldPendingFirmwareUpdate( 4459483L, - new Date(mostRecentCreationMillis), + Instant.ofEpochMilli(mostRecentCreationMillis), deviceIdentification, correlationUidMostRecentPendingFirmwareUpdate); final Organisation organisation = @@ -587,7 +593,7 @@ private void assertFirmwareVersionRequested( private SsldPendingFirmwareUpdate anSsldPendingFirmwareUpdate( final Long id, - final Date creationTime, + final Instant creationTime, final String deviceIdentification, final String correlationUid) { @@ -602,7 +608,7 @@ private SsldPendingFirmwareUpdate anSsldPendingFirmwareUpdate( correlationUid); ReflectionTestUtils.setField(ssldPendingFirmwareUpdate, "id", id, Long.class); ReflectionTestUtils.setField( - ssldPendingFirmwareUpdate, "creationTime", creationTime, Date.class); + ssldPendingFirmwareUpdate, "creationTime", creationTime, Instant.class); return ssldPendingFirmwareUpdate; } @@ -639,7 +645,7 @@ void checkSsldPendingFirmwareUpdateReturnsFalseIfPendingUpdatesAreForDifferentCo .thenReturn( Collections.singletonList( this.anSsldPendingFirmwareUpdate( - 4579L, new Date(), DEVICE_IDENTIFICATION, "some-other-correlation-uid"))); + 4579L, Instant.now(), DEVICE_IDENTIFICATION, "some-other-correlation-uid"))); final boolean hasPendingFirmwareUpdate = this.firmwareManagementService.checkSsldPendingFirmwareUpdate(ids, firmwareVersions); @@ -660,15 +666,19 @@ void checkSsldPendingFirmwareUpdateReturnsFalseIfPendingUpdatesAreForDifferentCo final List firmwareVersions = Collections.singletonList(new FirmwareVersion(FirmwareModuleType.FUNCTIONAL, VERSION_2)); final SsldPendingFirmwareUpdate matchingPendingFirmwareUpdate = - this.anSsldPendingFirmwareUpdate(437L, new Date(), DEVICE_IDENTIFICATION, correlationUid); + this.anSsldPendingFirmwareUpdate( + 437L, Instant.now(), DEVICE_IDENTIFICATION, correlationUid); when(this.ssldPendingFirmwareUpdateRepository.findByDeviceIdentification(DEVICE_IDENTIFICATION)) .thenReturn( Arrays.asList( this.anSsldPendingFirmwareUpdate( - 457198L, new Date(), DEVICE_IDENTIFICATION, "some-other-correlation-uid"), + 457198L, Instant.now(), DEVICE_IDENTIFICATION, "some-other-correlation-uid"), matchingPendingFirmwareUpdate, this.anSsldPendingFirmwareUpdate( - 94085089L, new Date(), DEVICE_IDENTIFICATION, "yet-another-correlation-uid"))); + 94085089L, + Instant.now(), + DEVICE_IDENTIFICATION, + "yet-another-correlation-uid"))); final boolean hasPendingFirmwareUpdate = this.firmwareManagementService.checkSsldPendingFirmwareUpdate(ids, firmwareVersions); @@ -683,7 +693,7 @@ void checkSsldPendingFirmwareUpdateReturnsFalseIfPendingUpdatesAreForDifferentCo */ private Device getMockDevice(final Class deviceClass) { final Device device = (Device) Mockito.mock(deviceClass); - when(device.getIpAddress()).thenReturn("0.0.0.0"); + when(device.getNetworkAddress()).thenReturn("0.0.0.0"); return device; } diff --git a/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/services/TransactionalDeviceLogItemServiceTest.java b/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/services/TransactionalDeviceLogItemServiceTest.java index 2ebf58d9218..aed2e27a3b0 100644 --- a/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/services/TransactionalDeviceLogItemServiceTest.java +++ b/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/services/TransactionalDeviceLogItemServiceTest.java @@ -7,10 +7,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.fail; +import java.time.Instant; import java.util.ArrayList; -import java.util.Date; import java.util.List; -import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; @@ -26,7 +25,7 @@ public class TransactionalDeviceLogItemServiceTest { - private final Date now = DateTime.now().toDate(); + private final Instant now = Instant.now(); @InjectMocks private TransactionalDeviceLogItemService transactionalDeviceLogItemService; diff --git a/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/services/TransactionalEventServiceTest.java b/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/services/TransactionalEventServiceTest.java index 860bd8b705b..6beb15907d8 100644 --- a/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/services/TransactionalEventServiceTest.java +++ b/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/services/TransactionalEventServiceTest.java @@ -7,10 +7,10 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.fail; +import java.time.Instant; +import java.time.ZonedDateTime; import java.util.ArrayList; -import java.util.Date; import java.util.List; -import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; @@ -27,7 +27,7 @@ public class TransactionalEventServiceTest { - private final Date now = DateTime.now().toDate(); + private final Instant now = Instant.now(); @InjectMocks private TransactionalEventService transactionalEventService; @@ -72,7 +72,7 @@ public void serviceDeletesEvents() { } private Slice mockSliceOfEvents(final int numberOfEvents) { - final Date oneMonthAgo = DateTime.now().minusMonths(1).toDate(); + final Instant oneMonthAgo = ZonedDateTime.now().minusMonths(1).toInstant(); final List events = new ArrayList<>(); for (int i = 0; i < numberOfEvents; i++) { diff --git a/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/tasks/DeviceMessageCleanupJobTest.java b/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/tasks/DeviceMessageCleanupJobTest.java index 0c6ed5ea834..2cede8f5579 100644 --- a/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/tasks/DeviceMessageCleanupJobTest.java +++ b/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/tasks/DeviceMessageCleanupJobTest.java @@ -10,8 +10,8 @@ import java.io.File; import java.io.IOException; import java.nio.file.Path; +import java.time.Instant; import java.util.Arrays; -import java.util.Date; import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -58,7 +58,7 @@ public void test() throws IOException { final List deviceLogItems = this.createDeviceLogItems(); Mockito.when( this.transactionalDeviceLogItemService.findDeviceLogItemsBeforeDate( - any(Date.class), any(Integer.class))) + any(Instant.class), any(Integer.class))) .thenReturn(deviceLogItems); // Act diff --git a/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/tasks/EventCleanupJobTest.java b/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/tasks/EventCleanupJobTest.java index 0814d8bdf14..baf8091a38b 100644 --- a/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/tasks/EventCleanupJobTest.java +++ b/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/application/tasks/EventCleanupJobTest.java @@ -10,10 +10,10 @@ import java.io.File; import java.io.IOException; import java.nio.file.Path; +import java.time.Instant; +import java.time.ZonedDateTime; import java.util.Arrays; -import java.util.Date; import java.util.List; -import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; @@ -59,7 +59,8 @@ public void test() throws IOException { // Arrange final List events = this.createEvents(); Mockito.when( - this.transactionalEventService.getEventsBeforeDate(any(Date.class), any(Integer.class))) + this.transactionalEventService.getEventsBeforeDate( + any(Instant.class), any(Integer.class))) .thenReturn(events); // Act @@ -92,7 +93,7 @@ private List createEvents() { final Event event = new Event( "test", - DateTime.now().minusMonths(1).toDate(), + ZonedDateTime.now().minusMonths(1).toInstant(), EventType.DIAG_EVENTS_GENERAL, "description", 1); diff --git a/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/infra/jms/core/OsgpCoreRequestMessageSenderTest.java b/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/infra/jms/core/OsgpCoreRequestMessageSenderTest.java index 9632cf30787..8fcb3abc263 100644 --- a/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/infra/jms/core/OsgpCoreRequestMessageSenderTest.java +++ b/osgp/platform/osgp-adapter-domain-core/src/test/java/org/opensmartgridplatform/adapter/domain/core/infra/jms/core/OsgpCoreRequestMessageSenderTest.java @@ -76,7 +76,7 @@ void testSend() throws JMSException { .setStringProperty(Constants.ORGANISATION_IDENTIFICATION, organisationIdentification); verify(this.objectMessage) .setStringProperty(Constants.DEVICE_IDENTIFICATION, deviceIdentification); - verify(this.objectMessage).setStringProperty(Constants.IP_ADDRESS, ipAddress); + verify(this.objectMessage).setStringProperty(Constants.NETWORK_ADDRESS, ipAddress); verify(this.objectMessage).setObject(requestMessage.getRequest()); } } diff --git a/osgp/platform/osgp-adapter-domain-distributionautomation/pom.xml b/osgp/platform/osgp-adapter-domain-distributionautomation/pom.xml index 814994e4b81..2a80f286546 100644 --- a/osgp/platform/osgp-adapter-domain-distributionautomation/pom.xml +++ b/osgp/platform/osgp-adapter-domain-distributionautomation/pom.xml @@ -12,7 +12,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-platform - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-platform/pom.xml diff --git a/osgp/platform/osgp-adapter-domain-distributionautomation/src/main/java/org/opensmartgridplatform/adapter/domain/da/application/services/AdHocManagementService.java b/osgp/platform/osgp-adapter-domain-distributionautomation/src/main/java/org/opensmartgridplatform/adapter/domain/da/application/services/AdHocManagementService.java index dff83307d38..b3b69d16870 100644 --- a/osgp/platform/osgp-adapter-domain-distributionautomation/src/main/java/org/opensmartgridplatform/adapter/domain/da/application/services/AdHocManagementService.java +++ b/osgp/platform/osgp-adapter-domain-distributionautomation/src/main/java/org/opensmartgridplatform/adapter/domain/da/application/services/AdHocManagementService.java @@ -58,7 +58,7 @@ public void getDeviceModel( this.osgpCoreRequestMessageSender.send( new RequestMessage(correlationUid, organisationIdentification, deviceIdentification, dto), messageType, - device.getIpAddress()); + device.getNetworkAddress()); } public void handleGetDeviceModelResponse( diff --git a/osgp/platform/osgp-adapter-domain-distributionautomation/src/main/java/org/opensmartgridplatform/adapter/domain/da/application/services/CommunicationRecoveryService.java b/osgp/platform/osgp-adapter-domain-distributionautomation/src/main/java/org/opensmartgridplatform/adapter/domain/da/application/services/CommunicationRecoveryService.java index 12ac7b75175..6d2b3eb7fe8 100644 --- a/osgp/platform/osgp-adapter-domain-distributionautomation/src/main/java/org/opensmartgridplatform/adapter/domain/da/application/services/CommunicationRecoveryService.java +++ b/osgp/platform/osgp-adapter-domain-distributionautomation/src/main/java/org/opensmartgridplatform/adapter/domain/da/application/services/CommunicationRecoveryService.java @@ -64,7 +64,7 @@ public void restoreCommunication(final RtuDevice rtu) { final RequestMessage message = this.createMessage(rtu); this.osgpCoreRequestMessageSender.send( - message, DeviceFunction.GET_DATA.toString(), rtu.getIpAddress()); + message, DeviceFunction.GET_DATA.toString(), rtu.getNetworkAddress()); } private RequestMessage createMessage(final RtuDevice rtu) { diff --git a/osgp/platform/osgp-adapter-domain-distributionautomation/src/main/java/org/opensmartgridplatform/adapter/domain/da/application/services/DeviceManagementService.java b/osgp/platform/osgp-adapter-domain-distributionautomation/src/main/java/org/opensmartgridplatform/adapter/domain/da/application/services/DeviceManagementService.java index 16fbe1d0b26..17632759036 100644 --- a/osgp/platform/osgp-adapter-domain-distributionautomation/src/main/java/org/opensmartgridplatform/adapter/domain/da/application/services/DeviceManagementService.java +++ b/osgp/platform/osgp-adapter-domain-distributionautomation/src/main/java/org/opensmartgridplatform/adapter/domain/da/application/services/DeviceManagementService.java @@ -60,7 +60,7 @@ public void getHealthStatus( this.osgpCoreRequestMessageSender.send( new RequestMessage(correlationUid, organisationIdentification, deviceIdentification, dto), messageType, - device.getIpAddress()); + device.getNetworkAddress()); } public void handleInternalHealthStatusResponse( diff --git a/osgp/platform/osgp-adapter-domain-distributionautomation/src/main/java/org/opensmartgridplatform/adapter/domain/da/application/services/MonitoringService.java b/osgp/platform/osgp-adapter-domain-distributionautomation/src/main/java/org/opensmartgridplatform/adapter/domain/da/application/services/MonitoringService.java index e242e2fbfc0..015f45ffa71 100644 --- a/osgp/platform/osgp-adapter-domain-distributionautomation/src/main/java/org/opensmartgridplatform/adapter/domain/da/application/services/MonitoringService.java +++ b/osgp/platform/osgp-adapter-domain-distributionautomation/src/main/java/org/opensmartgridplatform/adapter/domain/da/application/services/MonitoringService.java @@ -57,7 +57,7 @@ public void getPQValues( this.mapper.map(getPQValuesRequest, GetPQValuesRequestDto.class); this.osgpCoreRequestMessageSender.send( - new RequestMessage(ids, dto), messageType, device.getIpAddress()); + new RequestMessage(ids, dto), messageType, device.getNetworkAddress()); } public void getPQValuesPeriodic( @@ -78,7 +78,7 @@ public void getPQValuesPeriodic( this.mapper.map(getPQValuesPeriodicRequest, GetPQValuesPeriodicRequestDto.class); this.osgpCoreRequestMessageSender.send( - new RequestMessage(ids, dto), messageType, device.getIpAddress()); + new RequestMessage(ids, dto), messageType, device.getNetworkAddress()); } public void handleGetPQValuesResponse( diff --git a/osgp/platform/osgp-adapter-domain-distributionautomation/src/main/java/org/opensmartgridplatform/adapter/domain/da/application/services/RtuDeviceService.java b/osgp/platform/osgp-adapter-domain-distributionautomation/src/main/java/org/opensmartgridplatform/adapter/domain/da/application/services/RtuDeviceService.java index b7d6e6c0b83..1db81692b0b 100644 --- a/osgp/platform/osgp-adapter-domain-distributionautomation/src/main/java/org/opensmartgridplatform/adapter/domain/da/application/services/RtuDeviceService.java +++ b/osgp/platform/osgp-adapter-domain-distributionautomation/src/main/java/org/opensmartgridplatform/adapter/domain/da/application/services/RtuDeviceService.java @@ -4,8 +4,6 @@ package org.opensmartgridplatform.adapter.domain.da.application.services; -import java.net.InetAddress; -import java.net.UnknownHostException; import org.opensmartgridplatform.domain.core.entities.DeviceAuthorization; import org.opensmartgridplatform.domain.core.entities.DeviceModel; import org.opensmartgridplatform.domain.core.entities.Manufacturer; @@ -79,22 +77,9 @@ private void throwExceptionOnExistingDevice(final AddRtuDeviceRequest addRtuDevi private void addRegistrationData( final RtuDevice rtuDevice, - final org.opensmartgridplatform.domain.core.entities.RtuDevice rtuDeviceEntity) - throws FunctionalException { + final org.opensmartgridplatform.domain.core.entities.RtuDevice rtuDeviceEntity) { final String networkAddress = rtuDevice.getNetworkAddress(); - final InetAddress inetAddress; - try { - inetAddress = - LOCAL_HOST.equals(networkAddress) - ? InetAddress.getLoopbackAddress() - : InetAddress.getByName(networkAddress); - } catch (final UnknownHostException e) { - throw new FunctionalException( - FunctionalExceptionType.INVALID_IP_ADDRESS, - ComponentType.DOMAIN_DISTRIBUTION_AUTOMATION, - e); - } - rtuDeviceEntity.updateRegistrationData(inetAddress, RtuDevice.PSD_TYPE); + rtuDeviceEntity.updateRegistrationData(networkAddress, RtuDevice.PSD_TYPE); } private void addDeviceModel( diff --git a/osgp/platform/osgp-adapter-domain-distributionautomation/src/main/java/org/opensmartgridplatform/adapter/domain/da/infra/jms/core/OsgpCoreRequestMessageCreator.java b/osgp/platform/osgp-adapter-domain-distributionautomation/src/main/java/org/opensmartgridplatform/adapter/domain/da/infra/jms/core/OsgpCoreRequestMessageCreator.java index 08843ff87e6..97ce0a35e57 100644 --- a/osgp/platform/osgp-adapter-domain-distributionautomation/src/main/java/org/opensmartgridplatform/adapter/domain/da/infra/jms/core/OsgpCoreRequestMessageCreator.java +++ b/osgp/platform/osgp-adapter-domain-distributionautomation/src/main/java/org/opensmartgridplatform/adapter/domain/da/infra/jms/core/OsgpCoreRequestMessageCreator.java @@ -14,10 +14,10 @@ public class OsgpCoreRequestMessageCreator implements MessageCreator { - private RequestMessage requestMessage; - private String messageType; - private String ipAddress; - private Long scheduleTime; + private final RequestMessage requestMessage; + private final String messageType; + private final String ipAddress; + private final Long scheduleTime; public OsgpCoreRequestMessageCreator( final RequestMessage requestMessage, @@ -40,7 +40,7 @@ public Message createMessage(final Session session) throws JMSException { Constants.ORGANISATION_IDENTIFICATION, this.requestMessage.getOrganisationIdentification()); objectMessage.setStringProperty( Constants.DEVICE_IDENTIFICATION, this.requestMessage.getDeviceIdentification()); - objectMessage.setStringProperty(Constants.IP_ADDRESS, this.ipAddress); + objectMessage.setStringProperty(Constants.NETWORK_ADDRESS, this.ipAddress); if (this.scheduleTime != null) { objectMessage.setLongProperty(Constants.SCHEDULE_TIME, this.scheduleTime); } diff --git a/osgp/platform/osgp-adapter-domain-microgrids/pom.xml b/osgp/platform/osgp-adapter-domain-microgrids/pom.xml index 1efa94a5371..13f06585d4e 100644 --- a/osgp/platform/osgp-adapter-domain-microgrids/pom.xml +++ b/osgp/platform/osgp-adapter-domain-microgrids/pom.xml @@ -11,7 +11,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-platform - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-platform/pom.xml diff --git a/osgp/platform/osgp-adapter-domain-microgrids/src/main/java/org/opensmartgridplatform/adapter/domain/microgrids/application/services/AdHocManagementService.java b/osgp/platform/osgp-adapter-domain-microgrids/src/main/java/org/opensmartgridplatform/adapter/domain/microgrids/application/services/AdHocManagementService.java index 09e1c98418b..cbbd4a8ea37 100644 --- a/osgp/platform/osgp-adapter-domain-microgrids/src/main/java/org/opensmartgridplatform/adapter/domain/microgrids/application/services/AdHocManagementService.java +++ b/osgp/platform/osgp-adapter-domain-microgrids/src/main/java/org/opensmartgridplatform/adapter/domain/microgrids/application/services/AdHocManagementService.java @@ -76,7 +76,7 @@ public void getData( this.osgpCoreRequestMessageSender.send( new RequestMessage(correlationUid, organisationIdentification, deviceIdentification, dto), messageType, - device.getIpAddress()); + device.getNetworkAddress()); } public void handleInternalDataResponse( @@ -166,7 +166,7 @@ public void handleSetDataRequest( this.osgpCoreRequestMessageSender.send( new RequestMessage(correlationUid, organisationIdentification, deviceIdentification, dto), messageType, - device.getIpAddress()); + device.getNetworkAddress()); } public void handleSetDataResponse( diff --git a/osgp/platform/osgp-adapter-domain-microgrids/src/main/java/org/opensmartgridplatform/adapter/domain/microgrids/application/services/CommunicationRecoveryService.java b/osgp/platform/osgp-adapter-domain-microgrids/src/main/java/org/opensmartgridplatform/adapter/domain/microgrids/application/services/CommunicationRecoveryService.java index 0efba6c352f..c0fe29056a4 100644 --- a/osgp/platform/osgp-adapter-domain-microgrids/src/main/java/org/opensmartgridplatform/adapter/domain/microgrids/application/services/CommunicationRecoveryService.java +++ b/osgp/platform/osgp-adapter-domain-microgrids/src/main/java/org/opensmartgridplatform/adapter/domain/microgrids/application/services/CommunicationRecoveryService.java @@ -90,7 +90,7 @@ public void restoreCommunication(final RtuDevice rtu) { final RequestMessage message = this.createMessage(rtu); this.osgpCoreRequestMessageSender.send( - message, DeviceFunction.GET_DATA.toString(), rtu.getIpAddress()); + message, DeviceFunction.GET_DATA.toString(), rtu.getNetworkAddress()); } private RequestMessage createMessage(final RtuDevice rtu) { diff --git a/osgp/platform/osgp-adapter-domain-microgrids/src/main/java/org/opensmartgridplatform/adapter/domain/microgrids/infra/jms/core/OsgpCoreRequestMessageCreator.java b/osgp/platform/osgp-adapter-domain-microgrids/src/main/java/org/opensmartgridplatform/adapter/domain/microgrids/infra/jms/core/OsgpCoreRequestMessageCreator.java index 5c3ae57bb04..cf75f80c4b5 100644 --- a/osgp/platform/osgp-adapter-domain-microgrids/src/main/java/org/opensmartgridplatform/adapter/domain/microgrids/infra/jms/core/OsgpCoreRequestMessageCreator.java +++ b/osgp/platform/osgp-adapter-domain-microgrids/src/main/java/org/opensmartgridplatform/adapter/domain/microgrids/infra/jms/core/OsgpCoreRequestMessageCreator.java @@ -14,10 +14,10 @@ public class OsgpCoreRequestMessageCreator implements MessageCreator { - private RequestMessage requestMessage; - private String messageType; - private String ipAddress; - private Long scheduleTime; + private final RequestMessage requestMessage; + private final String messageType; + private final String ipAddress; + private final Long scheduleTime; public OsgpCoreRequestMessageCreator( final RequestMessage requestMessage, @@ -40,7 +40,7 @@ public Message createMessage(final Session session) throws JMSException { Constants.ORGANISATION_IDENTIFICATION, this.requestMessage.getOrganisationIdentification()); objectMessage.setStringProperty( Constants.DEVICE_IDENTIFICATION, this.requestMessage.getDeviceIdentification()); - objectMessage.setStringProperty(Constants.IP_ADDRESS, this.ipAddress); + objectMessage.setStringProperty(Constants.NETWORK_ADDRESS, this.ipAddress); if (this.scheduleTime != null) { objectMessage.setLongProperty(Constants.SCHEDULE_TIME, this.scheduleTime); } diff --git a/osgp/platform/osgp-adapter-domain-publiclighting/pom.xml b/osgp/platform/osgp-adapter-domain-publiclighting/pom.xml index 8a636d6a50c..416620695a5 100644 --- a/osgp/platform/osgp-adapter-domain-publiclighting/pom.xml +++ b/osgp/platform/osgp-adapter-domain-publiclighting/pom.xml @@ -17,7 +17,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-platform - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-platform/pom.xml diff --git a/osgp/platform/osgp-adapter-domain-publiclighting/src/main/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/services/AdHocManagementService.java b/osgp/platform/osgp-adapter-domain-publiclighting/src/main/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/services/AdHocManagementService.java index f53b9e0ba1e..227b2e740cf 100644 --- a/osgp/platform/osgp-adapter-domain-publiclighting/src/main/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/services/AdHocManagementService.java +++ b/osgp/platform/osgp-adapter-domain-publiclighting/src/main/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/services/AdHocManagementService.java @@ -5,7 +5,6 @@ package org.opensmartgridplatform.adapter.domain.publiclighting.application.services; import java.time.Instant; -import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -105,7 +104,7 @@ public void setLight( lightValueMessageDataContainer), messageType, messagePriority, - device.getIpAddress()); + device.getNetworkAddress()); } // === GET LIGHT SENSOR STATUS === @@ -222,10 +221,10 @@ public void getStatus( private String getIpAddress(final Device device) { String ipAddress = null; if (device.getGatewayDevice() != null) { - ipAddress = device.getGatewayDevice().getIpAddress(); + ipAddress = device.getGatewayDevice().getNetworkAddress(); } if (ipAddress == null) { - ipAddress = device.getIpAddress(); + ipAddress = device.getNetworkAddress(); } return ipAddress; } @@ -371,7 +370,7 @@ public void resumeSchedule( new RequestMessage(ids, resumeScheduleMessageDataContainerDto), messageType, messagePriority, - device.getIpAddress()); + device.getNetworkAddress()); } // === TRANSITION MESSAGE FROM LIGHT MEASUREMENT DEVICE === @@ -440,7 +439,7 @@ private LightMeasurementDevice updateLmdLastCommunicationTime(final LightMeasure LOGGER.info( "Trying to update lastCommunicationTime for light measurement device: {} at DateTime: {}", lmd.getDeviceIdentification(), - Date.from(now)); + now); lmd.setLastCommunicationTime(now); final Device gateway = lmd.getGatewayDevice(); @@ -543,7 +542,7 @@ private void updateDeviceRelayStatusForGetStatus( boolean updated = false; for (final RelayStatus relayStatus : relayStatuses) { if (relayStatus.getIndex() == lightValue.getIndex()) { - relayStatus.updateLastKnownState(lightValue.isOn(), new Date()); + relayStatus.updateLastKnownState(lightValue.isOn(), Instant.now()); updated = true; break; } @@ -551,7 +550,7 @@ private void updateDeviceRelayStatusForGetStatus( if (!updated) { final RelayStatus newRelayStatus = new RelayStatus.Builder(device, lightValue.getIndex()) - .withLastKnownState(lightValue.isOn(), new Date()) + .withLastKnownState(lightValue.isOn(), Instant.now()) .build(); relayStatuses.add(newRelayStatus); } diff --git a/osgp/platform/osgp-adapter-domain-publiclighting/src/main/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/services/ScheduleManagementService.java b/osgp/platform/osgp-adapter-domain-publiclighting/src/main/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/services/ScheduleManagementService.java index 2d04739349c..e083bd19c4e 100644 --- a/osgp/platform/osgp-adapter-domain-publiclighting/src/main/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/services/ScheduleManagementService.java +++ b/osgp/platform/osgp-adapter-domain-publiclighting/src/main/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/services/ScheduleManagementService.java @@ -52,7 +52,7 @@ public void setLightSchedule( new RequestMessage(ids, scheduleDto), messageType, messagePriority, - device.getIpAddress(), + device.getNetworkAddress(), scheduleTime); } diff --git a/osgp/platform/osgp-adapter-domain-publiclighting/src/main/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/services/SetTransitionService.java b/osgp/platform/osgp-adapter-domain-publiclighting/src/main/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/services/SetTransitionService.java index 10e21b99e09..a324043b1cf 100644 --- a/osgp/platform/osgp-adapter-domain-publiclighting/src/main/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/services/SetTransitionService.java +++ b/osgp/platform/osgp-adapter-domain-publiclighting/src/main/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/services/SetTransitionService.java @@ -4,16 +4,15 @@ package org.opensmartgridplatform.adapter.domain.publiclighting.application.services; -import java.net.InetAddress; import java.time.Duration; import java.time.Instant; +import java.time.ZonedDateTime; import java.util.Iterator; import java.util.Set; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import javax.annotation.PreDestroy; import javax.validation.constraints.NotNull; -import org.joda.time.DateTime; import org.opensmartgridplatform.adapter.domain.publiclighting.application.valueobjects.CdmaBatch; import org.opensmartgridplatform.adapter.domain.publiclighting.application.valueobjects.CdmaBatchDevice; import org.opensmartgridplatform.adapter.domain.publiclighting.application.valueobjects.CdmaMastSegment; @@ -44,7 +43,7 @@ public SetTransitionService( public void setTransitionForDevice( final MessageMetadata metadata, @NotNull final TransitionType transitionType, - final DateTime transitionTime) + final ZonedDateTime transitionTime) throws FunctionalException { final String organisationIdentification = metadata.getOrganisationIdentification(); @@ -58,14 +57,15 @@ public void setTransitionForDevice( this.findOrganisation(organisationIdentification); final Device device = this.findActiveDevice(deviceIdentification); - this.setTransitionForDevice(metadata, device.getIpAddress(), transitionType, transitionTime); + this.setTransitionForDevice( + metadata, device.getNetworkAddress(), transitionType, transitionTime); } private void setTransitionForDevice( final MessageMetadata metadata, final String ipAddress, @NotNull final TransitionType transitionType, - final DateTime transitionTime) { + final ZonedDateTime transitionTime) { final String organisationIdentification = metadata.getOrganisationIdentification(); final String deviceIdentification = metadata.getDeviceIdentification(); @@ -212,13 +212,12 @@ private void setTransitionForDeviceRunnable( DeviceFunction.SET_TRANSITION.name()) .build(); - final DateTime emptyTransitionTime = null; - final InetAddress inetAddress = device.getInetAddress(); + final String networkAddress = device.getNetworkAddress(); try { - if (inetAddress != null) { + if (networkAddress != null) { SetTransitionService.this.setTransitionForDevice( - metadata, inetAddress.getHostAddress(), transitionType, emptyTransitionTime); + metadata, networkAddress, transitionType, null); } else { LOGGER.warn( "setTransition not possible, because InetAddress is null for device {}", diff --git a/osgp/platform/osgp-adapter-domain-publiclighting/src/main/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/tasks/BaseTask.java b/osgp/platform/osgp-adapter-domain-publiclighting/src/main/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/tasks/BaseTask.java index ad8cc57940b..cc065609d0a 100644 --- a/osgp/platform/osgp-adapter-domain-publiclighting/src/main/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/tasks/BaseTask.java +++ b/osgp/platform/osgp-adapter-domain-publiclighting/src/main/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/tasks/BaseTask.java @@ -4,8 +4,9 @@ package org.opensmartgridplatform.adapter.domain.publiclighting.application.tasks; -import java.net.InetAddress; import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Collection; @@ -18,8 +19,6 @@ import java.util.Set; import java.util.function.Predicate; import java.util.stream.Collectors; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; import org.opensmartgridplatform.adapter.domain.publiclighting.application.valueobjects.OsgpSystemCorrelationUid; import org.opensmartgridplatform.adapter.domain.publiclighting.infra.jms.core.OsgpCoreRequestMessageSender; import org.opensmartgridplatform.domain.core.entities.Device; @@ -189,7 +188,8 @@ protected List findDevicesToContact( this.eventRepository.findLatestEventForEveryDevice(devices); LOGGER.info("devicesWithEventsList.size(): {}", listOfObjectArrays.size()); - final Date maxAge = DateTime.now(DateTimeZone.UTC).minusHours(maximumAllowedAge).toDate(); + final Date maxAge = + Date.from(ZonedDateTime.now(ZoneId.of("UTC")).minusHours(maximumAllowedAge).toInstant()); LOGGER.info("maxAge: {}", maxAge); final Map map = new HashMap<>(); @@ -251,23 +251,24 @@ protected void sendRequestMessageToDevice( final String deviceFunctionString = deviceFunction.name(); final DomainTypeDto domain = DomainTypeDto.PUBLIC_LIGHTING; - String ipAddress = null; - if (device.getNetworkAddress() == null) { + final String networkAddress = device.getNetworkAddress(); + if (networkAddress == null) { // In case the device does not have a known IP address, don't send // a request message. LOGGER.warn( - "Unable to create protocol request message because the IP address is empty for device: {}", + "Unable to create protocol request message because the network address is empty for device: {}", deviceIdentification); return; - } else { - ipAddress = device.getNetworkAddress().getHostAddress(); } final RequestMessage requestMessage = new RequestMessage(correlationUid, organisation, deviceIdentification, domain); this.osgpCoreRequestMessageSender.send( - requestMessage, deviceFunctionString, MessagePriorityEnum.LOW.getPriority(), ipAddress); + requestMessage, + deviceFunctionString, + MessagePriorityEnum.LOW.getPriority(), + networkAddress); } /** @@ -430,10 +431,10 @@ protected void sendConnectRequestToDevice(final LightMeasurementDevice lightMeas final String messageType = DeviceFunction.CONNECT.name(); final DomainTypeDto domain = DomainTypeDto.PUBLIC_LIGHTING; - final String ipAddress = getIpAddress(lightMeasurementDevice); - if (ipAddress == null) { + final String networkAddress = getNetworkAddress(lightMeasurementDevice); + if (networkAddress == null) { LOGGER.warn( - "Unable to create connect request because no IP address is known for device: {}", + "Unable to create connect request because no network address is known for device: {}", deviceIdentification); return; } @@ -441,7 +442,7 @@ protected void sendConnectRequestToDevice(final LightMeasurementDevice lightMeas final RequestMessage requestMessage = new RequestMessage(correlationUid, organisation, deviceIdentification, domain); this.osgpCoreRequestMessageSender.send( - requestMessage, messageType, MessagePriorityEnum.LOW.getPriority(), ipAddress); + requestMessage, messageType, MessagePriorityEnum.LOW.getPriority(), networkAddress); } private static String getDeviceIdentification(final LightMeasurementDevice device) { @@ -460,25 +461,18 @@ private static String getOwnerOrganisation(final LightMeasurementDevice device) } } - private static String getIpAddress(final Device lightMeasurementDevice) { - final String gatewayIpAddress = getGatewayIpAddress(lightMeasurementDevice); - if (gatewayIpAddress != null) { - return gatewayIpAddress; + private static String getNetworkAddress(final Device lightMeasurementDevice) { + final String gatewayNetworkAddress = getGatewayNetworkAddress(lightMeasurementDevice); + if (gatewayNetworkAddress != null) { + return gatewayNetworkAddress; } - return getHostAddress(lightMeasurementDevice.getNetworkAddress()); + return lightMeasurementDevice.getNetworkAddress(); } - private static String getGatewayIpAddress(final Device lightMeasurementDevice) { + private static String getGatewayNetworkAddress(final Device lightMeasurementDevice) { if (lightMeasurementDevice.getGatewayDevice() == null) { return null; } - return getHostAddress(lightMeasurementDevice.getGatewayDevice().getNetworkAddress()); - } - - private static String getHostAddress(final InetAddress inetAddress) { - if (inetAddress == null) { - return null; - } - return inetAddress.getHostAddress(); + return lightMeasurementDevice.getGatewayDevice().getNetworkAddress(); } } diff --git a/osgp/platform/osgp-adapter-domain-publiclighting/src/main/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/tasks/EventRetrievalScheduledTask.java b/osgp/platform/osgp-adapter-domain-publiclighting/src/main/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/tasks/EventRetrievalScheduledTask.java index 0cec64903ca..9d6c1c7ac89 100644 --- a/osgp/platform/osgp-adapter-domain-publiclighting/src/main/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/tasks/EventRetrievalScheduledTask.java +++ b/osgp/platform/osgp-adapter-domain-publiclighting/src/main/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/tasks/EventRetrievalScheduledTask.java @@ -4,11 +4,11 @@ package org.opensmartgridplatform.adapter.domain.publiclighting.application.tasks; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.util.List; import java.util.function.Predicate; import java.util.stream.Collectors; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; import org.opensmartgridplatform.adapter.domain.publiclighting.application.config.SchedulingConfigForEventRetrievalScheduledTask; import org.opensmartgridplatform.domain.core.entities.Device; import org.opensmartgridplatform.domain.core.entities.DeviceModel; @@ -108,11 +108,11 @@ public List filterByExponentialBackOff(final List devicesToFilte } private boolean calculateThresholdForDevice(final Device device) { - final DateTime threshold = this.determineMinimalDeviceThreshold(device); + final ZonedDateTime threshold = this.determineMinimalDeviceThreshold(device); final boolean isBefore = - new DateTime(device.getLastFailedConnectionTimestamp()) - .withZone(DateTimeZone.UTC) + ZonedDateTime.ofInstant( + device.getLastFailedConnectionTimestamp().toInstant(), ZoneId.of("UTC")) .isBefore(threshold); if (isBefore) { @@ -132,7 +132,7 @@ private boolean calculateThresholdForDevice(final Device device) { return isBefore; } - private DateTime determineMinimalDeviceThreshold(final Device device) { + private ZonedDateTime determineMinimalDeviceThreshold(final Device device) { final int failedConnectionCount = device.getFailedConnectionCount(); final int waitTime = @@ -140,11 +140,11 @@ private DateTime determineMinimalDeviceThreshold(final Device device) { this.calculateDeviceBackOff(failedConnectionCount), this.eventRetrievalScheduledTaskMaxBackoff); - final DateTime threshold = - DateTime.now(DateTimeZone.UTC) + final ZonedDateTime threshold = + ZonedDateTime.now(ZoneId.of("UTC")) .minusMinutes(waitTime) .plusMinutes(this.eventRetrievalScheduledTaskHysteresis) - .withMillisOfSecond(0); + .withNano(0); LOGGER.info( "Determined threshold: {} for device: {} based on failed connection count: {} and hysteresis: {}", diff --git a/osgp/platform/osgp-adapter-domain-publiclighting/src/main/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/valueobjects/CdmaBatchDevice.java b/osgp/platform/osgp-adapter-domain-publiclighting/src/main/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/valueobjects/CdmaBatchDevice.java index 8099b7b1aff..58ae9cddcd1 100644 --- a/osgp/platform/osgp-adapter-domain-publiclighting/src/main/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/valueobjects/CdmaBatchDevice.java +++ b/osgp/platform/osgp-adapter-domain-publiclighting/src/main/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/valueobjects/CdmaBatchDevice.java @@ -4,15 +4,18 @@ package org.opensmartgridplatform.adapter.domain.publiclighting.application.valueobjects; -import java.net.InetAddress; import org.opensmartgridplatform.domain.core.valueobjects.CdmaDevice; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class CdmaBatchDevice { - private String deviceIdentification; - private InetAddress networkAddress; + private static final Logger LOGGER = LoggerFactory.getLogger(CdmaBatchDevice.class); - public CdmaBatchDevice(final String deviceIdentification, final InetAddress networkAddress) { + private final String deviceIdentification; + private final String networkAddress; + + public CdmaBatchDevice(final String deviceIdentification, final String networkAddress) { this.deviceIdentification = deviceIdentification; this.networkAddress = networkAddress; } @@ -26,7 +29,7 @@ public String getDeviceIdentification() { return this.deviceIdentification; } - public InetAddress getInetAddress() { + public String getNetworkAddress() { return this.networkAddress; } diff --git a/osgp/platform/osgp-adapter-domain-publiclighting/src/main/java/org/opensmartgridplatform/adapter/domain/publiclighting/infra/jms/core/OsgpCoreRequestMessageSender.java b/osgp/platform/osgp-adapter-domain-publiclighting/src/main/java/org/opensmartgridplatform/adapter/domain/publiclighting/infra/jms/core/OsgpCoreRequestMessageSender.java index a801335116c..19d057102ea 100644 --- a/osgp/platform/osgp-adapter-domain-publiclighting/src/main/java/org/opensmartgridplatform/adapter/domain/publiclighting/infra/jms/core/OsgpCoreRequestMessageSender.java +++ b/osgp/platform/osgp-adapter-domain-publiclighting/src/main/java/org/opensmartgridplatform/adapter/domain/publiclighting/infra/jms/core/OsgpCoreRequestMessageSender.java @@ -54,7 +54,7 @@ public Message createMessage(final Session session) throws JMSException { requestMessage.getOrganisationIdentification()); objectMessage.setStringProperty( Constants.DEVICE_IDENTIFICATION, requestMessage.getDeviceIdentification()); - objectMessage.setStringProperty(Constants.IP_ADDRESS, ipAddress); + objectMessage.setStringProperty(Constants.NETWORK_ADDRESS, ipAddress); if (scheduleTime != null) { objectMessage.setLongProperty(Constants.SCHEDULE_TIME, scheduleTime); } diff --git a/osgp/platform/osgp-adapter-domain-publiclighting/src/test/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/services/CdmaBatchTest.java b/osgp/platform/osgp-adapter-domain-publiclighting/src/test/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/services/CdmaBatchTest.java index 54889a6469f..4705e779e16 100644 --- a/osgp/platform/osgp-adapter-domain-publiclighting/src/test/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/services/CdmaBatchTest.java +++ b/osgp/platform/osgp-adapter-domain-publiclighting/src/test/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/services/CdmaBatchTest.java @@ -14,7 +14,7 @@ public class CdmaBatchTest { - private final InetAddress loopbackAddress = InetAddress.getLoopbackAddress(); + private final String loopbackAddress = InetAddress.getLoopbackAddress().getHostAddress(); @Test public void newBatchNumberNull() { diff --git a/osgp/platform/osgp-adapter-domain-publiclighting/src/test/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/services/CdmaMastSegmentTest.java b/osgp/platform/osgp-adapter-domain-publiclighting/src/test/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/services/CdmaMastSegmentTest.java index 0c2d0ac69b9..ca1e4c17710 100644 --- a/osgp/platform/osgp-adapter-domain-publiclighting/src/test/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/services/CdmaMastSegmentTest.java +++ b/osgp/platform/osgp-adapter-domain-publiclighting/src/test/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/services/CdmaMastSegmentTest.java @@ -13,12 +13,12 @@ import org.opensmartgridplatform.adapter.domain.publiclighting.application.valueobjects.CdmaBatchDevice; import org.opensmartgridplatform.adapter.domain.publiclighting.application.valueobjects.CdmaMastSegment; -public class CdmaMastSegmentTest { +class CdmaMastSegmentTest { - private final InetAddress loopbackAddress = InetAddress.getLoopbackAddress(); + private final String loopbackAddress = InetAddress.getLoopbackAddress().getHostAddress(); @Test - public void newNameNull() { + void newNameNull() { assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy( () -> { @@ -27,7 +27,7 @@ public void newNameNull() { } @Test - public void newBatchNumberNull() { + void newBatchNumberNull() { final CdmaMastSegment mastSegment = new CdmaMastSegment("200/1"); final CdmaBatchDevice cd1 = new CdmaBatchDevice("cd1", this.loopbackAddress); @@ -39,7 +39,7 @@ public void newBatchNumberNull() { } @Test - public void newCdmaMastSegment() { + void newCdmaMastSegment() { final CdmaMastSegment mastSegment = new CdmaMastSegment("200/1"); final CdmaBatchDevice cd1 = new CdmaBatchDevice("cd1", this.loopbackAddress); @@ -52,7 +52,7 @@ public void newCdmaMastSegment() { } @Test - public void popCdmaBatch() { + void popCdmaBatch() { final CdmaMastSegment mastSegment = new CdmaMastSegment("200/1"); final CdmaBatchDevice cd1 = new CdmaBatchDevice("cd1", this.loopbackAddress); @@ -72,7 +72,7 @@ public void popCdmaBatch() { } @Test - public void equalsWhenSegmentNameMatch() { + void equalsWhenSegmentNameMatch() { final CdmaMastSegment mastSegment1 = new CdmaMastSegment("200/1"); final CdmaMastSegment mastSegment2 = new CdmaMastSegment("200/1"); assertThat(mastSegment1) @@ -81,7 +81,7 @@ public void equalsWhenSegmentNameMatch() { } @Test - public void testSegmentNameDefaultIsLastItem() { + void testSegmentNameDefaultIsLastItem() { final CdmaMastSegment mastSegmentDefault = new CdmaMastSegment(CdmaMastSegment.DEFAULT_MASTSEGMENT); final CdmaMastSegment mastSegmentNormal = new CdmaMastSegment("zzzMast"); @@ -92,7 +92,7 @@ public void testSegmentNameDefaultIsLastItem() { } @Test - public void testPopBatches() { + void testPopBatches() { final CdmaMastSegment mastSegment = new CdmaMastSegment("200/55"); for (short i = 0; i < 10; i++) { // Each device has a different batch diff --git a/osgp/platform/osgp-adapter-domain-publiclighting/src/test/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/services/CdmaRunTest.java b/osgp/platform/osgp-adapter-domain-publiclighting/src/test/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/services/CdmaRunTest.java index d6c37dad5e1..12ec63dd2b3 100644 --- a/osgp/platform/osgp-adapter-domain-publiclighting/src/test/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/services/CdmaRunTest.java +++ b/osgp/platform/osgp-adapter-domain-publiclighting/src/test/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/services/CdmaRunTest.java @@ -34,7 +34,7 @@ public class CdmaRunTest { @Mock private DomainPublicLightingMapper domainCoreMapper; - private final InetAddress loopbackAddress = InetAddress.getLoopbackAddress(); + private final String loopbackAddress = InetAddress.getLoopbackAddress().getHostAddress(); private static final String IP_ADDRESS = "127.0.0.1"; private static final String SET_TRANSITION = "SET_TRANSITION"; diff --git a/osgp/platform/osgp-adapter-domain-publiclighting/src/test/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/tasks/EventRetrievalScheduledTaskTest.java b/osgp/platform/osgp-adapter-domain-publiclighting/src/test/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/tasks/EventRetrievalScheduledTaskTest.java index eb3e730d4a0..9a6dca70508 100644 --- a/osgp/platform/osgp-adapter-domain-publiclighting/src/test/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/tasks/EventRetrievalScheduledTaskTest.java +++ b/osgp/platform/osgp-adapter-domain-publiclighting/src/test/java/org/opensmartgridplatform/adapter/domain/publiclighting/application/tasks/EventRetrievalScheduledTaskTest.java @@ -6,11 +6,11 @@ import static org.assertj.core.api.Assertions.assertThat; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.Date; import java.util.List; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -40,7 +40,10 @@ public void initProperties() { public void applyExponentialBackOffToListOfDevicesWithoutCommunicationErrors() { final List devices = new ArrayList<>(); devices.add( - this.createDevice("device-01", DateTime.now(DateTimeZone.UTC).minusDays(15).toDate(), 0)); + this.createDevice( + "device-01", + Date.from(ZonedDateTime.now(ZoneId.of("UTC")).minusDays(15).toInstant()), + 0)); final List filteredList = this.task.filterByExponentialBackOff(devices); @@ -57,7 +60,10 @@ public void applyExponentialBackOffToListOfDevicesWithoutCommunicationErrors() { applyExponentialBackOffToListOfDevicesWithCommunicationTimestampOlderThan24HoursAndManyConnectionsFailure() { final List devices = new ArrayList<>(); devices.add( - this.createDevice("device-02", DateTime.now(DateTimeZone.UTC).minusDays(2).toDate(), 100)); + this.createDevice( + "device-02", + Date.from(ZonedDateTime.now(ZoneId.of("UTC")).minusDays(2).toInstant()), + 100)); final List filteredList = this.task.filterByExponentialBackOff(devices); @@ -74,7 +80,10 @@ public void applyExponentialBackOffToListOfDevicesWithoutCommunicationErrors() { applyExponentialBackOffToListOfDevicesWithCommunicationTimestampYoungerThan24HoursAnd1ConnectionFailure() { final List devices = new ArrayList<>(); devices.add( - this.createDevice("device-03", DateTime.now(DateTimeZone.UTC).minusHours(23).toDate(), 1)); + this.createDevice( + "device-03", + Date.from(ZonedDateTime.now(ZoneId.of("UTC")).minusHours(23).toInstant()), + 1)); final List filteredList = this.task.filterByExponentialBackOff(devices); @@ -92,7 +101,9 @@ public void applyExponentialBackOffToListOfDevicesWithoutCommunicationErrors() { final List devices = new ArrayList<>(); devices.add( this.createDevice( - "device-04", DateTime.now(DateTimeZone.UTC).minusMinutes(61).toDate(), 1)); + "device-04", + Date.from(ZonedDateTime.now(ZoneId.of("UTC")).minusMinutes(61).toInstant()), + 1)); final List filteredList = this.task.filterByExponentialBackOff(devices); @@ -110,7 +121,9 @@ public void applyExponentialBackOffToListOfDevicesWithoutCommunicationErrors() { final List devices = new ArrayList<>(); devices.add( this.createDevice( - "device-05", DateTime.now(DateTimeZone.UTC).minusMinutes(59).toDate(), 1)); + "device-05", + Date.from(ZonedDateTime.now(ZoneId.of("UTC")).minusMinutes(59).toInstant()), + 1)); final List filteredList = this.task.filterByExponentialBackOff(devices); @@ -127,7 +140,10 @@ public void applyExponentialBackOffToListOfDevicesWithoutCommunicationErrors() { applyExponentialBackOffToListOfDevicesWithCommunicationTimestampYoungerThan1HourAnd2ConnectionFailures() { final List devices = new ArrayList<>(); devices.add( - this.createDevice("device-06", DateTime.now(DateTimeZone.UTC).minusHours(1).toDate(), 2)); + this.createDevice( + "device-06", + Date.from(ZonedDateTime.now(ZoneId.of("UTC")).minusHours(1).toInstant()), + 2)); final List filteredList = this.task.filterByExponentialBackOff(devices); @@ -144,7 +160,10 @@ public void applyExponentialBackOffToListOfDevicesWithoutCommunicationErrors() { applyExponentialBackOffToListOfDevicesWithCommunicationTimestampYoungerThan2HoursAnd1ConnectionFailure() { final List devices = new ArrayList<>(); devices.add( - this.createDevice("device-07", DateTime.now(DateTimeZone.UTC).minusHours(2).toDate(), 1)); + this.createDevice( + "device-07", + Date.from(ZonedDateTime.now(ZoneId.of("UTC")).minusHours(2).toInstant()), + 1)); final List filteredList = this.task.filterByExponentialBackOff(devices); @@ -162,7 +181,9 @@ public void applyExponentialBackOffToListOfDevicesWithoutCommunicationErrors() { final List devices = new ArrayList<>(); devices.add( this.createDevice( - "device-08", DateTime.now(DateTimeZone.UTC).minusHours(2).plusMinutes(1).toDate(), 2)); + "device-08", + Date.from(ZonedDateTime.now(ZoneId.of("UTC")).minusHours(2).plusMinutes(1).toInstant()), + 2)); final List filteredList = this.task.filterByExponentialBackOff(devices); @@ -179,7 +200,10 @@ public void applyExponentialBackOffToListOfDevicesWithoutCommunicationErrors() { applyExponentialBackOffToListOfDevicesWithCommunicationTimestampYoungerThan2HoursAnd3ConnectionFailures() { final List devices = new ArrayList<>(); devices.add( - this.createDevice("device-09", DateTime.now(DateTimeZone.UTC).minusHours(2).toDate(), 3)); + this.createDevice( + "device-09", + Date.from(ZonedDateTime.now(ZoneId.of("UTC")).minusHours(2).toInstant()), + 3)); final List filteredList = this.task.filterByExponentialBackOff(devices); diff --git a/osgp/platform/osgp-adapter-domain-shared/pom.xml b/osgp/platform/osgp-adapter-domain-shared/pom.xml index 313c34a9cca..a9d321fb29e 100644 --- a/osgp/platform/osgp-adapter-domain-shared/pom.xml +++ b/osgp/platform/osgp-adapter-domain-shared/pom.xml @@ -17,7 +17,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-platform - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-platform/pom.xml diff --git a/osgp/platform/osgp-adapter-domain-smartmetering/pom.xml b/osgp/platform/osgp-adapter-domain-smartmetering/pom.xml index 6f9bd6e4176..5ee9698464f 100644 --- a/osgp/platform/osgp-adapter-domain-smartmetering/pom.xml +++ b/osgp/platform/osgp-adapter-domain-smartmetering/pom.xml @@ -18,7 +18,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-platform - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-platform/pom.xml diff --git a/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/mapping/customconverters/ProfileEntryValueConverter.java b/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/mapping/customconverters/ProfileEntryValueConverter.java index dd644ce849b..0009cc2a8d5 100644 --- a/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/mapping/customconverters/ProfileEntryValueConverter.java +++ b/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/mapping/customconverters/ProfileEntryValueConverter.java @@ -6,12 +6,14 @@ import java.math.BigDecimal; import java.util.Date; +import lombok.extern.slf4j.Slf4j; import ma.glasnost.orika.CustomConverter; import ma.glasnost.orika.MappingContext; import ma.glasnost.orika.metadata.Type; import org.opensmartgridplatform.domain.core.valueobjects.smartmetering.ProfileEntryValue; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ProfileEntryValueDto; +@Slf4j public class ProfileEntryValueConverter extends CustomConverter { @@ -22,14 +24,24 @@ public ProfileEntryValue convert( final MappingContext context) { final Object value = source.getValue(); if (value != null) { - if (value instanceof Long) { - return new ProfileEntryValue((Long) value); - } else if (value instanceof Date) { - return new ProfileEntryValue((Date) value); - } else if (value instanceof BigDecimal) { - return new ProfileEntryValue((BigDecimal) value); + if (value instanceof final Long longValue) { + return new ProfileEntryValue(longValue); + } else if (value instanceof final Date date) { + return new ProfileEntryValue(date); + } else if (value instanceof final BigDecimal bigDecimal) { + return new ProfileEntryValue(bigDecimal); + } else if (value instanceof final Integer integer) { + return new ProfileEntryValue(integer); + } else if (value instanceof final Short shortValue) { + return new ProfileEntryValue(shortValue); + } else if (value instanceof final String stringValue) { + return new ProfileEntryValue(stringValue); } else { - return new ProfileEntryValue((String) value); + log.info( + "Using default convert toString() for value {}, with class {}", + value, + value.getClass().getSimpleName()); + return new ProfileEntryValue(value.toString()); } } else { return new ProfileEntryValue((String) null); diff --git a/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/AdhocService.java b/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/AdhocService.java index fa7ff4bccdc..3c09f495fb5 100644 --- a/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/AdhocService.java +++ b/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/AdhocService.java @@ -83,7 +83,7 @@ public void synchronizeTime( requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) .build()); } @@ -110,7 +110,7 @@ public void scheduleTestAlarm( requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) .build()); } @@ -145,7 +145,7 @@ public void getAllAttributeValues(final MessageMetadata messageMetadata) requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) .build()); } @@ -183,7 +183,7 @@ public void getAssociationLnObjects(final MessageMetadata messageMetadata) requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) .build()); } @@ -227,7 +227,7 @@ public void getSpecificAttributeValue( requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) .build()); } @@ -264,7 +264,7 @@ public void scanMbusChannels(final MessageMetadata messageMetadata) throws Funct requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) .build()); } diff --git a/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/BundleService.java b/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/BundleService.java index dbdd09b6e5b..16d644ae721 100644 --- a/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/BundleService.java +++ b/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/BundleService.java @@ -4,6 +4,8 @@ package org.opensmartgridplatform.adapter.domain.smartmetering.application.services; +import static org.opensmartgridplatform.adapter.domain.smartmetering.application.services.util.DeviceModelCodeUtil.createDeviceModelCodes; + import java.util.Arrays; import java.util.List; import org.opensmartgridplatform.adapter.domain.smartmetering.application.mapping.ConfigurationMapper; @@ -81,6 +83,9 @@ public void handleBundle( final SmartMeter smartMeter = this.domainHelperService.findSmartMeter(messageMetadata.getDeviceIdentification()); + final List smartMeters = this.domainHelperService.searchMBusDevicesFor(smartMeter); + final String deviceModelCodes = createDeviceModelCodes(smartMeter, smartMeters); + final BundleMessagesRequestDto requestDto = this.actionMapperService.mapAllActions(bundleMessageRequest, smartMeter); @@ -90,8 +95,9 @@ public void handleBundle( requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) + .withDeviceModelCode(deviceModelCodes) .build()); } diff --git a/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/ConfigurationService.java b/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/ConfigurationService.java index c46475422ce..fe7a08129a5 100644 --- a/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/ConfigurationService.java +++ b/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/ConfigurationService.java @@ -130,7 +130,7 @@ public void setSpecialDays( requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) .build()); } @@ -156,7 +156,7 @@ public void setConfigurationObject( requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) .build()); } @@ -180,7 +180,7 @@ public void setPushSetupAlarm( requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) .build()); } @@ -204,7 +204,7 @@ public void setPushSetupLastGasp( requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) .build()); } @@ -228,7 +228,7 @@ public void setPushSetupSms( requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) .build()); } @@ -253,7 +253,7 @@ public void setPushSetupUdp( requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) .build()); } @@ -299,7 +299,7 @@ public void setAlarmNotifications( requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) .build()); } @@ -326,7 +326,7 @@ public void setAdministrativeStatus( requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) .build()); } @@ -378,7 +378,7 @@ public void getAdministrativeStatus( requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) .build()); } @@ -432,7 +432,7 @@ public void setActivityCalendar( requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) .build()); } @@ -637,7 +637,7 @@ public void setKeyOnGMeter( messageMetadata .builder() .withDeviceIdentification(gatewayDevice.getDeviceIdentification()) - .withIpAddress(gatewayDevice.getIpAddress()) + .withNetworkAddress(gatewayDevice.getNetworkAddress()) .withNetworkSegmentIds(gatewayDevice.getBtsId(), gatewayDevice.getCellId()) .build()); } @@ -683,7 +683,7 @@ public void setMbusUserKeyByChannel( requestDto, messageMetadata .builder() - .withIpAddress(gatewayDevice.getIpAddress()) + .withNetworkAddress(gatewayDevice.getNetworkAddress()) .withNetworkSegmentIds(gatewayDevice.getBtsId(), gatewayDevice.getCellId()) .build()); } @@ -729,7 +729,7 @@ public void replaceKeys(final MessageMetadata messageMetadata, final SetKeysRequ requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) .build()); } @@ -770,7 +770,7 @@ public void generateAndReplaceKeys(final MessageMetadata messageMetadata) null, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) .build()); } @@ -862,7 +862,7 @@ public void requestFirmwareVersion( messageMetadata .builder() .withDeviceIdentification(gatewayDevice.getDeviceIdentification()) - .withIpAddress(gatewayDevice.getIpAddress()) + .withNetworkAddress(gatewayDevice.getNetworkAddress()) .withNetworkSegmentIds(gatewayDevice.getBtsId(), gatewayDevice.getCellId()) .build()); @@ -873,7 +873,7 @@ public void requestFirmwareVersion( requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) .build()); } @@ -988,12 +988,12 @@ public void requestUpdateFirmware( final Device gatewayDevice = smartMeter.getGatewayDevice(); if (gatewayDevice != null) { deviceIdentification = gatewayDevice.getDeviceIdentification(); - ipAddress = gatewayDevice.getIpAddress(); + ipAddress = gatewayDevice.getNetworkAddress(); baseTransceiverStationId = gatewayDevice.getBtsId(); cellId = gatewayDevice.getCellId(); } else { deviceIdentification = smartMeter.getDeviceIdentification(); - ipAddress = smartMeter.getIpAddress(); + ipAddress = smartMeter.getNetworkAddress(); baseTransceiverStationId = smartMeter.getBtsId(); cellId = smartMeter.getCellId(); } @@ -1005,7 +1005,7 @@ public void requestUpdateFirmware( messageMetadata .builder() .withDeviceIdentification(deviceIdentification) - .withIpAddress(ipAddress) + .withNetworkAddress(ipAddress) .withNetworkSegmentIds(baseTransceiverStationId, cellId) .build()); } @@ -1058,7 +1058,7 @@ public void setClockConfiguration( requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) .build()); } @@ -1108,7 +1108,7 @@ public void getConfigurationObject( requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) .build()); } @@ -1163,7 +1163,7 @@ public void configureDefinableLoadProfile( requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) .build()); } @@ -1221,7 +1221,7 @@ public void getMbusEncryptionKeyStatus(final MessageMetadata messageMetadata) messageMetadata .builder() .withDeviceIdentification(gatewayDevice.getDeviceIdentification()) - .withIpAddress(gatewayDevice.getIpAddress()) + .withNetworkAddress(gatewayDevice.getNetworkAddress()) .withNetworkSegmentIds(gatewayDevice.getBtsId(), gatewayDevice.getCellId()) .build()); } @@ -1279,7 +1279,7 @@ public void getMbusEncryptionKeyStatusByChannel( messageMetadata .builder() .withDeviceIdentification(gatewayDevice.getDeviceIdentification()) - .withIpAddress(gatewayDevice.getIpAddress()) + .withNetworkAddress(gatewayDevice.getNetworkAddress()) .withNetworkSegmentIds(gatewayDevice.getBtsId(), gatewayDevice.getCellId()) .build()); } @@ -1332,7 +1332,7 @@ public void setRandomisationSettings( requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) .build()); } @@ -1383,7 +1383,7 @@ public void getKeys( requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) .build()); } diff --git a/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/DomainHelperService.java b/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/DomainHelperService.java index 250826c0f2f..5664cd671b3 100644 --- a/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/DomainHelperService.java +++ b/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/DomainHelperService.java @@ -4,6 +4,7 @@ package org.opensmartgridplatform.adapter.domain.smartmetering.application.services; +import java.util.List; import org.opensmartgridplatform.domain.core.entities.SmartMeter; import org.opensmartgridplatform.domain.core.exceptions.UnknownEntityException; import org.opensmartgridplatform.domain.core.services.SmartMeterDomainService; @@ -56,4 +57,16 @@ public void ensureFunctionalExceptionForUnknownDevice(final String deviceIdentif */ this.findSmartMeter(deviceIdentification); } + + /** + * Search the MBus Devices coupled on this SmartMeter. + * + * @param smartMeter + * @return the active device for the given identification + * @throws FunctionalException when the device is not in the database or is not in use + */ + public List searchMBusDevicesFor(final SmartMeter smartMeter) { + + return this.smartMeteringDeviceDomainService.searchMBusDevicesFor(smartMeter); + } } diff --git a/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/MBusGatewayService.java b/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/MBusGatewayService.java index 039ee77398b..b19f01e1e44 100644 --- a/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/MBusGatewayService.java +++ b/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/MBusGatewayService.java @@ -94,7 +94,7 @@ public void coupleMbusDevice( requestDto, messageMetadata .builder() - .withIpAddress(gatewayDevice.getIpAddress()) + .withNetworkAddress(gatewayDevice.getNetworkAddress()) .withNetworkSegmentIds(gatewayDevice.getBtsId(), gatewayDevice.getCellId()) .build()); } @@ -128,7 +128,7 @@ public void decoupleMbusDevice( requestDto, messageMetadata .builder() - .withIpAddress(gatewayDevice.getIpAddress()) + .withNetworkAddress(gatewayDevice.getNetworkAddress()) .withNetworkSegmentIds(gatewayDevice.getBtsId(), gatewayDevice.getCellId()) .build()); } @@ -175,7 +175,7 @@ public void decoupleMbusDeviceByChannel( requestDto, messageMetadata .builder() - .withIpAddress(gatewayDevice.getIpAddress()) + .withNetworkAddress(gatewayDevice.getNetworkAddress()) .withNetworkSegmentIds(gatewayDevice.getBtsId(), gatewayDevice.getCellId()) .build()); } @@ -235,7 +235,7 @@ public void coupleMbusDeviceByChannel( requestDto, messageMetadata .builder() - .withIpAddress(gatewayDevice.getIpAddress()) + .withNetworkAddress(gatewayDevice.getNetworkAddress()) .withNetworkSegmentIds(gatewayDevice.getBtsId(), gatewayDevice.getCellId()) .build()); } diff --git a/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/ManagementService.java b/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/ManagementService.java index 612053d85f4..59d3e5e9a9a 100644 --- a/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/ManagementService.java +++ b/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/ManagementService.java @@ -95,7 +95,7 @@ public void findEvents( requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) .build()); } @@ -189,7 +189,7 @@ public void setDeviceCommunicationSettings( requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) .build()); } @@ -225,7 +225,7 @@ public void setDeviceLifecycleStatusByChannel( requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) .build()); } @@ -284,7 +284,7 @@ public void getGsmDiagnostic( requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) .build()); } @@ -329,7 +329,7 @@ public void clearMBusStatusOnAllChannels( requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) .build()); } @@ -367,7 +367,7 @@ public void updateProtocol( requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) .build()); } @@ -447,7 +447,7 @@ private void sendMetadataOnlyRequestMessage(final MessageMetadata messageMetadat this.domainHelperService.findSmartMeter(messageMetadata.getDeviceIdentification()); LOGGER.info(SENDING_REQUEST_MESSAGE_TO_CORE_LOG_MSG); - this.osgpCoreRequestMessageSender.send(smartMeter.getIpAddress(), messageMetadata); + this.osgpCoreRequestMessageSender.send(smartMeter.getNetworkAddress(), messageMetadata); } private void handleMetadataOnlyResponseMessage( diff --git a/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/MonitoringService.java b/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/MonitoringService.java index 13be2a8de22..6082ef16524 100644 --- a/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/MonitoringService.java +++ b/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/MonitoringService.java @@ -4,6 +4,9 @@ package org.opensmartgridplatform.adapter.domain.smartmetering.application.services; +import static org.opensmartgridplatform.adapter.domain.smartmetering.application.services.util.DeviceModelCodeUtil.createDeviceModelCodes; + +import java.util.List; import org.opensmartgridplatform.adapter.domain.smartmetering.application.mapping.MonitoringMapper; import org.opensmartgridplatform.adapter.domain.smartmetering.infra.jms.core.JmsMessageSender; import org.opensmartgridplatform.adapter.domain.smartmetering.infra.jms.ws.WebServiceResponseMessageSender; @@ -123,15 +126,26 @@ public void requestPeriodicMeterReads( new AssertionError( "Meter for gas reads should have an energy meter as gateway device.")); } + + final SmartMeter gatewaySmartMeter = + this.domainHelperService.findSmartMeter(gatewayDevice.getDeviceIdentification()); + final List smartMeters = + this.domainHelperService.searchMBusDevicesFor(gatewaySmartMeter); + final String deviceModelCodes = createDeviceModelCodes(gatewaySmartMeter, smartMeters); + this.osgpCoreRequestMessageSender.send( requestDto, messageMetadata .builder() .withDeviceIdentification(gatewayDevice.getDeviceIdentification()) - .withIpAddress(gatewayDevice.getIpAddress()) + .withNetworkAddress(gatewayDevice.getNetworkAddress()) .withNetworkSegmentIds(gatewayDevice.getBtsId(), gatewayDevice.getCellId()) + .withDeviceModelCode(deviceModelCodes) .build()); } else { + final List smartMeters = + this.domainHelperService.searchMBusDevicesFor(smartMeter); + final String deviceModelCodes = createDeviceModelCodes(smartMeter, smartMeters); final PeriodicMeterReadsRequestDto requestDto = this.monitoringMapper.map( @@ -140,8 +154,9 @@ public void requestPeriodicMeterReads( requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) + .withDeviceModelCode(deviceModelCodes) .build()); } } @@ -211,7 +226,6 @@ public void requestActualMeterReads( final SmartMeter smartMeter = this.domainHelperService.findSmartMeter(messageMetadata.getDeviceIdentification()); - if (actualMeterReadsQuery.isMbusDevice()) { if (smartMeter.getChannel() == null) { @@ -240,6 +254,13 @@ public void requestActualMeterReads( new AssertionError( "Meter for gas reads should have an energy meter as gateway device.")); } + + final SmartMeter gatewaySmartMeter = + this.domainHelperService.findSmartMeter(gatewayDevice.getDeviceIdentification()); + final List smartMeters = + this.domainHelperService.searchMBusDevicesFor(gatewaySmartMeter); + final String deviceModelCodes = createDeviceModelCodes(gatewaySmartMeter, smartMeters); + final ActualMeterReadsQueryDto requestDto = new ActualMeterReadsQueryDto(ChannelDto.fromNumber(smartMeter.getChannel())); this.osgpCoreRequestMessageSender.send( @@ -247,16 +268,23 @@ public void requestActualMeterReads( messageMetadata .builder() .withDeviceIdentification(gatewayDevice.getDeviceIdentification()) - .withIpAddress(gatewayDevice.getIpAddress()) + .withNetworkAddress(gatewayDevice.getNetworkAddress()) .withNetworkSegmentIds(gatewayDevice.getBtsId(), gatewayDevice.getCellId()) + .withDeviceModelCode(deviceModelCodes) .build()); } else { + + final List smartMeters = + this.domainHelperService.searchMBusDevicesFor(smartMeter); + final String deviceModelCodes = createDeviceModelCodes(smartMeter, smartMeters); + this.osgpCoreRequestMessageSender.send( new ActualMeterReadsQueryDto(), messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) + .withDeviceModelCode(deviceModelCodes) .build()); } } @@ -323,6 +351,9 @@ public void requestActualPowerQuality( final SmartMeter smartMeter = this.domainHelperService.findSmartMeter(messageMetadata.getDeviceIdentification()); + final List smartMeters = this.domainHelperService.searchMBusDevicesFor(smartMeter); + final String deviceModelCodes = createDeviceModelCodes(smartMeter, smartMeters); + final ActualPowerQualityRequestDto requestDto = this.monitoringMapper.map(request, ActualPowerQualityRequestDto.class); @@ -330,8 +361,9 @@ public void requestActualPowerQuality( requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) + .withDeviceModelCode(deviceModelCodes) .build()); } @@ -385,7 +417,7 @@ public void requestReadAlarmRegister( requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) .build()); } @@ -430,6 +462,9 @@ public void requestPowerQualityProfile( final SmartMeter smartMeter = this.domainHelperService.findSmartMeter(messageMetadata.getDeviceIdentification()); + final List smartMeters = this.domainHelperService.searchMBusDevicesFor(smartMeter); + final String deviceModelCodes = createDeviceModelCodes(smartMeter, smartMeters); + final ConfigureDefinableLoadProfileRequestDto requestDto = this.monitoringMapper.map(request, ConfigureDefinableLoadProfileRequestDto.class); @@ -437,8 +472,9 @@ public void requestPowerQualityProfile( requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) + .withDeviceModelCode(deviceModelCodes) .build()); } @@ -492,7 +528,7 @@ public void requestClearAlarmRegister( requestDto, messageMetadata .builder() - .withIpAddress(smartMeter.getIpAddress()) + .withNetworkAddress(smartMeter.getNetworkAddress()) .withNetworkSegmentIds(smartMeter.getBtsId(), smartMeter.getCellId()) .build()); } diff --git a/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/util/DeviceModelCodeUtil.java b/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/util/DeviceModelCodeUtil.java new file mode 100644 index 00000000000..6c891c608de --- /dev/null +++ b/osgp/platform/osgp-adapter-domain-smartmetering/src/main/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/util/DeviceModelCodeUtil.java @@ -0,0 +1,36 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 +package org.opensmartgridplatform.adapter.domain.smartmetering.application.services.util; + +import java.util.List; +import org.opensmartgridplatform.domain.core.entities.SmartMeter; + +public class DeviceModelCodeUtil { + private DeviceModelCodeUtil() { + /// static class + } + + public static String createDeviceModelCodes( + final SmartMeter gatewayDevice, final List mbusDevices) { + + final String emetercode = + gatewayDevice.getDeviceModel() != null ? gatewayDevice.getDeviceModel().getModelCode() : ""; + final String mbus1code = getAndMapMbusChannelSmartMeter(mbusDevices, 1); + final String mbus2code = getAndMapMbusChannelSmartMeter(mbusDevices, 2); + final String mbus3code = getAndMapMbusChannelSmartMeter(mbusDevices, 3); + final String mbus4code = getAndMapMbusChannelSmartMeter(mbusDevices, 4); + + return String.format("%s,%s,%s,%s,%s", emetercode, mbus1code, mbus2code, mbus3code, mbus4code); + } + + private static String getAndMapMbusChannelSmartMeter( + final List mbusDevices, final int channel) { + return mbusDevices.stream() + .filter(m -> m.getChannel() != null && m.getChannel() == channel) + .map(m -> m.getDeviceModel() != null ? m.getDeviceModel().getModelCode() : "") + .map(s -> s.replace(",", "")) // no comma's signs + .findAny() + .orElse(""); + } +} diff --git a/osgp/platform/osgp-adapter-domain-smartmetering/src/test/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/mapping/InstallationMapperTest.java b/osgp/platform/osgp-adapter-domain-smartmetering/src/test/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/mapping/InstallationMapperTest.java index 45276f4eecb..e61063a2dcc 100644 --- a/osgp/platform/osgp-adapter-domain-smartmetering/src/test/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/mapping/InstallationMapperTest.java +++ b/osgp/platform/osgp-adapter-domain-smartmetering/src/test/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/mapping/InstallationMapperTest.java @@ -76,6 +76,7 @@ public void testSmartMeteringDeviceToSmartMeteringDeviceDtoMapping() { smartMeteringDevice.setGlobalEncryptionUnicastKey("globalEncryptionUnicastKey".getBytes()); smartMeteringDevice.setAuthenticationKey("authenticationKey".getBytes()); smartMeteringDevice.setSupplier("supplier"); + smartMeteringDevice.setLls1Active(true); smartMeteringDevice.setHls3Active(true); smartMeteringDevice.setHls4Active(true); smartMeteringDevice.setHls5Active(true); @@ -93,7 +94,8 @@ public void testSmartMeteringDeviceToSmartMeteringDeviceDtoMapping() { assertThat(smartMeteringDeviceDto).isNotNull(); assertThat(smartMeteringDeviceDto) .isEqualToIgnoringGivenFields( - smartMeteringDevice, "hls3Active", "hls4Active", "hls5Active"); + smartMeteringDevice, "lls1Active", "hls3Active", "hls4Active", "hls5Active"); + assertThat(smartMeteringDeviceDto.isLls1Active()).isEqualTo(smartMeteringDevice.isLls1Active()); assertThat(smartMeteringDeviceDto.isHls3Active()).isEqualTo(smartMeteringDevice.isHls3Active()); assertThat(smartMeteringDeviceDto.isHls4Active()).isEqualTo(smartMeteringDevice.isHls4Active()); assertThat(smartMeteringDeviceDto.isHls5Active()).isEqualTo(smartMeteringDevice.isHls5Active()); diff --git a/osgp/platform/osgp-adapter-domain-smartmetering/src/test/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/ConfigurationServiceTest.java b/osgp/platform/osgp-adapter-domain-smartmetering/src/test/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/ConfigurationServiceTest.java index 503f5d2d599..db44f566641 100644 --- a/osgp/platform/osgp-adapter-domain-smartmetering/src/test/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/ConfigurationServiceTest.java +++ b/osgp/platform/osgp-adapter-domain-smartmetering/src/test/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/ConfigurationServiceTest.java @@ -10,8 +10,6 @@ import static org.mockito.Mockito.when; import java.io.Serializable; -import java.net.InetAddress; -import java.net.UnknownHostException; import java.util.Arrays; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -73,19 +71,15 @@ class ConfigurationServiceTest { new KeyDto(SecretTypeDto.E_METER_AUTHENTICATION_KEY, KEY_1), new KeyDto(SecretTypeDto.E_METER_MASTER_KEY, KEY_2))); - private static final String IP_ADDRESS; + private static final String NETWORK_ADDRESS; private static final Integer BASE_TRANSCEIVER_STATION_ID; private static final Integer CELL_ID; static { - try { - device.setNetworkAddress(InetAddress.getByAddress(new byte[] {127, 0, 0, 1})); - IP_ADDRESS = device.getIpAddress(); - BASE_TRANSCEIVER_STATION_ID = device.getBtsId(); - CELL_ID = device.getCellId(); - } catch (final UnknownHostException e) { - throw new AssertionError(e); - } + device.setNetworkAddress("127.0.0.1"); + NETWORK_ADDRESS = device.getNetworkAddress(); + BASE_TRANSCEIVER_STATION_ID = device.getBtsId(); + CELL_ID = device.getCellId(); } @InjectMocks private ConfigurationService instance; @@ -115,7 +109,7 @@ void getKeys() throws FunctionalException { final MessageMetadata expectedMessageMetadata = messageMetadata .builder() - .withIpAddress(IP_ADDRESS) + .withNetworkAddress(NETWORK_ADDRESS) .withNetworkSegmentIds(BASE_TRANSCEIVER_STATION_ID, CELL_ID) .build(); diff --git a/osgp/platform/osgp-adapter-domain-smartmetering/src/test/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/MeterReadsGasMappingTest.java b/osgp/platform/osgp-adapter-domain-smartmetering/src/test/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/MeterReadsGasMappingTest.java index ea3b7eced9e..6eda5d8b639 100644 --- a/osgp/platform/osgp-adapter-domain-smartmetering/src/test/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/MeterReadsGasMappingTest.java +++ b/osgp/platform/osgp-adapter-domain-smartmetering/src/test/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/MeterReadsGasMappingTest.java @@ -17,16 +17,16 @@ import org.opensmartgridplatform.dto.valueobjects.smartmetering.DlmsUnitTypeDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.MeterReadsGasResponseDto; -public class MeterReadsGasMappingTest { +class MeterReadsGasMappingTest { private final MonitoringMapper monitoringMapper = new MonitoringMapper(); // Test the mapping of a complete MeterReadsGasDto object @Test - public void testMeterReadsGasMappingTest() { + void testMeterReadsGasMappingTest() { // build test data final DlmsMeterValueDto consumption = - new DlmsMeterValueDto(new BigDecimal(1.0), DlmsUnitTypeDto.M3); + new DlmsMeterValueDto(new BigDecimal("1.0"), DlmsUnitTypeDto.M3); final MeterReadsGasResponseDto meterReadsGasDto = new MeterReadsGasResponseDto(new Date(), consumption, new Date()); // actual mapping @@ -39,13 +39,35 @@ public void testMeterReadsGasMappingTest() { final BigDecimal bigDecimal1 = consumption.getValue(); final BigDecimal bigDecimal2 = meterReadsGas.getConsumption().getValue(); - assertThat(bigDecimal1.compareTo(bigDecimal2) == 0).isTrue(); + assertThat(bigDecimal1).isEqualByComparingTo(bigDecimal2); + assertThat(meterReadsGas.getConsumption().getOsgpUnit()).isEqualTo(OsgpUnit.M3); + } + + // Test the mapping of a complete MeterReadsGasDto object without a capture time + @Test + void testMeterReadsGasMappingWithoutCaptureTimeTest() { + // build test data + final DlmsMeterValueDto consumption = + new DlmsMeterValueDto(new BigDecimal("1.0"), DlmsUnitTypeDto.M3); + final MeterReadsGasResponseDto meterReadsGasDto = + new MeterReadsGasResponseDto(new Date(), consumption, null); + // actual mapping + final MeterReadsGas meterReadsGas = + this.monitoringMapper.map(meterReadsGasDto, MeterReadsGas.class); + // test mapping + assertThat(meterReadsGas).isNotNull(); + assertThat(meterReadsGas.getLogTime()).isEqualTo(meterReadsGasDto.getLogTime()); + assertThat(meterReadsGas.getCaptureTime()).isNull(); + + final BigDecimal bigDecimal1 = consumption.getValue(); + final BigDecimal bigDecimal2 = meterReadsGas.getConsumption().getValue(); + assertThat(bigDecimal1).isEqualByComparingTo(bigDecimal2); assertThat(meterReadsGas.getConsumption().getOsgpUnit()).isEqualTo(OsgpUnit.M3); } // Test mapping when DlmsMeterValue is null; @Test - public void testWithNullDlmsMeterValueDto() { + void testWithNullDlmsMeterValueDto() { // build test data final DlmsMeterValueDto consumption = null; final MeterReadsGasResponseDto meterReadsGasDto = @@ -63,7 +85,7 @@ public void testWithNullDlmsMeterValueDto() { // Dates can never be null, because of the way the constructor for a // MeterReadsGasDto is defined. @Test - public void testWithNullDates() { + void testWithNullDates() { final DlmsMeterValueDto consumption = new DlmsMeterValueDto(new BigDecimal(1.0), DlmsUnitTypeDto.M3); assertThatExceptionOfType(NullPointerException.class) diff --git a/osgp/platform/osgp-adapter-domain-smartmetering/src/test/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/MonitoringServiceTest.java b/osgp/platform/osgp-adapter-domain-smartmetering/src/test/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/MonitoringServiceTest.java new file mode 100644 index 00000000000..28672494104 --- /dev/null +++ b/osgp/platform/osgp-adapter-domain-smartmetering/src/test/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/MonitoringServiceTest.java @@ -0,0 +1,145 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.adapter.domain.smartmetering.application.services; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.List; +import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.ArgumentCaptor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; +import org.opensmartgridplatform.adapter.domain.smartmetering.application.mapping.MonitoringMapper; +import org.opensmartgridplatform.adapter.domain.smartmetering.infra.jms.core.JmsMessageSender; +import org.opensmartgridplatform.domain.core.entities.DeviceModel; +import org.opensmartgridplatform.domain.core.entities.SmartMeter; +import org.opensmartgridplatform.domain.core.valueobjects.smartmetering.ActualMeterReadsQuery; +import org.opensmartgridplatform.domain.core.valueobjects.smartmetering.ActualPowerQualityRequest; +import org.opensmartgridplatform.domain.core.valueobjects.smartmetering.GetPowerQualityProfileRequest; +import org.opensmartgridplatform.domain.core.valueobjects.smartmetering.PeriodicMeterReadsQuery; +import org.opensmartgridplatform.shared.exceptionhandling.FunctionalException; +import org.opensmartgridplatform.shared.infra.jms.MessageMetadata; + +@ExtendWith(MockitoExtension.class) +@Slf4j +class MonitoringServiceTest { + + public static final String TEST_1024000000001 = "TEST1024000000001"; + + public static final String NETWORK_ADDRESS = "127.0.0.1"; + + private static final String DEVICE_MODEL_CODE = "BK-G4 ETB WR"; + + public static final int BTS_580 = 580; + + public static final int CELL_ID_1 = 1; + + @Mock private DomainHelperService domainHelperService; + + @Mock private MonitoringMapper monitoringMapper; + + @Mock private JmsMessageSender osgpCoreRequestMessageSender; + + @InjectMocks private MonitoringService monitoringService; + + private final ArgumentCaptor messageMetadataCaptor = + ArgumentCaptor.forClass(MessageMetadata.class); + + @ParameterizedTest + @MethodSource("methodNames") + void requestPeriodicMeterReads(final String methodName, final Class clazz) + throws FunctionalException, InvocationTargetException, NoSuchMethodException, + IllegalAccessException { + + final MessageMetadata messageMetadata = mock(MessageMetadata.class); + final SmartMeter smartMeter = mockSmartMeter("base code", null); + final SmartMeter meterOnCh1 = mockSmartMeter("channel 1 code", (short) 1); + final SmartMeter meterOnCh2 = mockSmartMeter("channel 2 code", (short) 2); + final SmartMeter meterOnCh3 = mockSmartMeter("channel 3 code", (short) 3); + final SmartMeter meterOnCh4 = mockSmartMeter("channel 4 code", (short) 4); + + when(messageMetadata.builder()).thenReturn(MessageMetadata.newBuilder()); + when(messageMetadata.getDeviceIdentification()).thenReturn(TEST_1024000000001); + when(messageMetadata.getOrganisationIdentification()).thenReturn("test-org"); + when(this.domainHelperService.findSmartMeter(TEST_1024000000001)).thenReturn(smartMeter); + when(this.domainHelperService.searchMBusDevicesFor(smartMeter)) + .thenReturn(List.of(smartMeter, meterOnCh1, meterOnCh2, meterOnCh3, meterOnCh4)); + + this.invokeMethodByName(methodName, clazz, messageMetadata); + + verify(this.osgpCoreRequestMessageSender) + .send(Mockito.any(), this.messageMetadataCaptor.capture()); + + final MessageMetadata metadata = this.messageMetadataCaptor.getValue(); + final String expectedDeviceModelCode = + String.format( + "%s,%s,%s,%s,%s", + getModelCode(smartMeter), + getModelCode(meterOnCh1), + getModelCode(meterOnCh2), + getModelCode(meterOnCh3), + getModelCode(meterOnCh4)); + + assertNotNull(metadata); + assertEquals(NETWORK_ADDRESS, metadata.getNetworkAddress()); + assertEquals(BTS_580, metadata.getBaseTransceiverStationId()); + assertEquals(CELL_ID_1, metadata.getCellId()); + assertEquals(expectedDeviceModelCode, metadata.getDeviceModelCode()); + } + + private static String getModelCode(final SmartMeter smartMeter) { + return smartMeter.getDeviceModel().getModelCode(); + } + + private static Stream methodNames() { + return Stream.of( + Arguments.of("requestPeriodicMeterReads", PeriodicMeterReadsQuery.class), + Arguments.of("requestActualMeterReads", ActualMeterReadsQuery.class), + Arguments.of("requestActualPowerQuality", ActualPowerQualityRequest.class), + Arguments.of("requestPeriodicMeterReads", PeriodicMeterReadsQuery.class), + Arguments.of("requestPowerQualityProfile", GetPowerQualityProfileRequest.class)); + } + + private void invokeMethodByName( + final String methodName, final Class clazz, final MessageMetadata messageMetadata) + throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + final Method method = + MonitoringService.class.getMethod(methodName, MessageMetadata.class, clazz); + method.invoke(this.monitoringService, messageMetadata, mock(clazz)); + } + + private void verifyMessageMetadata() {} + + private static SmartMeter mockSmartMeter(final String deviceModelCode, final Short channel) { + final DeviceModel deviceModel = mock(DeviceModel.class); + + final SmartMeter smartMeter = mock(SmartMeter.class); + + if (channel == null) { + when(smartMeter.getNetworkAddress()).thenReturn(NETWORK_ADDRESS); + when(smartMeter.getBtsId()).thenReturn(BTS_580); + when(smartMeter.getCellId()).thenReturn(CELL_ID_1); + } else { + when(smartMeter.getChannel()).thenReturn(channel); + } + + when(smartMeter.getDeviceModel()).thenReturn(deviceModel); + when(deviceModel.getModelCode()).thenReturn(deviceModelCode); + + return smartMeter; + } +} diff --git a/osgp/platform/osgp-adapter-domain-smartmetering/src/test/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/util/DeviceModelCodeUtilTest.java b/osgp/platform/osgp-adapter-domain-smartmetering/src/test/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/util/DeviceModelCodeUtilTest.java new file mode 100644 index 00000000000..26792627427 --- /dev/null +++ b/osgp/platform/osgp-adapter-domain-smartmetering/src/test/java/org/opensmartgridplatform/adapter/domain/smartmetering/application/services/util/DeviceModelCodeUtilTest.java @@ -0,0 +1,73 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 +package org.opensmartgridplatform.adapter.domain.smartmetering.application.services.util; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.when; + +import java.util.Arrays; +import java.util.Collections; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; +import org.opensmartgridplatform.domain.core.entities.DeviceModel; +import org.opensmartgridplatform.domain.core.entities.SmartMeter; + +@ExtendWith(MockitoExtension.class) +class DeviceModelCodeUtilTest { + + @Test + void shouldGiveAllDeviceModelCodes() { + final SmartMeter baseMeter = createSmartMeterMock("base meter", null); + final SmartMeter gmeter1 = createSmartMeterMock("g-meter 1", (short) 1); + final SmartMeter gmeter2 = createSmartMeterMock("g-meter 2", (short) 2); + final SmartMeter gmeter3 = createSmartMeterMock("g-meter 3", (short) 3); + final SmartMeter gmeter4 = createSmartMeterMock("g-meter 4", (short) 4); + + final String codes = + DeviceModelCodeUtil.createDeviceModelCodes( + baseMeter, Arrays.asList(gmeter1, gmeter2, gmeter3, gmeter4)); + + assertEquals("base meter,g-meter 1,g-meter 2,g-meter 3,g-meter 4", codes); + } + + @Test + void createDeviceModelCodesShouldGiveSomeDeviceModelCodes() { + final SmartMeter baseMeter = createSmartMeterMock("base meter", null); + final SmartMeter gmeter1 = createSmartMeterMock("g-meter 1", (short) 1); + final SmartMeter gmeter3 = createSmartMeterMock("g-meter 3", (short) 3); + + final String codes = + DeviceModelCodeUtil.createDeviceModelCodes(baseMeter, Arrays.asList(gmeter1, gmeter3)); + + assertEquals("base meter,g-meter 1,,g-meter 3,", codes); + } + + @Test + void createDeviceModelCodesShouldBeSafeForNullChannel() { + final SmartMeter baseMeter = createSmartMeterMock("base meter", null); + final SmartMeter gmeter1 = createSmartMeterMock(null, null); + + final String codes = + DeviceModelCodeUtil.createDeviceModelCodes(baseMeter, Collections.singletonList(gmeter1)); + assertEquals("base meter,,,,", codes); + } + + private static SmartMeter createSmartMeterMock(final String code, final Short channel) { + final SmartMeter smartMeter = Mockito.mock(SmartMeter.class); + + if (code != null) { + final DeviceModel deviceModel = Mockito.mock(DeviceModel.class); + when(deviceModel.getModelCode()).thenReturn(code); + when(smartMeter.getDeviceModel()).thenReturn(deviceModel); + } + + if (channel != null) { + when(smartMeter.getChannel()).thenReturn(channel); + } + + return smartMeter; + } +} diff --git a/osgp/platform/osgp-adapter-domain-tariffswitching/pom.xml b/osgp/platform/osgp-adapter-domain-tariffswitching/pom.xml index ae94c498a51..7d8975fd3dd 100644 --- a/osgp/platform/osgp-adapter-domain-tariffswitching/pom.xml +++ b/osgp/platform/osgp-adapter-domain-tariffswitching/pom.xml @@ -17,7 +17,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-platform - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-platform/pom.xml diff --git a/osgp/platform/osgp-adapter-domain-tariffswitching/src/main/java/org/opensmartgridplatform/adapter/domain/tariffswitching/application/services/AdHocManagementService.java b/osgp/platform/osgp-adapter-domain-tariffswitching/src/main/java/org/opensmartgridplatform/adapter/domain/tariffswitching/application/services/AdHocManagementService.java index 69a7e5cb51a..71e8a0777e8 100644 --- a/osgp/platform/osgp-adapter-domain-tariffswitching/src/main/java/org/opensmartgridplatform/adapter/domain/tariffswitching/application/services/AdHocManagementService.java +++ b/osgp/platform/osgp-adapter-domain-tariffswitching/src/main/java/org/opensmartgridplatform/adapter/domain/tariffswitching/application/services/AdHocManagementService.java @@ -4,7 +4,7 @@ package org.opensmartgridplatform.adapter.domain.tariffswitching.application.services; -import java.util.Date; +import java.time.Instant; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -78,7 +78,7 @@ public void getStatus( correlationUid, organisationIdentification, deviceIdentification, allowedDomainTypeDto), messageType, messagePriority, - device.getIpAddress()); + device.getNetworkAddress()); } public void handleGetStatusResponse( @@ -154,12 +154,12 @@ private void updateDeviceRelayOverview( final RelayStatus oldRelayStatus = device.getRelayStatusByIndex(externalIndex); if (oldRelayStatus != null) { // Update the old relay status value - oldRelayStatus.updateLastKnownState(state, new Date()); + oldRelayStatus.updateLastKnownState(state, Instant.now()); } else { // Create a new relay status value final RelayStatus newRelayStatus = new RelayStatus.Builder(device, externalIndex) - .withLastKnownState(state, new Date()) + .withLastKnownState(state, Instant.now()) .build(); relayStatuses.add(newRelayStatus); } diff --git a/osgp/platform/osgp-adapter-domain-tariffswitching/src/main/java/org/opensmartgridplatform/adapter/domain/tariffswitching/application/services/ScheduleManagementService.java b/osgp/platform/osgp-adapter-domain-tariffswitching/src/main/java/org/opensmartgridplatform/adapter/domain/tariffswitching/application/services/ScheduleManagementService.java index ef9c0c02dae..8382b525525 100644 --- a/osgp/platform/osgp-adapter-domain-tariffswitching/src/main/java/org/opensmartgridplatform/adapter/domain/tariffswitching/application/services/ScheduleManagementService.java +++ b/osgp/platform/osgp-adapter-domain-tariffswitching/src/main/java/org/opensmartgridplatform/adapter/domain/tariffswitching/application/services/ScheduleManagementService.java @@ -83,7 +83,7 @@ public void setTariffSchedule( new RequestMessage(ids, scheduleDto), messageType, messagePriority, - device.getIpAddress(), + device.getNetworkAddress(), scheduleTime); } } diff --git a/osgp/platform/osgp-adapter-domain-tariffswitching/src/main/java/org/opensmartgridplatform/adapter/domain/tariffswitching/infra/jms/core/OsgpCoreRequestMessageSender.java b/osgp/platform/osgp-adapter-domain-tariffswitching/src/main/java/org/opensmartgridplatform/adapter/domain/tariffswitching/infra/jms/core/OsgpCoreRequestMessageSender.java index 9dce7f769a5..41734acef98 100644 --- a/osgp/platform/osgp-adapter-domain-tariffswitching/src/main/java/org/opensmartgridplatform/adapter/domain/tariffswitching/infra/jms/core/OsgpCoreRequestMessageSender.java +++ b/osgp/platform/osgp-adapter-domain-tariffswitching/src/main/java/org/opensmartgridplatform/adapter/domain/tariffswitching/infra/jms/core/OsgpCoreRequestMessageSender.java @@ -54,7 +54,7 @@ public Message createMessage(final Session session) throws JMSException { requestMessage.getOrganisationIdentification()); objectMessage.setStringProperty( Constants.DEVICE_IDENTIFICATION, requestMessage.getDeviceIdentification()); - objectMessage.setStringProperty(Constants.IP_ADDRESS, ipAddress); + objectMessage.setStringProperty(Constants.NETWORK_ADDRESS, ipAddress); if (scheduleTime != null) { objectMessage.setLongProperty(Constants.SCHEDULE_TIME, scheduleTime); } diff --git a/osgp/platform/osgp-adapter-kafka-distributionautomation/pom.xml b/osgp/platform/osgp-adapter-kafka-distributionautomation/pom.xml index a78d1d05d61..8a309a00bea 100644 --- a/osgp/platform/osgp-adapter-kafka-distributionautomation/pom.xml +++ b/osgp/platform/osgp-adapter-kafka-distributionautomation/pom.xml @@ -11,7 +11,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-platform - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-platform/pom.xml diff --git a/osgp/platform/osgp-adapter-kafka-logging/pom.xml b/osgp/platform/osgp-adapter-kafka-logging/pom.xml index d43bcd525d9..a495d885735 100644 --- a/osgp/platform/osgp-adapter-kafka-logging/pom.xml +++ b/osgp/platform/osgp-adapter-kafka-logging/pom.xml @@ -11,7 +11,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-platform - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-platform/pom.xml diff --git a/osgp/platform/osgp-adapter-ws-admin/pom.xml b/osgp/platform/osgp-adapter-ws-admin/pom.xml index f3d6be87b32..6c598dba7c6 100644 --- a/osgp/platform/osgp-adapter-ws-admin/pom.xml +++ b/osgp/platform/osgp-adapter-ws-admin/pom.xml @@ -18,7 +18,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-platform - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-platform/pom.xml diff --git a/osgp/platform/osgp-adapter-ws-admin/src/main/java/org/opensmartgridplatform/adapter/ws/admin/application/mapping/DeviceManagementMapper.java b/osgp/platform/osgp-adapter-ws-admin/src/main/java/org/opensmartgridplatform/adapter/ws/admin/application/mapping/DeviceManagementMapper.java index 2a31f4589bd..3ab618369f7 100644 --- a/osgp/platform/osgp-adapter-ws-admin/src/main/java/org/opensmartgridplatform/adapter/ws/admin/application/mapping/DeviceManagementMapper.java +++ b/osgp/platform/osgp-adapter-ws-admin/src/main/java/org/opensmartgridplatform/adapter/ws/admin/application/mapping/DeviceManagementMapper.java @@ -7,6 +7,7 @@ import ma.glasnost.orika.MapperFactory; import ma.glasnost.orika.impl.ConfigurableMapper; import org.opensmartgridplatform.shared.mappers.XMLGregorianCalendarToDateTimeConverter; +import org.opensmartgridplatform.shared.mappers.XMLGregorianCalendarToInstantConverter; import org.opensmartgridplatform.shared.mappers.XMLGregorianCalendarToZonedDateTimeConverter; import org.springframework.stereotype.Component; @@ -65,5 +66,8 @@ public void configure(final MapperFactory mapperFactory) { mapperFactory .getConverterFactory() .registerConverter(new XMLGregorianCalendarToZonedDateTimeConverter()); + mapperFactory + .getConverterFactory() + .registerConverter(new XMLGregorianCalendarToInstantConverter()); } } diff --git a/osgp/platform/osgp-adapter-ws-admin/src/main/java/org/opensmartgridplatform/adapter/ws/admin/application/services/DeviceManagementService.java b/osgp/platform/osgp-adapter-ws-admin/src/main/java/org/opensmartgridplatform/adapter/ws/admin/application/services/DeviceManagementService.java index 90d2728a1c0..4278a4cb2b7 100644 --- a/osgp/platform/osgp-adapter-ws-admin/src/main/java/org/opensmartgridplatform/adapter/ws/admin/application/services/DeviceManagementService.java +++ b/osgp/platform/osgp-adapter-ws-admin/src/main/java/org/opensmartgridplatform/adapter/ws/admin/application/services/DeviceManagementService.java @@ -4,8 +4,6 @@ package org.opensmartgridplatform.adapter.ws.admin.application.services; -import java.net.InetAddress; -import java.net.UnknownHostException; import java.util.List; import javax.persistence.EntityNotFoundException; import javax.persistence.PersistenceException; @@ -368,7 +366,7 @@ public Slice findDeviceMessages( final Organisation organisation = this.findOrganisation(organisationIdentification); this.isAllowed(organisation, PlatformFunction.GET_MESSAGES); - PageRequest pageRequest; + final PageRequest pageRequest; if (!StringUtils.isBlank(filter.getSortDirection()) && !StringUtils.isBlank(filter.getSortBy())) { pageRequest = @@ -660,7 +658,7 @@ public void updateDeviceProtocol( public Device updateCommunicationNetworkInformation( final String organisationIdentification, final String deviceIdentification, - final String ipAddress, + final String networkAddress, final Integer btsId, final Integer cellId) throws FunctionalException { @@ -670,29 +668,31 @@ public Device updateCommunicationNetworkInformation( this.isAllowed(organisation, device, DeviceFunction.SET_COMMUNICATION_NETWORK_INFORMATION); - if (ipAddress != null) { - try { - device.setNetworkAddress(InetAddress.getByName(ipAddress)); - } catch (final UnknownHostException e) { - LOGGER.error("Invalid ip address found {} for device {}", ipAddress, deviceIdentification); - throw new FunctionalException( - FunctionalExceptionType.INVALID_IP_ADDRESS, ComponentType.DOMAIN_SMART_METERING); - } + if (networkAddress != null) { + device.setNetworkAddress(networkAddress); } if (btsId != null) { device.setBtsId(btsId); + } else { + LOGGER.info( + "Bts id for device {} is not overwritten since no new value is found", + deviceIdentification); } if (cellId != null) { device.setCellId(cellId); + } else { + LOGGER.info( + "Cell id for device {} is not overwritten since no new value is found", + deviceIdentification); } final Device updatedDevice = this.deviceRepository.save(device); LOGGER.info( "CommunicationNetworkInformation for Device {} updated to : ipAddress={}, btsId={}, cellId={} ", deviceIdentification, - updatedDevice.getIpAddress(), + updatedDevice.getNetworkAddress(), updatedDevice.getBtsId(), updatedDevice.getCellId()); @@ -719,7 +719,7 @@ private ProtocolInfo findProtocolInfo( private Organisation findOrganisation(final String organisationIdentification) throws FunctionalException { - Organisation organisation; + final Organisation organisation; try { organisation = this.organisationDomainService.searchOrganisation(organisationIdentification); } catch (final UnknownEntityException e) { diff --git a/osgp/platform/osgp-adapter-ws-admin/src/main/java/org/opensmartgridplatform/adapter/ws/admin/endpoints/DeviceManagementEndpoint.java b/osgp/platform/osgp-adapter-ws-admin/src/main/java/org/opensmartgridplatform/adapter/ws/admin/endpoints/DeviceManagementEndpoint.java index 52c8525c886..32b66a15e1f 100644 --- a/osgp/platform/osgp-adapter-ws-admin/src/main/java/org/opensmartgridplatform/adapter/ws/admin/endpoints/DeviceManagementEndpoint.java +++ b/osgp/platform/osgp-adapter-ws-admin/src/main/java/org/opensmartgridplatform/adapter/ws/admin/endpoints/DeviceManagementEndpoint.java @@ -597,7 +597,7 @@ public SetCommunicationNetworkInformationResponse setCommunicationNetworkInforma request.getCellId()); response.setResult(OsgpResultType.OK); - response.setIpAddress(updatedDevice.getIpAddress()); + response.setIpAddress(updatedDevice.getNetworkAddress()); response.setBtsId(updatedDevice.getBtsId()); response.setCellId(updatedDevice.getCellId()); diff --git a/osgp/platform/osgp-adapter-ws-admin/src/main/java/org/opensmartgridplatform/adapter/ws/admin/infra/specifications/JpaDeviceLogItemSpecifications.java b/osgp/platform/osgp-adapter-ws-admin/src/main/java/org/opensmartgridplatform/adapter/ws/admin/infra/specifications/JpaDeviceLogItemSpecifications.java index 5f5b83d8a17..f59521398b6 100644 --- a/osgp/platform/osgp-adapter-ws-admin/src/main/java/org/opensmartgridplatform/adapter/ws/admin/infra/specifications/JpaDeviceLogItemSpecifications.java +++ b/osgp/platform/osgp-adapter-ws-admin/src/main/java/org/opensmartgridplatform/adapter/ws/admin/infra/specifications/JpaDeviceLogItemSpecifications.java @@ -6,8 +6,8 @@ import static org.opensmartgridplatform.shared.utils.SearchUtil.replaceAndEscapeWildcards; +import java.time.Instant; import java.time.ZonedDateTime; -import java.util.Date; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Root; @@ -56,7 +56,7 @@ public Specification hasStartDate(final ZonedDateTime startDate) return ALL; } else { return (final Root r, final CriteriaQuery q, final CriteriaBuilder cb) -> - cb.greaterThanOrEqualTo(r.get(MODIFICATION_TIME), Date.from(startDate.toInstant())); + cb.greaterThanOrEqualTo(r.get(MODIFICATION_TIME), startDate.toInstant()); } } @@ -66,7 +66,7 @@ public Specification hasEndDate(final ZonedDateTime endDate) { return ALL; } else { return (final Root r, final CriteriaQuery q, final CriteriaBuilder cb) -> - cb.lessThanOrEqualTo(r.get(MODIFICATION_TIME), Date.from(endDate.toInstant())); + cb.lessThanOrEqualTo(r.get(MODIFICATION_TIME), endDate.toInstant()); } } } diff --git a/osgp/platform/osgp-adapter-ws-core/pom.xml b/osgp/platform/osgp-adapter-ws-core/pom.xml index be40f49af0f..0289fbbfe0a 100644 --- a/osgp/platform/osgp-adapter-ws-core/pom.xml +++ b/osgp/platform/osgp-adapter-ws-core/pom.xml @@ -18,7 +18,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-platform - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-platform/pom.xml diff --git a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/config/ApplicationContext.java b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/config/ApplicationContext.java index 33bac0aec38..eedfaa7a724 100644 --- a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/config/ApplicationContext.java +++ b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/config/ApplicationContext.java @@ -4,9 +4,8 @@ package org.opensmartgridplatform.adapter.ws.core.application.config; -import org.joda.time.DateTime; -import org.joda.time.DateTimeConstants; -import org.joda.time.DateTimeZone; +import java.time.Instant; +import java.time.ZoneId; import org.opensmartgridplatform.adapter.ws.infra.specifications.JpaDeviceSpecifications; import org.opensmartgridplatform.adapter.ws.infra.specifications.JpaEventSpecifications; import org.opensmartgridplatform.adapter.ws.shared.db.application.config.WritablePersistenceConfigCore; @@ -66,11 +65,13 @@ public class ApplicationContext extends AbstractConfig { private static final String PROPERTY_NAME_PAGING_DEFAULT_PAGE_SIZE = "paging.default.pagesize"; private static final String LOCAL_TIME_ZONE_IDENTIFIER = "Europe/Paris"; - private static final DateTimeZone LOCAL_TIME_ZONE = - DateTimeZone.forID(LOCAL_TIME_ZONE_IDENTIFIER); + private static final ZoneId LOCAL_TIME_ZONE = ZoneId.of(LOCAL_TIME_ZONE_IDENTIFIER); + + public static final int SECONDS_PER_MINUTE = 60; + private static final int TIME_ZONE_OFFSET_MINUTES = - LOCAL_TIME_ZONE.getStandardOffset(new DateTime().getMillis()) - / DateTimeConstants.MILLIS_PER_MINUTE; + LOCAL_TIME_ZONE.getRules().getStandardOffset(Instant.now()).getTotalSeconds() + / SECONDS_PER_MINUTE; private static final String PROPERTY_NAME_NET_MANAGEMENT_ORGANISATION = "net.management.organisation"; @@ -159,7 +160,7 @@ public String localTimeZoneIdentifier() { } @Bean - public DateTimeZone localTimeZone() { + public ZoneId localTimeZone() { return LOCAL_TIME_ZONE; } diff --git a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/criteria/SearchEventsCriteria.java b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/criteria/SearchEventsCriteria.java index f96b5afe1fb..f4044e61e98 100644 --- a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/criteria/SearchEventsCriteria.java +++ b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/criteria/SearchEventsCriteria.java @@ -4,11 +4,11 @@ package org.opensmartgridplatform.adapter.ws.core.application.criteria; +import java.time.ZonedDateTime; import java.util.List; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; -import org.joda.time.DateTime; import org.opensmartgridplatform.domain.core.valueobjects.EventType; import org.opensmartgridplatform.shared.application.config.PageSpecifier; @@ -20,8 +20,8 @@ public class SearchEventsCriteria { private final String organisationIdentification; private final String deviceIdentification; private final PageSpecifier pageSpecifier; - private final DateTime from; - private final DateTime until; + private final ZonedDateTime from; + private final ZonedDateTime until; private final List eventTypes; private final String description; private final String descriptionStartsWith; diff --git a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/ConfigurationConverter.java b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/ConfigurationConverter.java index 25d450c9898..99b33c430bf 100644 --- a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/ConfigurationConverter.java +++ b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/ConfigurationConverter.java @@ -4,10 +4,10 @@ package org.opensmartgridplatform.adapter.ws.core.application.mapping; +import java.time.ZonedDateTime; import ma.glasnost.orika.CustomConverter; import ma.glasnost.orika.MappingContext; import ma.glasnost.orika.metadata.Type; -import org.joda.time.DateTime; import org.opensmartgridplatform.adapter.ws.schema.core.configurationmanagement.Configuration; import org.opensmartgridplatform.domain.core.valueobjects.DaliConfiguration; import org.opensmartgridplatform.domain.core.valueobjects.DeviceFixedIp; @@ -51,8 +51,10 @@ public org.opensmartgridplatform.domain.core.valueobjects.Configuration convert( .withSwitchingDelays(source.getSwitchingDelays()) .withRelayLinking(this.mapperFacade.mapAsList(source.getRelayLinking(), RelayMatrix.class)) .withRelayRefreshing(source.isRelayRefreshing()) - .withSummerTimeDetails(this.mapperFacade.map(source.getSummerTimeDetails(), DateTime.class)) - .withWinterTimeDetails(this.mapperFacade.map(source.getWinterTimeDetails(), DateTime.class)) + .withSummerTimeDetails( + this.mapperFacade.map(source.getSummerTimeDetails(), ZonedDateTime.class)) + .withWinterTimeDetails( + this.mapperFacade.map(source.getWinterTimeDetails(), ZonedDateTime.class)) .build(); } } diff --git a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/ConfigurationManagementMapper.java b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/ConfigurationManagementMapper.java index fd66de3e2ce..61cfa163f93 100644 --- a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/ConfigurationManagementMapper.java +++ b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/ConfigurationManagementMapper.java @@ -8,6 +8,7 @@ import ma.glasnost.orika.impl.ConfigurableMapper; import org.opensmartgridplatform.adapter.ws.core.application.mapping.ws.DaliConfigurationConverter; import org.opensmartgridplatform.shared.mappers.XMLGregorianCalendarToDateTimeConverter; +import org.opensmartgridplatform.shared.mappers.XMLGregorianCalendarToZonedDateTimeConverter; import org.springframework.stereotype.Component; @Component(value = "coreConfigurationManagementMapper") @@ -15,9 +16,13 @@ public class ConfigurationManagementMapper extends ConfigurableMapper { @Override public void configure(final MapperFactory mapperFactory) { mapperFactory.getConverterFactory().registerConverter(new DaliConfigurationConverter()); + // TODO remove after refactor of FDP-1558 mapperFactory .getConverterFactory() .registerConverter(new XMLGregorianCalendarToDateTimeConverter()); + mapperFactory + .getConverterFactory() + .registerConverter(new XMLGregorianCalendarToZonedDateTimeConverter()); mapperFactory.getConverterFactory().registerConverter(new ConfigurationConverter()); } } diff --git a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/DeviceConverterHelper.java b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/DeviceConverterHelper.java index ab5eaa69a5e..49b72afb051 100644 --- a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/DeviceConverterHelper.java +++ b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/DeviceConverterHelper.java @@ -35,7 +35,7 @@ public void setMapperFacade(final MapperFacade mapper) { @SuppressWarnings("unchecked") T initEntity(final Device source) { - T destination; + final T destination; final Address containerAddress = this.mapper.map(source.getContainerAddress(), Address.class); @@ -74,11 +74,11 @@ T initEntity(final Device source) { DeviceLifecycleStatus.valueOf(source.getDeviceLifecycleStatus().name())); } - destination.updateRegistrationData(destination.getNetworkAddress(), source.getDeviceType()); + destination.updateRegistrationData(source.getNetworkAddress(), source.getDeviceType()); if (source.getTechnicalInstallationDate() != null) { destination.setTechnicalInstallationDate( - source.getTechnicalInstallationDate().toGregorianCalendar().getTime()); + source.getTechnicalInstallationDate().toGregorianCalendar().toInstant()); } destination.setDeviceModel( @@ -119,8 +119,7 @@ Device initJaxb(final T source) { } } - destination.setNetworkAddress( - source.getNetworkAddress() == null ? null : source.getNetworkAddress().toString()); + destination.setNetworkAddress(source.getNetworkAddress()); destination.setOwner(source.getOwner() == null ? "" : source.getOwner().getName()); destination.getOrganisations().addAll(source.getOrganisations()); diff --git a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/DeviceFirmwareConverter.java b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/DeviceFirmwareConverter.java index 017984f68a8..bfb0cdcf2cc 100644 --- a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/DeviceFirmwareConverter.java +++ b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/DeviceFirmwareConverter.java @@ -4,6 +4,7 @@ package org.opensmartgridplatform.adapter.ws.core.application.mapping; +import java.util.Date; import java.util.GregorianCalendar; import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeFactory; @@ -52,7 +53,7 @@ public DeviceFirmwareFile convertTo( return new DeviceFirmwareFile( device, firmwareFile, - source.getInstallationDate().toGregorianCalendar().getTime(), + source.getInstallationDate().toGregorianCalendar().toInstant(), source.getInstalledBy()); } @@ -69,7 +70,7 @@ public DeviceFirmware convertFrom( destination.setFirmware(firmware); final GregorianCalendar gCalendar = new GregorianCalendar(); - gCalendar.setTime(source.getInstallationDate()); + gCalendar.setTime(Date.from(source.getInstallationDate())); try { destination.setInstallationDate( diff --git a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/DeviceManagementMapper.java b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/DeviceManagementMapper.java index acd8ecda324..515d9cbe1c0 100644 --- a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/DeviceManagementMapper.java +++ b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/DeviceManagementMapper.java @@ -43,7 +43,6 @@ public void configure(final MapperFactory mapperFactory) { .classMap( org.opensmartgridplatform.domain.core.entities.Device.class, org.opensmartgridplatform.adapter.ws.schema.core.devicemanagement.Device.class) - .field("ipAddress", "networkAddress") .byDefault() .toClassMap()); diff --git a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/FirmwareConverter.java b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/FirmwareConverter.java index 7f19a27b718..c47a5ecdb1a 100644 --- a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/FirmwareConverter.java +++ b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/FirmwareConverter.java @@ -4,6 +4,7 @@ package org.opensmartgridplatform.adapter.ws.core.application.mapping; +import java.util.Date; import java.util.GregorianCalendar; import java.util.Map; import java.util.Map.Entry; @@ -97,7 +98,7 @@ public org.opensmartgridplatform.adapter.ws.schema.core.firmwaremanagement.Firmw output.setFirmwareModuleData(firmwareModuleData); final GregorianCalendar gCalendar = new GregorianCalendar(); - gCalendar.setTime(source.getCreationTime()); + gCalendar.setTime(Date.from(source.getCreationTime())); try { output.setCreationTime(DatatypeFactory.newInstance().newXMLGregorianCalendar(gCalendar)); diff --git a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/services/ConfigurationManagementService.java b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/services/ConfigurationManagementService.java index 1b487164e6c..70e65a6ed2c 100644 --- a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/services/ConfigurationManagementService.java +++ b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/services/ConfigurationManagementService.java @@ -4,8 +4,8 @@ package org.opensmartgridplatform.adapter.ws.core.application.services; +import java.time.ZonedDateTime; import javax.validation.Valid; -import org.joda.time.DateTime; import org.opensmartgridplatform.adapter.ws.core.infra.jms.CommonRequestMessage; import org.opensmartgridplatform.adapter.ws.core.infra.jms.CommonRequestMessageSender; import org.opensmartgridplatform.domain.core.entities.Device; @@ -46,7 +46,7 @@ public String enqueueSetConfigurationRequest( @Identification final String organisationIdentification, @Identification final String deviceIdentification, @Valid final Configuration configuration, - final DateTime scheduledTime, + final ZonedDateTime scheduledTime, final int messagePriority) throws FunctionalException { @@ -73,7 +73,8 @@ public String enqueueSetConfigurationRequest( .withCorrelationUid(correlationUid) .withMessageType(MessageType.SET_CONFIGURATION.name()) .withMessagePriority(messagePriority) - .withScheduleTime(scheduledTime == null ? null : scheduledTime.getMillis()) + .withScheduleTime( + scheduledTime == null ? null : scheduledTime.toInstant().toEpochMilli()) .build(); final CommonRequestMessage message = diff --git a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/services/DeviceInstallationService.java b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/services/DeviceInstallationService.java index d3f7bb48067..d3bec4ce732 100644 --- a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/services/DeviceInstallationService.java +++ b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/services/DeviceInstallationService.java @@ -4,11 +4,11 @@ package org.opensmartgridplatform.adapter.ws.core.application.services; -import java.util.Date; +import java.time.Instant; +import java.time.ZonedDateTime; import java.util.List; import javax.validation.Valid; import org.apache.commons.lang3.StringUtils; -import org.joda.time.DateMidnight; import org.opensmartgridplatform.adapter.ws.core.infra.jms.CommonRequestMessage; import org.opensmartgridplatform.adapter.ws.core.infra.jms.CommonRequestMessageSender; import org.opensmartgridplatform.adapter.ws.shared.db.domain.repositories.writable.WritableDeviceAuthorizationRepository; @@ -319,7 +319,14 @@ public List findRecentDevices(@Identification final String organisationI final Organisation organisation = this.domainHelperService.findOrganisation(organisationIdentification); - final Date fromDate = new DateMidnight().minusDays(this.recentDevicesPeriod).toDate(); + final Instant fromDate = + ZonedDateTime.now() + .withHour(0) + .withMinute(0) + .withSecond(0) + .withNano(0) + .minusDays(this.recentDevicesPeriod) + .toInstant(); return this.deviceRepository.findRecentDevices(organisation, fromDate); } diff --git a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/services/DeviceManagementService.java b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/services/DeviceManagementService.java index dc86e075fad..3b7cdb32050 100644 --- a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/services/DeviceManagementService.java +++ b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/services/DeviceManagementService.java @@ -7,12 +7,12 @@ import static org.opensmartgridplatform.shared.utils.SearchUtil.replaceAndEscapeWildcards; import static org.springframework.data.jpa.domain.Specification.where; +import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.List; import javax.validation.Valid; import org.apache.commons.lang3.StringUtils; import org.hibernate.QueryException; -import org.joda.time.DateTime; import org.opensmartgridplatform.adapter.ws.core.application.criteria.SearchEventsCriteria; import org.opensmartgridplatform.adapter.ws.core.infra.jms.CommonRequestMessage; import org.opensmartgridplatform.adapter.ws.core.infra.jms.CommonRequestMessageSender; @@ -195,14 +195,15 @@ public Page findEvents(final SearchEventsCriteria criteria) throws Functi specification = where(this.eventSpecifications.isAuthorized(organisation)); } - final DateTime from = criteria.getFrom(); + final ZonedDateTime from = criteria.getFrom(); if (from != null) { - specification = specification.and(this.eventSpecifications.isCreatedAfter(from.toDate())); + specification = specification.and(this.eventSpecifications.isCreatedAfter(from.toInstant())); } - final DateTime until = criteria.getUntil(); + final ZonedDateTime until = criteria.getUntil(); if (until != null) { - specification = specification.and(this.eventSpecifications.isCreatedBefore(until.toDate())); + specification = + specification.and(this.eventSpecifications.isCreatedBefore(until.toInstant())); } specification = diff --git a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/services/FirmwareManagementService.java b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/services/FirmwareManagementService.java index ea6ec694a42..cadf23a8d96 100644 --- a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/services/FirmwareManagementService.java +++ b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/services/FirmwareManagementService.java @@ -10,6 +10,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.nio.file.Files; +import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -18,7 +19,6 @@ import javax.annotation.Resource; import javax.validation.Valid; import org.apache.commons.lang3.StringUtils; -import org.joda.time.DateTime; import org.opensmartgridplatform.adapter.ws.core.infra.jms.CommonRequestMessage; import org.opensmartgridplatform.adapter.ws.core.infra.jms.CommonRequestMessageSender; import org.opensmartgridplatform.adapter.ws.schema.core.firmwaremanagement.ChangeableFirmware; @@ -96,7 +96,7 @@ public String enqueueUpdateFirmwareRequest( @Identification final String organisationIdentification, @Identification final String deviceIdentification, final FirmwareUpdateMessageDataContainer firmwareUpdateMessageDataContainer, - final DateTime scheduledTime, + final ZonedDateTime scheduledTime, final int messagePriority) throws FunctionalException { LOGGER.debug("Queue update firmware request"); @@ -124,7 +124,8 @@ public String enqueueUpdateFirmwareRequest( .withCorrelationUid(correlationUid) .withMessageType(MessageType.UPDATE_FIRMWARE.name()) .withMessagePriority(messagePriority) - .withScheduleTime(scheduledTime == null ? null : scheduledTime.getMillis()) + .withScheduleTime( + scheduledTime == null ? null : scheduledTime.toInstant().toEpochMilli()) .build(); final CommonRequestMessage message = @@ -210,7 +211,7 @@ public void addManufacturer( this.domainHelperService.isAllowed(organisation, PlatformFunction.CREATE_MANUFACTURER); final Manufacturer databaseManufacturer = - this.manufacturerRepository.findByCode(manufacturer.getCode()); + this.manufacturerRepository.findByCodeIgnoreCase(manufacturer.getCode()); if (databaseManufacturer != null) { LOGGER.info("Manufacturer already exists."); @@ -237,7 +238,7 @@ public void changeManufacturer( this.domainHelperService.isAllowed(organisation, PlatformFunction.CHANGE_MANUFACTURER); final Manufacturer databaseManufacturer = - this.manufacturerRepository.findByCode(manufacturer.getCode()); + this.manufacturerRepository.findByCodeIgnoreCase(manufacturer.getCode()); if (databaseManufacturer == null) { LOGGER.info("Manufacturer not found."); @@ -268,7 +269,7 @@ public void removeManufacturer( this.domainHelperService.isAllowed(organisation, PlatformFunction.REMOVE_MANUFACTURER); final Manufacturer databaseManufacturer = - this.manufacturerRepository.findByCode(manufacturerCode); + this.manufacturerRepository.findByCodeIgnoreCase(manufacturerCode); final List deviceModels = this.deviceModelRepository.findByManufacturer(databaseManufacturer); @@ -377,7 +378,8 @@ public void addDeviceModel( final Manufacturer manufacturer = this.findManufacturerByCode(manufacturerCode); final DeviceModel savedDeviceModel = - this.deviceModelRepository.findByManufacturerAndModelCode(manufacturer, modelCode); + this.deviceModelRepository.findByManufacturerAndModelCodeIgnoreCase( + manufacturer, modelCode); if (savedDeviceModel != null) { LOGGER.info("DeviceModel already exists."); @@ -406,9 +408,11 @@ public void removeDeviceModel( this.domainHelperService.findOrganisation(organisationIdentification); this.domainHelperService.isAllowed(organisation, PlatformFunction.REMOVE_DEVICE_MODEL); - final Manufacturer databaseManufacturer = this.manufacturerRepository.findByCode(manufacturer); + final Manufacturer databaseManufacturer = + this.manufacturerRepository.findByCodeIgnoreCase(manufacturer); final DeviceModel removedDeviceModel = - this.deviceModelRepository.findByManufacturerAndModelCode(databaseManufacturer, modelCode); + this.deviceModelRepository.findByManufacturerAndModelCodeIgnoreCase( + databaseManufacturer, modelCode); if (removedDeviceModel == null) { LOGGER.info("DeviceModel not found."); @@ -453,9 +457,11 @@ public void changeDeviceModel( this.domainHelperService.findOrganisation(organisationIdentification); this.domainHelperService.isAllowed(organisation, PlatformFunction.CHANGE_DEVICE_MODEL); - final Manufacturer databaseManufacturer = this.manufacturerRepository.findByCode(manufacturer); + final Manufacturer databaseManufacturer = + this.manufacturerRepository.findByCodeIgnoreCase(manufacturer); final DeviceModel changedDeviceModel = - this.deviceModelRepository.findByManufacturerAndModelCode(databaseManufacturer, modelCode); + this.deviceModelRepository.findByManufacturerAndModelCodeIgnoreCase( + databaseManufacturer, modelCode); if (changedDeviceModel == null) { LOGGER.info("DeviceModel not found."); @@ -505,9 +511,11 @@ private List getFirmwareFiles( return new ArrayList<>(); } - final Manufacturer manufacturer = this.manufacturerRepository.findByCode(manufacturerCode); + final Manufacturer manufacturer = + this.manufacturerRepository.findByCodeIgnoreCase(manufacturerCode); final DeviceModel deviceModel = - this.deviceModelRepository.findByManufacturerAndModelCode(manufacturer, modelCode); + this.deviceModelRepository.findByManufacturerAndModelCodeIgnoreCase( + manufacturer, modelCode); if (deviceModel == null) { return new ArrayList<>(); @@ -588,7 +596,8 @@ public void addFirmware( final Manufacturer databaseManufacturer = this.findManufacturerByCode(manufacturer); final DeviceModel databaseDeviceModel = - this.deviceModelRepository.findByManufacturerAndModelCode(databaseManufacturer, modelCode); + this.deviceModelRepository.findByManufacturerAndModelCodeIgnoreCase( + databaseManufacturer, modelCode); if (databaseDeviceModel == null) { LOGGER.info("DeviceModel doesn't exist."); @@ -654,7 +663,8 @@ public void addFirmware( private Manufacturer findManufacturerByCode(final String manufacturer) throws FunctionalException { - final Manufacturer databaseManufacturer = this.manufacturerRepository.findByCode(manufacturer); + final Manufacturer databaseManufacturer = + this.manufacturerRepository.findByCodeIgnoreCase(manufacturer); if (databaseManufacturer == null) { LOGGER.info("Manufacturer doesn't exist."); @@ -694,7 +704,7 @@ public void addOrChangeFirmware( this.findManufacturerByCode(deviceModel.getManufacturer()); final DeviceModel databaseDeviceModel = - this.deviceModelRepository.findByManufacturerAndModelCode( + this.deviceModelRepository.findByManufacturerAndModelCodeIgnoreCase( databaseManufacturer, deviceModel.getModelCode()); if (databaseDeviceModel == null) { diff --git a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/services/ResponseUrlDataCleanupService.java b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/services/ResponseUrlDataCleanupService.java index beb462a90cc..47920bd35cf 100644 --- a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/services/ResponseUrlDataCleanupService.java +++ b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/application/services/ResponseUrlDataCleanupService.java @@ -4,8 +4,8 @@ package org.opensmartgridplatform.adapter.ws.core.application.services; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; +import java.time.ZoneId; +import java.time.ZonedDateTime; import org.opensmartgridplatform.adapter.ws.domain.repositories.ResponseUrlDataRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -21,8 +21,8 @@ public class ResponseUrlDataCleanupService { public void execute() { - final DateTime removeBeforeDateTime = - DateTime.now(DateTimeZone.UTC).minusDays(this.cleanupJobRetentionTimeInDays); - this.responseUrlDataRepository.removeByCreationTimeBefore(removeBeforeDateTime.toDate()); + final ZonedDateTime removeBeforeDateTime = + ZonedDateTime.now(ZoneId.of("UTC")).minusDays(this.cleanupJobRetentionTimeInDays); + this.responseUrlDataRepository.removeByCreationTimeBefore(removeBeforeDateTime.toInstant()); } } diff --git a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/endpoints/ConfigurationManagementEndpoint.java b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/endpoints/ConfigurationManagementEndpoint.java index f88e45c31bb..826ac90d114 100644 --- a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/endpoints/ConfigurationManagementEndpoint.java +++ b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/endpoints/ConfigurationManagementEndpoint.java @@ -4,9 +4,9 @@ package org.opensmartgridplatform.adapter.ws.core.endpoints; +import java.time.ZoneId; +import java.time.ZonedDateTime; import javax.validation.ConstraintViolationException; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; import org.opensmartgridplatform.adapter.ws.core.application.mapping.ConfigurationManagementMapper; import org.opensmartgridplatform.adapter.ws.core.application.services.ConfigurationManagementService; import org.opensmartgridplatform.adapter.ws.endpointinterceptors.MessagePriority; @@ -87,11 +87,14 @@ public SetConfigurationAsyncResponse setConfiguration( // Get the request parameters, make sure that they are in UTC. // Maybe add an adapter to the service, so that all date-time are // converted to UTC automatically. - final DateTime scheduleTime = + final ZonedDateTime scheduleTime = request.getScheduledTime() == null ? null - : new DateTime(request.getScheduledTime().toGregorianCalendar()) - .toDateTime(DateTimeZone.UTC); + : request + .getScheduledTime() + .toGregorianCalendar() + .toZonedDateTime() + .withZoneSameInstant(ZoneId.of("UTC")); final Configuration configuration = this.configurationManagementMapper.map(request.getConfiguration(), Configuration.class); diff --git a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/endpoints/DeviceManagementEndpoint.java b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/endpoints/DeviceManagementEndpoint.java index c606cc47187..3b7f6c558f3 100644 --- a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/endpoints/DeviceManagementEndpoint.java +++ b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/endpoints/DeviceManagementEndpoint.java @@ -4,11 +4,11 @@ package org.opensmartgridplatform.adapter.ws.core.endpoints; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.List; import javax.validation.ConstraintViolationException; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; import org.opensmartgridplatform.adapter.ws.core.application.criteria.SearchEventsCriteria; import org.opensmartgridplatform.adapter.ws.core.application.mapping.DeviceManagementMapper; import org.opensmartgridplatform.adapter.ws.core.application.services.DeviceManagementService; @@ -71,6 +71,7 @@ import org.opensmartgridplatform.shared.exceptionhandling.FunctionalExceptionType; import org.opensmartgridplatform.shared.exceptionhandling.OsgpException; import org.opensmartgridplatform.shared.infra.jms.ResponseMessage; +import org.opensmartgridplatform.shared.utils.JavaTimeHelpers; import org.opensmartgridplatform.shared.wsheaderattribute.priority.MessagePriorityEnum; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -263,14 +264,16 @@ public FindEventsResponse findEventsRequest( // Get the request parameters, make sure that they are in UTC. // Maybe add an adapter to the service, so that all datetime are // converted to utc automatically. - final DateTime from = + final ZonedDateTime from = request.getFrom() == null ? null - : new DateTime(request.getFrom().toGregorianCalendar()).toDateTime(DateTimeZone.UTC); - final DateTime until = + : JavaTimeHelpers.gregorianCalendarToZonedDateTime( + request.getFrom().toGregorianCalendar(), ZoneId.of("UTC")); + final ZonedDateTime until = request.getUntil() == null ? null - : new DateTime(request.getUntil().toGregorianCalendar()).toDateTime(DateTimeZone.UTC); + : JavaTimeHelpers.gregorianCalendarToZonedDateTime( + request.getUntil().toGregorianCalendar(), ZoneId.of("UTC")); // Get all events matching the request. final SearchEventsCriteria criteria = diff --git a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/endpoints/FirmwareManagementEndpoint.java b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/endpoints/FirmwareManagementEndpoint.java index 6acde5c0a0a..31c2a5f16f2 100644 --- a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/endpoints/FirmwareManagementEndpoint.java +++ b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/endpoints/FirmwareManagementEndpoint.java @@ -4,11 +4,11 @@ package org.opensmartgridplatform.adapter.ws.core.endpoints; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.List; import javax.validation.ConstraintViolationException; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; import org.opensmartgridplatform.adapter.ws.core.application.mapping.FirmwareManagementMapper; import org.opensmartgridplatform.adapter.ws.core.application.services.FirmwareFileRequest; import org.opensmartgridplatform.adapter.ws.core.application.services.FirmwareManagementService; @@ -148,11 +148,14 @@ public UpdateFirmwareAsyncResponse updateFirmware( // Get the request parameters, make sure that they are in UTC. // Maybe add an adapter to the service, so that all datetime are // converted to utc automatically. - final DateTime scheduleTime = + final ZonedDateTime scheduleTime = request.getScheduledTime() == null ? null - : new DateTime(request.getScheduledTime().toGregorianCalendar()) - .toDateTime(DateTimeZone.UTC); + : request + .getScheduledTime() + .toGregorianCalendar() + .toZonedDateTime() + .withZoneSameInstant(ZoneId.of("UTC")); final String correlationUid = this.firmwareManagementService.enqueueUpdateFirmwareRequest( @@ -852,23 +855,25 @@ public AddFirmwareResponse addFirmware( @RequestPayload final AddFirmwareRequest request) throws OsgpException { - LOGGER.info("Adding firmware:{}.", request.getFirmware().getFilename()); + final Firmware firmware = request.getFirmware(); + + LOGGER.info("Adding firmware:{}.", firmware.getFilename()); final AddFirmwareResponse addFirmwareResponse = new AddFirmwareResponse(); try { final FirmwareModuleData firmwareModuleData = this.firmwareManagementMapper.map( - request.getFirmware().getFirmwareModuleData(), FirmwareModuleData.class); + firmware.getFirmwareModuleData(), FirmwareModuleData.class); // The AddFirmwareRequest accepts multiple DeviceModels to be related to a Firmware. // This FirmwareManagementService only accepts ONE for now - final String manufacturer = this.getManufacturerFromFirmware(request.getFirmware()); - final String modelCode = this.getModelCodeFromFirmware(request.getFirmware()); + final String manufacturer = this.getManufacturerFromFirmware(firmware); + final String modelCode = this.getModelCodeFromFirmware(firmware); this.firmwareManagementService.addFirmware( organisationIdentification, - this.firmwareFileRequestFor(request.getFirmware()), - request.getFirmware().getFile(), + this.firmwareFileRequestFor(firmware), + firmware.getFile(), manufacturer, modelCode, firmwareModuleData); @@ -887,7 +892,7 @@ public AddFirmwareResponse addFirmware( LOGGER.error( "Exception: {} while adding firmware: {} for organisation {}", e.getMessage(), - request.getFirmware().getFilename(), + firmware.getFilename(), organisationIdentification, e); this.handleException(e); @@ -914,10 +919,11 @@ public ChangeFirmwareResponse changeFirmware( @OrganisationIdentification final String organisationIdentification, @RequestPayload final ChangeFirmwareRequest request) throws OsgpException { + final Firmware firmware = request.getFirmware(); final FirmwareModuleData firmwareModuleData = this.firmwareManagementMapper.map( - request.getFirmware().getFirmwareModuleData(), FirmwareModuleData.class); + firmware.getFirmwareModuleData(), FirmwareModuleData.class); try { this.firmwareManagementService.changeFirmware( @@ -948,19 +954,21 @@ public AddOrChangeFirmwareResponse addOrChangeFirmware( @RequestPayload final AddOrChangeFirmwareRequest request) throws OsgpException { - LOGGER.info("Adding Or changing firmware:{}.", request.getFirmware().getFilename()); + final Firmware firmware = request.getFirmware(); + + LOGGER.info("Adding Or changing firmware:{}.", firmware.getFilename()); final AddOrChangeFirmwareResponse addOrChangeFirmwareResponse = new AddOrChangeFirmwareResponse(); try { final FirmwareModuleData firmwareModuleData = this.firmwareManagementMapper.map( - request.getFirmware().getFirmwareModuleData(), FirmwareModuleData.class); + firmware.getFirmwareModuleData(), FirmwareModuleData.class); final List deviceModels = new ArrayList<>(); for (final org.opensmartgridplatform.adapter.ws.schema.core.firmwaremanagement.DeviceModel - wsDeviceModel : request.getFirmware().getDeviceModels()) { + wsDeviceModel : firmware.getDeviceModels()) { final org.opensmartgridplatform.domain.core.valueobjects.DeviceModel deviceModel = this.firmwareManagementMapper.map( wsDeviceModel, @@ -970,8 +978,8 @@ public AddOrChangeFirmwareResponse addOrChangeFirmware( this.firmwareManagementService.addOrChangeFirmware( organisationIdentification, - this.firmwareFileRequestFor(request.getFirmware()), - request.getFirmware().getFile(), + this.firmwareFileRequestFor(firmware), + firmware.getFile(), deviceModels, firmwareModuleData); } catch (final ConstraintViolationException e) { @@ -989,7 +997,7 @@ public AddOrChangeFirmwareResponse addOrChangeFirmware( LOGGER.error( "Exception: {} while adding or changing firmware: {} for organisation {}", e.getMessage(), - request.getFirmware().getFilename(), + firmware.getFilename(), organisationIdentification, e); this.handleException(e); diff --git a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/infra/jms/CommonRequestMessage.java b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/infra/jms/CommonRequestMessage.java index 998ec64f5db..d6680af39a3 100644 --- a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/infra/jms/CommonRequestMessage.java +++ b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/infra/jms/CommonRequestMessage.java @@ -5,7 +5,9 @@ package org.opensmartgridplatform.adapter.ws.core.infra.jms; import java.io.Serializable; -import org.joda.time.DateTime; +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; import org.opensmartgridplatform.shared.infra.jms.MessageMetadata; import org.opensmartgridplatform.shared.infra.jms.MessageType; import org.opensmartgridplatform.shared.infra.jms.RequestMessage; @@ -15,7 +17,7 @@ public class CommonRequestMessage extends RequestMessage { private static final long serialVersionUID = 6094774737635965756L; private final MessageType messageType; - private final DateTime scheduleTime; + private final ZonedDateTime scheduleTime; private final Integer messagePriority; private CommonRequestMessage( @@ -33,7 +35,9 @@ private CommonRequestMessage( if (messageMetadata.getScheduleTime() == null) { this.scheduleTime = null; } else { - this.scheduleTime = new DateTime(messageMetadata.getScheduleTime()); + this.scheduleTime = + ZonedDateTime.ofInstant( + Instant.ofEpochMilli(messageMetadata.getScheduleTime()), ZoneId.systemDefault()); } } @@ -41,7 +45,7 @@ public MessageType getMessageType() { return this.messageType; } - public DateTime getScheduleTime() { + public ZonedDateTime getScheduleTime() { return this.scheduleTime; } diff --git a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/infra/jms/CommonRequestMessageSender.java b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/infra/jms/CommonRequestMessageSender.java index 56f74dc49a7..1948779d0e6 100644 --- a/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/infra/jms/CommonRequestMessageSender.java +++ b/osgp/platform/osgp-adapter-ws-core/src/main/java/org/opensmartgridplatform/adapter/ws/core/infra/jms/CommonRequestMessageSender.java @@ -81,7 +81,8 @@ public Message createMessage(final Session session) throws JMSException { Constants.DEVICE_IDENTIFICATION, requestMessage.getDeviceIdentification()); if (requestMessage.getScheduleTime() != null) { objectMessage.setLongProperty( - Constants.SCHEDULE_TIME, requestMessage.getScheduleTime().getMillis()); + Constants.SCHEDULE_TIME, + requestMessage.getScheduleTime().toInstant().toEpochMilli()); } return objectMessage; } diff --git a/osgp/platform/osgp-adapter-ws-core/src/test/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/ConfigurationManagementMapperTest.java b/osgp/platform/osgp-adapter-ws-core/src/test/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/ConfigurationManagementMapperTest.java index 2f4cbe1e465..8e51d44f73b 100644 --- a/osgp/platform/osgp-adapter-ws-core/src/test/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/ConfigurationManagementMapperTest.java +++ b/osgp/platform/osgp-adapter-ws-core/src/test/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/ConfigurationManagementMapperTest.java @@ -8,11 +8,12 @@ import static java.util.Collections.emptyList; import static org.assertj.core.api.Assertions.assertThat; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.util.HashMap; import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeFactory; import ma.glasnost.orika.impl.DefaultMapperFactory; -import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.opensmartgridplatform.adapter.ws.schema.core.configurationmanagement.Configuration; @@ -178,10 +179,17 @@ void mapsWsConfigurationToDomainConfiguration() throws DatatypeConfigurationExce .withRelayLinking( asList(this.aTargetRelayMatrix(143, true), this.aTargetRelayMatrix(144, false))) .withRelayRefreshing(true) - .withSummerTimeDetails(DateTime.parse("2010-06-30T01:20:30+02:00")) - .withWinterTimeDetails(DateTime.parse("2011-06-30T01:20:30+02:00")) + .withSummerTimeDetails(ZonedDateTime.parse("2010-06-30T01:20:30+02:00")) + .withWinterTimeDetails(ZonedDateTime.parse("2011-06-30T01:20:30+02:00")) .build(); - assertThat(result).usingRecursiveComparison().isEqualTo(expected); + assertThat(result) + .usingRecursiveComparison() + .ignoringFields("summerTimeDetails", "winterTimeDetails") + .isEqualTo(expected); + assertThat(result.getWinterTimeDetails().withZoneSameInstant(ZoneId.of("UTC"))) + .isEqualTo(expected.getWinterTimeDetails().withZoneSameInstant(ZoneId.of("UTC"))); + assertThat(result.getSummerTimeDetails().withZoneSameInstant(ZoneId.of("UTC"))) + .isEqualTo(expected.getSummerTimeDetails().withZoneSameInstant(ZoneId.of("UTC"))); } @BeforeEach diff --git a/osgp/platform/osgp-adapter-ws-core/src/test/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/DeviceConverterTest.java b/osgp/platform/osgp-adapter-ws-core/src/test/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/DeviceConverterTest.java index 8b28217eedc..3286b3250c3 100644 --- a/osgp/platform/osgp-adapter-ws-core/src/test/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/DeviceConverterTest.java +++ b/osgp/platform/osgp-adapter-ws-core/src/test/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/DeviceConverterTest.java @@ -8,12 +8,10 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.when; -import java.net.InetAddress; import java.net.UnknownHostException; import java.time.Instant; import java.time.ZoneOffset; import java.time.ZonedDateTime; -import java.util.Date; import java.util.GregorianCalendar; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; @@ -33,6 +31,8 @@ @ExtendWith(MockitoExtension.class) public class DeviceConverterTest { + public static final String TEST_HOST = "localhost"; + @Mock private SsldRepository ssldRepository; @InjectMocks private DeviceManagementMapper deviceManagementMapper; @@ -43,7 +43,7 @@ public void initMapper() { } @Test - public void testDeviceConversion() throws UnknownHostException { + void testDeviceConversion() throws UnknownHostException { final Device device = new Device( "id", @@ -51,7 +51,7 @@ public void testDeviceConversion() throws UnknownHostException { new Address("city", "postal", "street", 42, "nr", "munic"), new GpsCoordinates(12f, 13f), null); - device.updateRegistrationData(InetAddress.getByName("localhost"), "type"); + device.updateRegistrationData(TEST_HOST, "type"); final org.opensmartgridplatform.adapter.ws.schema.core.devicemanagement.Device jaxbDevice = this.deviceManagementMapper.map( @@ -62,12 +62,12 @@ public void testDeviceConversion() throws UnknownHostException { assertThat(jaxbDevice.getContainerAddress().getCity()).isEqualTo("city"); assertThat(jaxbDevice.getContainerAddress().getPostalCode()).isEqualTo("postal"); assertThat(jaxbDevice.getContainerAddress().getStreet()).isEqualTo("street"); - assertThat(jaxbDevice.getContainerAddress().getNumber()).isEqualTo(new Integer(42)); + assertThat(jaxbDevice.getContainerAddress().getNumber()).isEqualTo(42); assertThat(jaxbDevice.getContainerAddress().getNumberAddition()).isEqualTo("nr"); assertThat(jaxbDevice.getContainerAddress().getMunicipality()).isEqualTo("munic"); assertThat(jaxbDevice.getGpsLatitude()).isEqualTo("12.0"); assertThat(jaxbDevice.getGpsLongitude()).isEqualTo("13.0"); - assertThat(jaxbDevice.getNetworkAddress()).isEqualTo("localhost/127.0.0.1"); + assertThat(jaxbDevice.getNetworkAddress()).isEqualTo(TEST_HOST); assertThat(jaxbDevice.getDeviceType()).isEqualTo("type"); final Device mappedBack = this.deviceManagementMapper.map(jaxbDevice, Device.class); @@ -77,26 +77,24 @@ public void testDeviceConversion() throws UnknownHostException { assertThat(mappedBack.getContainerAddress().getCity()).isEqualTo("city"); assertThat(mappedBack.getContainerAddress().getPostalCode()).isEqualTo("postal"); assertThat(mappedBack.getContainerAddress().getStreet()).isEqualTo("street"); - assertThat(mappedBack.getContainerAddress().getNumber()).isEqualTo(new Integer(42)); + assertThat(mappedBack.getContainerAddress().getNumber()).isEqualTo(42); assertThat(mappedBack.getContainerAddress().getNumberAddition()).isEqualTo("nr"); assertThat(mappedBack.getContainerAddress().getMunicipality()).isEqualTo("munic"); assertThat(mappedBack.getGpsCoordinates().getLatitude()).isEqualTo(12); assertThat(mappedBack.getGpsCoordinates().getLongitude()).isEqualTo(13); - // alas networkaddress in jaxb device is just a string, need parsing to - // convert that to InetAddress - assertThat(mappedBack.getNetworkAddress()).isEqualTo(null); + assertThat(mappedBack.getNetworkAddress()).isEqualTo(TEST_HOST); assertThat(mappedBack.getDeviceType()).isEqualTo("type"); } @Test - public void testSmartMeterConversion() throws UnknownHostException { + void testSmartMeterConversion() throws UnknownHostException { final Device device = new SmartMeter( "id", "alias", new Address("city", "postal", "street", 42, "nr", "munic"), new GpsCoordinates(12f, 13f)); - device.updateRegistrationData(InetAddress.getByName("localhost"), "type"); + device.updateRegistrationData(TEST_HOST, "type"); final org.opensmartgridplatform.adapter.ws.schema.core.devicemanagement.Device jaxbDevice = this.deviceManagementMapper.map( @@ -112,7 +110,7 @@ public void testSmartMeterConversion() throws UnknownHostException { assertThat(jaxbDevice.getContainerAddress().getMunicipality()).isEqualTo("munic"); assertThat(jaxbDevice.getGpsLatitude()).isEqualTo("12.0"); assertThat(jaxbDevice.getGpsLongitude()).isEqualTo("13.0"); - assertThat(jaxbDevice.getNetworkAddress()).isEqualTo("localhost/127.0.0.1"); + assertThat(jaxbDevice.getNetworkAddress()).isEqualTo(TEST_HOST); assertThat(jaxbDevice.getDeviceType()).isEqualTo("type"); final SmartMeter mappedBack = this.deviceManagementMapper.map(jaxbDevice, SmartMeter.class); @@ -127,16 +125,13 @@ public void testSmartMeterConversion() throws UnknownHostException { assertThat(mappedBack.getContainerAddress().getMunicipality()).isEqualTo("munic"); assertThat(mappedBack.getGpsCoordinates().getLatitude()).isEqualTo(12); assertThat(mappedBack.getGpsCoordinates().getLongitude()).isEqualTo(13); - // alas networkaddress in jaxb device is just a string, need parsing to - // convert that to InetAddress - assertThat(mappedBack.getNetworkAddress()).isEqualTo(null); + assertThat(mappedBack.getNetworkAddress()).isEqualTo(TEST_HOST); assertThat(mappedBack.getDeviceType()).isEqualTo("type"); } @Test - public void testSsldConversion() throws Exception { + void testSsldConversion() throws Exception { final Instant instant = ZonedDateTime.of(2020, 1, 1, 14, 0, 0, 0, ZoneOffset.UTC).toInstant(); - final Date date = Date.from(instant); final GregorianCalendar gregorianCalendar = GregorianCalendar.from(instant.atZone(ZoneOffset.UTC)); final XMLGregorianCalendar xmlGregorianCalendar = @@ -149,9 +144,9 @@ public void testSsldConversion() throws Exception { new Address("city", "postal", "street", 42, "nr", "munic"), new GpsCoordinates(12f, 13f), null); - device.updateRegistrationData(InetAddress.getByName("localhost"), Ssld.SSLD_TYPE); + device.updateRegistrationData(TEST_HOST, Ssld.SSLD_TYPE); device.getOutputSettings(); - device.setTechnicalInstallationDate(date); + device.setTechnicalInstallationDate(instant); when(this.ssldRepository.findByDeviceIdentification(anyString())).thenReturn(device); @@ -169,9 +164,9 @@ public void testSsldConversion() throws Exception { assertThat(jaxbDevice.getContainerAddress().getMunicipality()).isEqualTo("munic"); assertThat(jaxbDevice.getGpsLatitude()).isEqualTo("12.0"); assertThat(jaxbDevice.getGpsLongitude()).isEqualTo("13.0"); - assertThat(jaxbDevice.getNetworkAddress()).isEqualTo("localhost/127.0.0.1"); + assertThat(jaxbDevice.getNetworkAddress()).isEqualTo(TEST_HOST); assertThat(jaxbDevice.getDeviceType()).isEqualTo(Ssld.SSLD_TYPE); - assertThat(jaxbDevice.getOutputSettings().size()).isEqualTo(3); + assertThat(jaxbDevice.getOutputSettings()).hasSize(3); for (int i = 0; i < 3; i++) { assertThat(device.getOutputSettings().get(i).getAlias()) .isEqualTo(jaxbDevice.getOutputSettings().get(i).getAlias()); @@ -190,15 +185,13 @@ public void testSsldConversion() throws Exception { assertThat(mappedBack.getContainerAddress().getMunicipality()).isEqualTo("munic"); assertThat(mappedBack.getGpsCoordinates().getLatitude()).isEqualTo(12.0f); assertThat(mappedBack.getGpsCoordinates().getLongitude()).isEqualTo(13.0f); - // alas networkaddress in jaxb device is just a string, need parsing to - // convert that to InetAddress - assertThat(mappedBack.getNetworkAddress()).isEqualTo(null); + assertThat(mappedBack.getNetworkAddress()).isEqualTo(TEST_HOST); assertThat(mappedBack.getDeviceType()).isEqualTo(Ssld.SSLD_TYPE); - assertThat(mappedBack.getOutputSettings().size()).isEqualTo(3); + assertThat(mappedBack.getOutputSettings()).hasSize(3); for (int i = 0; i < 3; i++) { assertThat(device.getOutputSettings().get(i).getAlias()) .isEqualTo(mappedBack.getOutputSettings().get(i).getAlias()); } - assertThat(mappedBack.getTechnicalInstallationDate()).isEqualTo(date); + assertThat(mappedBack.getTechnicalInstallationDate()).isEqualTo(instant); } } diff --git a/osgp/platform/osgp-adapter-ws-core/src/test/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/DeviceManagementMapperTest.java b/osgp/platform/osgp-adapter-ws-core/src/test/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/DeviceManagementMapperTest.java index e0b44ddf472..cd66dfffe18 100644 --- a/osgp/platform/osgp-adapter-ws-core/src/test/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/DeviceManagementMapperTest.java +++ b/osgp/platform/osgp-adapter-ws-core/src/test/java/org/opensmartgridplatform/adapter/ws/core/application/mapping/DeviceManagementMapperTest.java @@ -26,7 +26,7 @@ import org.opensmartgridplatform.domain.core.valueobjects.DeviceExternalManagedFilterType; import org.opensmartgridplatform.domain.core.valueobjects.DeviceInMaintenanceFilterType; -public class DeviceManagementMapperTest { +class DeviceManagementMapperTest { private static final String STREET = "Main street"; private static final int HOUSE_NUMBER = 10; @@ -73,7 +73,7 @@ private org.opensmartgridplatform.domain.core.valueobjects.DeviceFilter expected } @Test - public void mapsDeviceFilter() { + void mapsDeviceFilter() { final DeviceFilter deviceFilter = new DeviceFilter(); deviceFilter.setOrganisationIdentification("organisationIdentification1"); deviceFilter.setAlias("alias1"); @@ -107,7 +107,7 @@ public void mapsDeviceFilter() { } @Test - public void mapsUpdatedDeviceToDevice() { + void mapsUpdatedDeviceToDevice() { final UpdatedDevice updatedDevice = new UpdatedDevice(); final DeviceOutputSetting outputSetting = new DeviceOutputSetting(); @@ -157,7 +157,7 @@ public void mapsUpdatedDeviceToDevice() { } @BeforeEach - public void setUp() { + void setUp() { this.mapper = new DeviceManagementMapper(); this.mapper.initialize(); } diff --git a/osgp/platform/osgp-adapter-ws-distributionautomation/pom.xml b/osgp/platform/osgp-adapter-ws-distributionautomation/pom.xml index 87febb1e63e..07db64dc38c 100644 --- a/osgp/platform/osgp-adapter-ws-distributionautomation/pom.xml +++ b/osgp/platform/osgp-adapter-ws-distributionautomation/pom.xml @@ -11,7 +11,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-platform - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-platform/pom.xml diff --git a/osgp/platform/osgp-adapter-ws-microgrids/pom.xml b/osgp/platform/osgp-adapter-ws-microgrids/pom.xml index d46f2b135f3..69db4ccb8af 100644 --- a/osgp/platform/osgp-adapter-ws-microgrids/pom.xml +++ b/osgp/platform/osgp-adapter-ws-microgrids/pom.xml @@ -11,7 +11,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-platform - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-platform/pom.xml diff --git a/osgp/platform/osgp-adapter-ws-publiclighting/pom.xml b/osgp/platform/osgp-adapter-ws-publiclighting/pom.xml index 3a7db4b8403..42f55a8bf71 100644 --- a/osgp/platform/osgp-adapter-ws-publiclighting/pom.xml +++ b/osgp/platform/osgp-adapter-ws-publiclighting/pom.xml @@ -18,7 +18,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-platform - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-platform/pom.xml diff --git a/osgp/platform/osgp-adapter-ws-publiclighting/src/main/java/org/opensmartgridplatform/adapter/ws/publiclighting/application/config/ApplicationContext.java b/osgp/platform/osgp-adapter-ws-publiclighting/src/main/java/org/opensmartgridplatform/adapter/ws/publiclighting/application/config/ApplicationContext.java index f07cbaa274a..36853584795 100644 --- a/osgp/platform/osgp-adapter-ws-publiclighting/src/main/java/org/opensmartgridplatform/adapter/ws/publiclighting/application/config/ApplicationContext.java +++ b/osgp/platform/osgp-adapter-ws-publiclighting/src/main/java/org/opensmartgridplatform/adapter/ws/publiclighting/application/config/ApplicationContext.java @@ -4,9 +4,8 @@ package org.opensmartgridplatform.adapter.ws.publiclighting.application.config; -import org.joda.time.DateTime; -import org.joda.time.DateTimeConstants; -import org.joda.time.DateTimeZone; +import java.time.Instant; +import java.time.ZoneId; import org.opensmartgridplatform.shared.application.config.AbstractConfig; import org.opensmartgridplatform.shared.application.config.PagingSettings; import org.opensmartgridplatform.shared.config.MetricsConfig; @@ -56,11 +55,13 @@ public class ApplicationContext extends AbstractConfig { private static final String PROPERTY_NAME_PAGING_DEFAULT_PAGE_SIZE = "paging.default.pagesize"; private static final String LOCAL_TIME_ZONE_IDENTIFIER = "Europe/Paris"; - private static final DateTimeZone LOCAL_TIME_ZONE = - DateTimeZone.forID(LOCAL_TIME_ZONE_IDENTIFIER); + private static final ZoneId LOCAL_TIME_ZONE = ZoneId.of(LOCAL_TIME_ZONE_IDENTIFIER); + + public static final int SECONDS_PER_MINUTE = 60; + private static final int TIME_ZONE_OFFSET_MINUTES = - LOCAL_TIME_ZONE.getStandardOffset(new DateTime().getMillis()) - / DateTimeConstants.MILLIS_PER_MINUTE; + LOCAL_TIME_ZONE.getRules().getStandardOffset(Instant.now()).getTotalSeconds() + / SECONDS_PER_MINUTE; @Bean public PagingSettings pagingSettings() { @@ -96,7 +97,7 @@ public String localTimeZoneIdentifier() { } @Bean - public DateTimeZone localTimeZone() { + public ZoneId localTimeZone() { return LOCAL_TIME_ZONE; } diff --git a/osgp/platform/osgp-adapter-ws-publiclighting/src/main/java/org/opensmartgridplatform/adapter/ws/publiclighting/application/services/ScheduleManagementService.java b/osgp/platform/osgp-adapter-ws-publiclighting/src/main/java/org/opensmartgridplatform/adapter/ws/publiclighting/application/services/ScheduleManagementService.java index d9ac62efdda..67cf9c2bb90 100644 --- a/osgp/platform/osgp-adapter-ws-publiclighting/src/main/java/org/opensmartgridplatform/adapter/ws/publiclighting/application/services/ScheduleManagementService.java +++ b/osgp/platform/osgp-adapter-ws-publiclighting/src/main/java/org/opensmartgridplatform/adapter/ws/publiclighting/application/services/ScheduleManagementService.java @@ -4,8 +4,8 @@ package org.opensmartgridplatform.adapter.ws.publiclighting.application.services; +import java.time.ZonedDateTime; import javax.validation.Valid; -import org.joda.time.DateTime; import org.opensmartgridplatform.adapter.ws.publiclighting.infra.jms.PublicLightingRequestMessage; import org.opensmartgridplatform.adapter.ws.publiclighting.infra.jms.PublicLightingRequestMessageSender; import org.opensmartgridplatform.domain.core.entities.Device; @@ -48,7 +48,7 @@ public String enqueueSetLightSchedule( @Identification final String organisationIdentification, @Identification final String deviceIdentification, @Valid final Schedule schedule, - final DateTime scheduledTime, + final ZonedDateTime scheduledTime, final int messagePriority) throws FunctionalException { @@ -75,7 +75,8 @@ public String enqueueSetLightSchedule( .withCorrelationUid(correlationUid) .withMessageType(MessageType.SET_LIGHT_SCHEDULE.name()) .withMessagePriority(messagePriority) - .withScheduleTime(scheduledTime == null ? null : scheduledTime.getMillis()) + .withScheduleTime( + scheduledTime == null ? null : scheduledTime.toInstant().toEpochMilli()) .build(); final PublicLightingRequestMessage message = diff --git a/osgp/platform/osgp-adapter-ws-publiclighting/src/main/java/org/opensmartgridplatform/adapter/ws/publiclighting/endpoints/PublicLightingAdHocManagementEndpoint.java b/osgp/platform/osgp-adapter-ws-publiclighting/src/main/java/org/opensmartgridplatform/adapter/ws/publiclighting/endpoints/PublicLightingAdHocManagementEndpoint.java index f7ee61f277d..af01cedcc5a 100644 --- a/osgp/platform/osgp-adapter-ws-publiclighting/src/main/java/org/opensmartgridplatform/adapter/ws/publiclighting/endpoints/PublicLightingAdHocManagementEndpoint.java +++ b/osgp/platform/osgp-adapter-ws-publiclighting/src/main/java/org/opensmartgridplatform/adapter/ws/publiclighting/endpoints/PublicLightingAdHocManagementEndpoint.java @@ -4,10 +4,10 @@ package org.opensmartgridplatform.adapter.ws.publiclighting.endpoints; +import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.List; import javax.validation.ConstraintViolationException; -import org.joda.time.DateTime; import org.opensmartgridplatform.adapter.ws.endpointinterceptors.MessagePriority; import org.opensmartgridplatform.adapter.ws.endpointinterceptors.OrganisationIdentification; import org.opensmartgridplatform.adapter.ws.publiclighting.application.mapping.AdHocManagementMapper; @@ -407,9 +407,9 @@ public SetTransitionAsyncResponse setTransition( request.getTransitionType(), org.opensmartgridplatform.domain.core.valueobjects.TransitionType.class)); } - DateTime dateTime = null; + ZonedDateTime dateTime = null; if (request.getTime() != null) { - dateTime = new DateTime(request.getTime().toGregorianCalendar().getTime()); + dateTime = request.getTime().toGregorianCalendar().toZonedDateTime(); } transitionMessageDataContainer.setDateTime(dateTime); diff --git a/osgp/platform/osgp-adapter-ws-publiclighting/src/main/java/org/opensmartgridplatform/adapter/ws/publiclighting/endpoints/PublicLightingScheduleManagementEndpoint.java b/osgp/platform/osgp-adapter-ws-publiclighting/src/main/java/org/opensmartgridplatform/adapter/ws/publiclighting/endpoints/PublicLightingScheduleManagementEndpoint.java index 9cdc0d5b4b3..992ed6fd7ec 100644 --- a/osgp/platform/osgp-adapter-ws-publiclighting/src/main/java/org/opensmartgridplatform/adapter/ws/publiclighting/endpoints/PublicLightingScheduleManagementEndpoint.java +++ b/osgp/platform/osgp-adapter-ws-publiclighting/src/main/java/org/opensmartgridplatform/adapter/ws/publiclighting/endpoints/PublicLightingScheduleManagementEndpoint.java @@ -4,10 +4,10 @@ package org.opensmartgridplatform.adapter.ws.publiclighting.endpoints; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.util.List; import javax.validation.ConstraintViolationException; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; import org.opensmartgridplatform.adapter.ws.domain.entities.ResponseData; import org.opensmartgridplatform.adapter.ws.endpointinterceptors.MessagePriority; import org.opensmartgridplatform.adapter.ws.endpointinterceptors.OrganisationIdentification; @@ -91,11 +91,14 @@ public SetScheduleAsyncResponse setLightSchedule( // Get the request parameters, make sure that they are in UTC. // Maybe add an adapter to the service, so that all datetime are // converted to utc automatically. - final DateTime scheduleTime = + final ZonedDateTime scheduleTime = request.getScheduledTime() == null ? null - : new DateTime(request.getScheduledTime().toGregorianCalendar()) - .toDateTime(DateTimeZone.UTC); + : request + .getScheduledTime() + .toGregorianCalendar() + .toZonedDateTime() + .withZoneSameInstant(ZoneId.of("UTC")); final List scheduleEntries = this.scheduleManagementMapper.mapAsList( diff --git a/osgp/platform/osgp-adapter-ws-publiclighting/src/main/java/org/opensmartgridplatform/adapter/ws/publiclighting/infra/jms/PublicLightingRequestMessage.java b/osgp/platform/osgp-adapter-ws-publiclighting/src/main/java/org/opensmartgridplatform/adapter/ws/publiclighting/infra/jms/PublicLightingRequestMessage.java index 31087fb9ac1..58eefd32a7f 100644 --- a/osgp/platform/osgp-adapter-ws-publiclighting/src/main/java/org/opensmartgridplatform/adapter/ws/publiclighting/infra/jms/PublicLightingRequestMessage.java +++ b/osgp/platform/osgp-adapter-ws-publiclighting/src/main/java/org/opensmartgridplatform/adapter/ws/publiclighting/infra/jms/PublicLightingRequestMessage.java @@ -5,7 +5,9 @@ package org.opensmartgridplatform.adapter.ws.publiclighting.infra.jms; import java.io.Serializable; -import org.joda.time.DateTime; +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; import org.opensmartgridplatform.shared.infra.jms.MessageMetadata; import org.opensmartgridplatform.shared.infra.jms.MessageType; import org.opensmartgridplatform.shared.infra.jms.RequestMessage; @@ -16,7 +18,7 @@ public class PublicLightingRequestMessage extends RequestMessage { private static final long serialVersionUID = 8981706563226676098L; private final MessageType messageType; - private final DateTime scheduleTime; + private final ZonedDateTime scheduleTime; private final Integer messagePriority; private PublicLightingRequestMessage( @@ -34,7 +36,9 @@ private PublicLightingRequestMessage( if (messageMetadata.getScheduleTime() == null) { this.scheduleTime = null; } else { - this.scheduleTime = new DateTime(messageMetadata.getScheduleTime()); + this.scheduleTime = + ZonedDateTime.ofInstant( + Instant.ofEpochMilli(messageMetadata.getScheduleTime()), ZoneId.systemDefault()); } } @@ -42,7 +46,7 @@ public MessageType getMessageType() { return this.messageType; } - public DateTime getScheduleTime() { + public ZonedDateTime getScheduleTime() { return this.scheduleTime; } diff --git a/osgp/platform/osgp-adapter-ws-publiclighting/src/main/java/org/opensmartgridplatform/adapter/ws/publiclighting/infra/jms/PublicLightingRequestMessageSender.java b/osgp/platform/osgp-adapter-ws-publiclighting/src/main/java/org/opensmartgridplatform/adapter/ws/publiclighting/infra/jms/PublicLightingRequestMessageSender.java index 5482c8fa123..0e6225f5a93 100644 --- a/osgp/platform/osgp-adapter-ws-publiclighting/src/main/java/org/opensmartgridplatform/adapter/ws/publiclighting/infra/jms/PublicLightingRequestMessageSender.java +++ b/osgp/platform/osgp-adapter-ws-publiclighting/src/main/java/org/opensmartgridplatform/adapter/ws/publiclighting/infra/jms/PublicLightingRequestMessageSender.java @@ -82,7 +82,8 @@ public Message createMessage(final Session session) throws JMSException { Constants.DEVICE_IDENTIFICATION, requestMessage.getDeviceIdentification()); if (requestMessage.getScheduleTime() != null) { objectMessage.setLongProperty( - Constants.SCHEDULE_TIME, requestMessage.getScheduleTime().getMillis()); + Constants.SCHEDULE_TIME, + requestMessage.getScheduleTime().toInstant().toEpochMilli()); } return objectMessage; } diff --git a/osgp/platform/osgp-adapter-ws-shared-db/pom.xml b/osgp/platform/osgp-adapter-ws-shared-db/pom.xml index 026ccc5607e..d64c2933de7 100644 --- a/osgp/platform/osgp-adapter-ws-shared-db/pom.xml +++ b/osgp/platform/osgp-adapter-ws-shared-db/pom.xml @@ -17,7 +17,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-platform - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-platform/pom.xml diff --git a/osgp/platform/osgp-adapter-ws-shared-db/src/main/java/org/opensmartgridplatform/adapter/ws/shared/db/domain/repositories/writable/WritableDeviceModelRepository.java b/osgp/platform/osgp-adapter-ws-shared-db/src/main/java/org/opensmartgridplatform/adapter/ws/shared/db/domain/repositories/writable/WritableDeviceModelRepository.java index 0612e0bdf99..b06927c8dd8 100644 --- a/osgp/platform/osgp-adapter-ws-shared-db/src/main/java/org/opensmartgridplatform/adapter/ws/shared/db/domain/repositories/writable/WritableDeviceModelRepository.java +++ b/osgp/platform/osgp-adapter-ws-shared-db/src/main/java/org/opensmartgridplatform/adapter/ws/shared/db/domain/repositories/writable/WritableDeviceModelRepository.java @@ -12,7 +12,7 @@ @Repository public interface WritableDeviceModelRepository extends JpaRepository { - DeviceModel findByManufacturerAndModelCode(Manufacturer manufacturer, String modelCode); + DeviceModel findByManufacturerAndModelCodeIgnoreCase(Manufacturer manufacturer, String modelCode); DeviceModel findByManufacturerCodeAndModelCode(String string, String modelCode); diff --git a/osgp/platform/osgp-adapter-ws-shared-db/src/main/java/org/opensmartgridplatform/adapter/ws/shared/db/domain/repositories/writable/WritableManufacturerRepository.java b/osgp/platform/osgp-adapter-ws-shared-db/src/main/java/org/opensmartgridplatform/adapter/ws/shared/db/domain/repositories/writable/WritableManufacturerRepository.java index 603970b275b..24e039a90cd 100644 --- a/osgp/platform/osgp-adapter-ws-shared-db/src/main/java/org/opensmartgridplatform/adapter/ws/shared/db/domain/repositories/writable/WritableManufacturerRepository.java +++ b/osgp/platform/osgp-adapter-ws-shared-db/src/main/java/org/opensmartgridplatform/adapter/ws/shared/db/domain/repositories/writable/WritableManufacturerRepository.java @@ -10,7 +10,7 @@ @Repository public interface WritableManufacturerRepository extends JpaRepository { - Manufacturer findByCode(String code); + Manufacturer findByCodeIgnoreCase(String code); Manufacturer findByName(String manufacturerName); } diff --git a/osgp/platform/osgp-adapter-ws-shared/pom.xml b/osgp/platform/osgp-adapter-ws-shared/pom.xml index 8fdd196b2bf..8510d3f97e2 100644 --- a/osgp/platform/osgp-adapter-ws-shared/pom.xml +++ b/osgp/platform/osgp-adapter-ws-shared/pom.xml @@ -17,7 +17,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-platform - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-platform/pom.xml diff --git a/osgp/platform/osgp-adapter-ws-shared/src/main/java/org/opensmartgridplatform/adapter/ws/domain/repositories/ResponseDataRepository.java b/osgp/platform/osgp-adapter-ws-shared/src/main/java/org/opensmartgridplatform/adapter/ws/domain/repositories/ResponseDataRepository.java index 8bd184781b3..82fd2b9253f 100644 --- a/osgp/platform/osgp-adapter-ws-shared/src/main/java/org/opensmartgridplatform/adapter/ws/domain/repositories/ResponseDataRepository.java +++ b/osgp/platform/osgp-adapter-ws-shared/src/main/java/org/opensmartgridplatform/adapter/ws/domain/repositories/ResponseDataRepository.java @@ -4,7 +4,7 @@ package org.opensmartgridplatform.adapter.ws.domain.repositories; -import java.util.Date; +import java.time.Instant; import java.util.List; import org.opensmartgridplatform.adapter.ws.domain.entities.ResponseData; import org.springframework.data.domain.Pageable; @@ -21,9 +21,9 @@ public interface ResponseDataRepository extends JpaRepository findByDeviceIdentification(String deviceIdentification); List findByNumberOfNotificationsSentAndCreationTimeBefore( - Short numberOfNotificationsSent, Date createdBefore, Pageable pageable); + Short numberOfNotificationsSent, Instant createdBefore, Pageable pageable); ResponseData findByCorrelationUid(String correlationUid); - void removeByCreationTimeBefore(Date date); + void removeByCreationTimeBefore(Instant date); } diff --git a/osgp/platform/osgp-adapter-ws-shared/src/main/java/org/opensmartgridplatform/adapter/ws/domain/repositories/ResponseUrlDataRepository.java b/osgp/platform/osgp-adapter-ws-shared/src/main/java/org/opensmartgridplatform/adapter/ws/domain/repositories/ResponseUrlDataRepository.java index ef4a83273d9..0fc5757198e 100644 --- a/osgp/platform/osgp-adapter-ws-shared/src/main/java/org/opensmartgridplatform/adapter/ws/domain/repositories/ResponseUrlDataRepository.java +++ b/osgp/platform/osgp-adapter-ws-shared/src/main/java/org/opensmartgridplatform/adapter/ws/domain/repositories/ResponseUrlDataRepository.java @@ -4,7 +4,7 @@ package org.opensmartgridplatform.adapter.ws.domain.repositories; -import java.util.Date; +import java.time.Instant; import org.opensmartgridplatform.adapter.ws.domain.entities.ResponseUrlData; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @@ -14,5 +14,5 @@ public interface ResponseUrlDataRepository extends JpaRepository NO_FILTER = (eventRoot, query, cb) -> cb.and(); @Override - public Specification isCreatedAfter(final Date dateFrom) { + public Specification isCreatedAfter(final Instant dateFrom) { if (dateFrom == null) { return NO_FILTER; } return ((eventRoot, query, cb) -> - cb.greaterThanOrEqualTo(eventRoot.get("dateTime"), dateFrom)); + cb.greaterThanOrEqualTo(eventRoot.get("dateTime"), dateFrom)); } @Override - public Specification isCreatedBefore(final Date dateUntil) { + public Specification isCreatedBefore(final Instant dateUntil) { if (dateUntil == null) { return NO_FILTER; } return ((eventRoot, query, cb) -> - cb.lessThanOrEqualTo(eventRoot.get("dateTime"), dateUntil)); + cb.lessThanOrEqualTo(eventRoot.get("dateTime"), dateUntil)); } @Override diff --git a/osgp/platform/osgp-adapter-ws-shared/src/main/java/org/opensmartgridplatform/adapter/ws/shared/services/AbstractResendNotificationService.java b/osgp/platform/osgp-adapter-ws-shared/src/main/java/org/opensmartgridplatform/adapter/ws/shared/services/AbstractResendNotificationService.java index 13f2a1b4af4..508054a859a 100644 --- a/osgp/platform/osgp-adapter-ws-shared/src/main/java/org/opensmartgridplatform/adapter/ws/shared/services/AbstractResendNotificationService.java +++ b/osgp/platform/osgp-adapter-ws-shared/src/main/java/org/opensmartgridplatform/adapter/ws/shared/services/AbstractResendNotificationService.java @@ -4,11 +4,12 @@ package org.opensmartgridplatform.adapter.ws.shared.services; +import java.time.Duration; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.temporal.ChronoUnit; import java.util.List; import org.apache.commons.lang3.EnumUtils; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.joda.time.Duration; import org.opensmartgridplatform.adapter.ws.domain.entities.ApplicationDataLookupKey; import org.opensmartgridplatform.adapter.ws.domain.entities.ResponseData; import org.opensmartgridplatform.adapter.ws.domain.repositories.ResponseDataRepository; @@ -69,7 +70,8 @@ public void execute() { notificationsResent > -1; notificationsResent--) { final long delay = resendDelays[notificationsResent]; - final DateTime createdBefore = DateTime.now(DateTimeZone.UTC).minus(delay); + final ZonedDateTime createdBefore = + ZonedDateTime.now(ZoneId.of("UTC")).minus(delay, ChronoUnit.MILLIS); /* * Dealing with the response data for each number of resent * notifications separately, allows for specification of the @@ -90,7 +92,8 @@ public void execute() { } } - private void resendNotifications(final short notificationsResent, final DateTime createdBefore) { + private void resendNotifications( + final short notificationsResent, final ZonedDateTime createdBefore) { List responseDataForNotifying = this.getResponseDataForNotifying(notificationsResent, createdBefore); @@ -178,8 +181,7 @@ private long[] calculateResendDelays(final int maximumNumberOfResends) { } private long calculateDelay(final int earlierResentNotifications) { - final long standardDelayInMillis = - Duration.standardMinutes(this.resendThresholdInMinutes).getMillis(); + final long standardDelayInMillis = Duration.ofMinutes(this.resendThresholdInMinutes).toMillis(); final long factor = (long) Math.pow(this.resendNotificationMultiplier, earlierResentNotifications); final long delay = standardDelayInMillis * factor; @@ -240,11 +242,11 @@ public String getNotificationMessage(final String responseData) { * equal to {@code notificationsResent} and a creation time before {@code createdBefore}. */ private List getResponseDataForNotifying( - final short notificationsResent, final DateTime createdBefore) { + final short notificationsResent, final ZonedDateTime createdBefore) { final Pageable pageable = PageRequest.of(0, this.resendPageSize, Sort.by(Direction.ASC, "creationTime")); return this.responseDataRepository.findByNumberOfNotificationsSentAndCreationTimeBefore( - notificationsResent, createdBefore.toDate(), pageable); + notificationsResent, createdBefore.toInstant(), pageable); } } diff --git a/osgp/platform/osgp-adapter-ws-shared/src/main/java/org/opensmartgridplatform/adapter/ws/shared/services/ResponseDataCleanupService.java b/osgp/platform/osgp-adapter-ws-shared/src/main/java/org/opensmartgridplatform/adapter/ws/shared/services/ResponseDataCleanupService.java index 0befbc5e40c..7974891d8d1 100644 --- a/osgp/platform/osgp-adapter-ws-shared/src/main/java/org/opensmartgridplatform/adapter/ws/shared/services/ResponseDataCleanupService.java +++ b/osgp/platform/osgp-adapter-ws-shared/src/main/java/org/opensmartgridplatform/adapter/ws/shared/services/ResponseDataCleanupService.java @@ -4,8 +4,8 @@ package org.opensmartgridplatform.adapter.ws.shared.services; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; +import java.time.ZoneId; +import java.time.ZonedDateTime; import org.opensmartgridplatform.adapter.ws.domain.repositories.ResponseDataRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -21,8 +21,8 @@ public class ResponseDataCleanupService { public void execute() { - final DateTime removeBeforeDateTime = - DateTime.now(DateTimeZone.UTC).minusDays(this.cleanupJobRetentionTimeInDays); - this.responseDataRepository.removeByCreationTimeBefore(removeBeforeDateTime.toDate()); + final ZonedDateTime removeBeforeDateTime = + ZonedDateTime.now(ZoneId.of("UTC")).minusDays(this.cleanupJobRetentionTimeInDays); + this.responseDataRepository.removeByCreationTimeBefore(removeBeforeDateTime.toInstant()); } } diff --git a/osgp/platform/osgp-adapter-ws-smartmetering/pom.xml b/osgp/platform/osgp-adapter-ws-smartmetering/pom.xml index ac5ee7bce5c..e220c70563c 100644 --- a/osgp/platform/osgp-adapter-ws-smartmetering/pom.xml +++ b/osgp/platform/osgp-adapter-ws-smartmetering/pom.xml @@ -18,7 +18,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-platform - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-platform/pom.xml diff --git a/osgp/platform/osgp-adapter-ws-smartmetering/src/main/java/org/opensmartgridplatform/adapter/ws/smartmetering/application/mapping/ManagementMapper.java b/osgp/platform/osgp-adapter-ws-smartmetering/src/main/java/org/opensmartgridplatform/adapter/ws/smartmetering/application/mapping/ManagementMapper.java index e7311cc101c..023cd52e555 100644 --- a/osgp/platform/osgp-adapter-ws-smartmetering/src/main/java/org/opensmartgridplatform/adapter/ws/smartmetering/application/mapping/ManagementMapper.java +++ b/osgp/platform/osgp-adapter-ws-smartmetering/src/main/java/org/opensmartgridplatform/adapter/ws/smartmetering/application/mapping/ManagementMapper.java @@ -9,6 +9,7 @@ import org.opensmartgridplatform.adapter.ws.schema.smartmetering.management.MessageLog; import org.opensmartgridplatform.logging.domain.entities.DeviceLogItem; import org.opensmartgridplatform.shared.mappers.XMLGregorianCalendarToDateTimeConverter; +import org.opensmartgridplatform.shared.mappers.XMLGregorianCalendarToInstantConverter; import org.springframework.stereotype.Component; @Component(value = "smartMeteringManagementMapper") @@ -24,8 +25,11 @@ public void configure(final MapperFactory mapperFactory) { // dates and times. mapperFactory .getConverterFactory() - .registerConverter(new XMLGregorianCalendarToDateTimeConverter()); + .registerConverter(new XMLGregorianCalendarToInstantConverter()); mapperFactory.getConverterFactory().registerConverter(new XsdDateTimeToLongConverter()); + mapperFactory + .getConverterFactory() + .registerConverter(new XMLGregorianCalendarToDateTimeConverter()); mapperFactory.getConverterFactory().registerConverter(new EventMessageDataContainerConverter()); diff --git a/osgp/platform/osgp-adapter-ws-smartmetering/src/main/java/org/opensmartgridplatform/adapter/ws/smartmetering/application/services/ResponseUrlDataCleanupService.java b/osgp/platform/osgp-adapter-ws-smartmetering/src/main/java/org/opensmartgridplatform/adapter/ws/smartmetering/application/services/ResponseUrlDataCleanupService.java index ceaa0f3a062..309ba2be7cf 100644 --- a/osgp/platform/osgp-adapter-ws-smartmetering/src/main/java/org/opensmartgridplatform/adapter/ws/smartmetering/application/services/ResponseUrlDataCleanupService.java +++ b/osgp/platform/osgp-adapter-ws-smartmetering/src/main/java/org/opensmartgridplatform/adapter/ws/smartmetering/application/services/ResponseUrlDataCleanupService.java @@ -4,8 +4,8 @@ package org.opensmartgridplatform.adapter.ws.smartmetering.application.services; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; +import java.time.ZoneId; +import java.time.ZonedDateTime; import org.opensmartgridplatform.adapter.ws.domain.repositories.ResponseUrlDataRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -21,8 +21,8 @@ public class ResponseUrlDataCleanupService { public void execute() { - final DateTime removeBeforeDateTime = - DateTime.now(DateTimeZone.UTC).minusDays(this.cleanupJobRetentionTimeInDays); - this.responseUrlDataRepository.removeByCreationTimeBefore(removeBeforeDateTime.toDate()); + final ZonedDateTime removeBeforeDateTime = + ZonedDateTime.now(ZoneId.of("UTC")).minusDays(this.cleanupJobRetentionTimeInDays); + this.responseUrlDataRepository.removeByCreationTimeBefore(removeBeforeDateTime.toInstant()); } } diff --git a/osgp/platform/osgp-adapter-ws-smartmetering/src/test/java/org/opensmartgridplatform/adapter/ws/smartmetering/application/mapping/DeviceMappingTest.java b/osgp/platform/osgp-adapter-ws-smartmetering/src/test/java/org/opensmartgridplatform/adapter/ws/smartmetering/application/mapping/DeviceMappingTest.java index 605b2b110e8..e749e214964 100644 --- a/osgp/platform/osgp-adapter-ws-smartmetering/src/test/java/org/opensmartgridplatform/adapter/ws/smartmetering/application/mapping/DeviceMappingTest.java +++ b/osgp/platform/osgp-adapter-ws-smartmetering/src/test/java/org/opensmartgridplatform/adapter/ws/smartmetering/application/mapping/DeviceMappingTest.java @@ -31,6 +31,8 @@ class DeviceMappingTest { private static final Long PORT = 3000L; private static final int CHALLENGE_LENGTH = 15; private static final boolean IS_ACTIVE = true; + private static final boolean LLS1_ACTIVE = true; + private static final byte[] KEY = "key".getBytes(); private final InstallationMapper installationMapper = new InstallationMapper(); private final Date deliveryDateSmartMeteringDevice = new Date(); @@ -88,6 +90,7 @@ private void checkSmartMeteringDeviceToDeviceMapping(final Device device) { assertThat(device.isHls3Active()).isEqualTo(IS_ACTIVE); assertThat(device.isHls4Active()).isEqualTo(IS_ACTIVE); assertThat(device.isHls5Active()).isEqualTo(IS_ACTIVE); + assertThat(device.isLls1Active()).isEqualTo(LLS1_ACTIVE); assertThat(device.getMasterKey()).isEqualTo(KEY); assertThat(device.getGlobalEncryptionUnicastKey()).isEqualTo(KEY); assertThat(device.getAuthenticationKey()).isEqualTo(KEY); @@ -150,6 +153,7 @@ private SmartMeteringDevice createSmartMeteringDevice() { smartMeteringDevice.setProtocolVersion(PROTOCOL_VERSION); smartMeteringDevice.setProtocolVariant(PROTOCOL_VARIANT); smartMeteringDevice.setSupplier(SUPPLIER); + smartMeteringDevice.setLls1Active(LLS1_ACTIVE); smartMeteringDevice.setHls3Active(IS_ACTIVE); smartMeteringDevice.setHls4Active(IS_ACTIVE); smartMeteringDevice.setHls5Active(IS_ACTIVE); diff --git a/osgp/platform/osgp-adapter-ws-smartmetering/src/test/java/org/opensmartgridplatform/adapter/ws/smartmetering/application/mapping/GetGsmDiagnosticResponseMappingTest.java b/osgp/platform/osgp-adapter-ws-smartmetering/src/test/java/org/opensmartgridplatform/adapter/ws/smartmetering/application/mapping/GetGsmDiagnosticResponseMappingTest.java index d5002f12562..7d5c60977a2 100644 --- a/osgp/platform/osgp-adapter-ws-smartmetering/src/test/java/org/opensmartgridplatform/adapter/ws/smartmetering/application/mapping/GetGsmDiagnosticResponseMappingTest.java +++ b/osgp/platform/osgp-adapter-ws-smartmetering/src/test/java/org/opensmartgridplatform/adapter/ws/smartmetering/application/mapping/GetGsmDiagnosticResponseMappingTest.java @@ -10,7 +10,6 @@ import java.util.Date; import org.junit.jupiter.api.Test; import org.opensmartgridplatform.domain.core.valueobjects.smartmetering.AdjacentCellInfo; -import org.opensmartgridplatform.domain.core.valueobjects.smartmetering.BitErrorRateType; import org.opensmartgridplatform.domain.core.valueobjects.smartmetering.CellInfo; import org.opensmartgridplatform.domain.core.valueobjects.smartmetering.CircuitSwitchedStatusType; import org.opensmartgridplatform.domain.core.valueobjects.smartmetering.GetGsmDiagnosticResponseData; @@ -41,8 +40,7 @@ void shouldConvertGetGsmDiagnosticResponse() { private GetGsmDiagnosticResponseData newGetGsmDiagnosticResponseData() { final CellInfo cellInfo = - new CellInfo( - 77L, 2230, SignalQualityType.MINUS_61_DBM, BitErrorRateType.RXQUAL_4, 31, 42, 1L); + new CellInfo(77L, 2230, SignalQualityType.MINUS_61_DBM, (short) 4, 31, 42, 1L); final AdjacentCellInfo adjacentCellInfo = new AdjacentCellInfo(93L, SignalQualityType.MINUS_61_DBM); diff --git a/osgp/platform/osgp-adapter-ws-tariffswitching/pom.xml b/osgp/platform/osgp-adapter-ws-tariffswitching/pom.xml index 6c35dd82b59..1f42653d329 100644 --- a/osgp/platform/osgp-adapter-ws-tariffswitching/pom.xml +++ b/osgp/platform/osgp-adapter-ws-tariffswitching/pom.xml @@ -18,7 +18,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-platform - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-platform/pom.xml diff --git a/osgp/platform/osgp-adapter-ws-tariffswitching/src/main/java/org/opensmartgridplatform/adapter/ws/tariffswitching/application/services/ScheduleManagementService.java b/osgp/platform/osgp-adapter-ws-tariffswitching/src/main/java/org/opensmartgridplatform/adapter/ws/tariffswitching/application/services/ScheduleManagementService.java index 1c1c0aa1065..89b20a1732e 100644 --- a/osgp/platform/osgp-adapter-ws-tariffswitching/src/main/java/org/opensmartgridplatform/adapter/ws/tariffswitching/application/services/ScheduleManagementService.java +++ b/osgp/platform/osgp-adapter-ws-tariffswitching/src/main/java/org/opensmartgridplatform/adapter/ws/tariffswitching/application/services/ScheduleManagementService.java @@ -4,11 +4,11 @@ package org.opensmartgridplatform.adapter.ws.tariffswitching.application.services; +import java.time.ZonedDateTime; import java.util.List; import javax.validation.Valid; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; -import org.joda.time.DateTime; import org.opensmartgridplatform.adapter.ws.tariffswitching.infra.jms.TariffSwitchingRequestMessage; import org.opensmartgridplatform.adapter.ws.tariffswitching.infra.jms.TariffSwitchingRequestMessageSender; import org.opensmartgridplatform.domain.core.entities.Device; @@ -49,7 +49,7 @@ public String enqueueSetTariffSchedule( @Identification final String organisationIdentification, @Identification final String deviceIdentification, @NotNull @Size(min = 1, max = 50) @Valid final List mapAsList, - final DateTime scheduledTime, + final ZonedDateTime scheduledTime, final int messagePriority) throws FunctionalException { @@ -78,7 +78,8 @@ public String enqueueSetTariffSchedule( .withCorrelationUid(correlationUid) .withMessageType(MessageType.SET_TARIFF_SCHEDULE.name()) .withMessagePriority(messagePriority) - .withScheduleTime(scheduledTime == null ? null : scheduledTime.getMillis()) + .withScheduleTime( + scheduledTime == null ? null : scheduledTime.toInstant().toEpochMilli()) .build(); final TariffSwitchingRequestMessage message = diff --git a/osgp/platform/osgp-adapter-ws-tariffswitching/src/main/java/org/opensmartgridplatform/adapter/ws/tariffswitching/endpoints/TariffSwitchingScheduleManagementEndpoint.java b/osgp/platform/osgp-adapter-ws-tariffswitching/src/main/java/org/opensmartgridplatform/adapter/ws/tariffswitching/endpoints/TariffSwitchingScheduleManagementEndpoint.java index 217fb799c8c..6fb529d41d1 100644 --- a/osgp/platform/osgp-adapter-ws-tariffswitching/src/main/java/org/opensmartgridplatform/adapter/ws/tariffswitching/endpoints/TariffSwitchingScheduleManagementEndpoint.java +++ b/osgp/platform/osgp-adapter-ws-tariffswitching/src/main/java/org/opensmartgridplatform/adapter/ws/tariffswitching/endpoints/TariffSwitchingScheduleManagementEndpoint.java @@ -4,9 +4,9 @@ package org.opensmartgridplatform.adapter.ws.tariffswitching.endpoints; +import java.time.ZoneId; +import java.time.ZonedDateTime; import javax.validation.ConstraintViolationException; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; import org.opensmartgridplatform.adapter.ws.domain.entities.ResponseData; import org.opensmartgridplatform.adapter.ws.endpointinterceptors.MessagePriority; import org.opensmartgridplatform.adapter.ws.endpointinterceptors.OrganisationIdentification; @@ -83,11 +83,14 @@ public SetScheduleAsyncResponse setSchedule( // Get the request parameters, make sure that they are in UTC. // Maybe add an adapter to the service, so that all datetime are // converted to utc automatically. - final DateTime scheduleTime = + final ZonedDateTime scheduleTime = request.getScheduledTime() == null ? null - : new DateTime(request.getScheduledTime().toGregorianCalendar()) - .toDateTime(DateTimeZone.UTC); + : request + .getScheduledTime() + .toGregorianCalendar() + .toZonedDateTime() + .withZoneSameInstant(ZoneId.of("UTC")); final SetScheduleAsyncResponse response = new SetScheduleAsyncResponse(); diff --git a/osgp/platform/osgp-adapter-ws-tariffswitching/src/main/java/org/opensmartgridplatform/adapter/ws/tariffswitching/infra/jms/TariffSwitchingRequestMessage.java b/osgp/platform/osgp-adapter-ws-tariffswitching/src/main/java/org/opensmartgridplatform/adapter/ws/tariffswitching/infra/jms/TariffSwitchingRequestMessage.java index f9dcd161465..e49597a0a23 100644 --- a/osgp/platform/osgp-adapter-ws-tariffswitching/src/main/java/org/opensmartgridplatform/adapter/ws/tariffswitching/infra/jms/TariffSwitchingRequestMessage.java +++ b/osgp/platform/osgp-adapter-ws-tariffswitching/src/main/java/org/opensmartgridplatform/adapter/ws/tariffswitching/infra/jms/TariffSwitchingRequestMessage.java @@ -5,7 +5,9 @@ package org.opensmartgridplatform.adapter.ws.tariffswitching.infra.jms; import java.io.Serializable; -import org.joda.time.DateTime; +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; import org.opensmartgridplatform.shared.infra.jms.MessageMetadata; import org.opensmartgridplatform.shared.infra.jms.MessageType; import org.opensmartgridplatform.shared.infra.jms.RequestMessage; @@ -16,7 +18,7 @@ public class TariffSwitchingRequestMessage extends RequestMessage { private static final long serialVersionUID = -5747625524754499878L; private final MessageType messageType; - private final DateTime scheduleTime; + private final ZonedDateTime scheduleTime; private final Integer messagePriority; private TariffSwitchingRequestMessage( @@ -34,7 +36,9 @@ private TariffSwitchingRequestMessage( if (messageMetadata.getScheduleTime() == null) { this.scheduleTime = null; } else { - this.scheduleTime = new DateTime(messageMetadata.getScheduleTime()); + this.scheduleTime = + ZonedDateTime.ofInstant( + Instant.ofEpochMilli(messageMetadata.getScheduleTime()), ZoneId.systemDefault()); } } @@ -42,7 +46,7 @@ public MessageType getMessageType() { return this.messageType; } - public DateTime getScheduleTime() { + public ZonedDateTime getScheduleTime() { return this.scheduleTime; } diff --git a/osgp/platform/osgp-adapter-ws-tariffswitching/src/main/java/org/opensmartgridplatform/adapter/ws/tariffswitching/infra/jms/TariffSwitchingRequestMessageSender.java b/osgp/platform/osgp-adapter-ws-tariffswitching/src/main/java/org/opensmartgridplatform/adapter/ws/tariffswitching/infra/jms/TariffSwitchingRequestMessageSender.java index d6b41eaf353..950431754f0 100644 --- a/osgp/platform/osgp-adapter-ws-tariffswitching/src/main/java/org/opensmartgridplatform/adapter/ws/tariffswitching/infra/jms/TariffSwitchingRequestMessageSender.java +++ b/osgp/platform/osgp-adapter-ws-tariffswitching/src/main/java/org/opensmartgridplatform/adapter/ws/tariffswitching/infra/jms/TariffSwitchingRequestMessageSender.java @@ -82,7 +82,8 @@ public Message createMessage(final Session session) throws JMSException { Constants.DEVICE_IDENTIFICATION, requestMessage.getDeviceIdentification()); if (requestMessage.getScheduleTime() != null) { objectMessage.setLongProperty( - Constants.SCHEDULE_TIME, requestMessage.getScheduleTime().getMillis()); + Constants.SCHEDULE_TIME, + requestMessage.getScheduleTime().toInstant().toEpochMilli()); } return objectMessage; } diff --git a/osgp/platform/osgp-core/pom.xml b/osgp/platform/osgp-core/pom.xml index 7c1ab322075..641ce33da90 100644 --- a/osgp/platform/osgp-core/pom.xml +++ b/osgp/platform/osgp-core/pom.xml @@ -18,7 +18,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-platform - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-platform/pom.xml diff --git a/osgp/platform/osgp-core/src/main/java/org/opensmartgridplatform/core/application/services/DeviceNetworkAddressCleanupService.java b/osgp/platform/osgp-core/src/main/java/org/opensmartgridplatform/core/application/services/DeviceNetworkAddressCleanupService.java index c8bce5286ec..a9c84611bd1 100644 --- a/osgp/platform/osgp-core/src/main/java/org/opensmartgridplatform/core/application/services/DeviceNetworkAddressCleanupService.java +++ b/osgp/platform/osgp-core/src/main/java/org/opensmartgridplatform/core/application/services/DeviceNetworkAddressCleanupService.java @@ -91,7 +91,7 @@ private Predicate duplicatesAllowed(final List configuredRa } final List> rangePredicates = - configuredRanges.stream().map(this::rangePredicate).collect(Collectors.toList()); + configuredRanges.stream().map(this::rangePredicate).toList(); return inetAddress -> { if (inetAddress == null) { @@ -183,50 +183,39 @@ private String[] fromTo(final String configuredRange) { * * @param deviceIdentification identification of the only device that is allowed to have the given * {@code address} as its network address - * @param host the network address that may not remain stored with other devices than the one - * identified by the given {@code deviceIdentification} - * @throws UnknownHostException - */ - public void clearDuplicateAddresses(final String deviceIdentification, final String host) - throws UnknownHostException { - - this.clearDuplicateAddresses(deviceIdentification, InetAddress.getByName(host)); - } - - /** - * Make sure that no other device than the one identified by {@code deviceIdentification} has the - * given {@code address} as network address, by removing the network address with other devices - * where it is stored. - * - * @param deviceIdentification identification of the only device that is allowed to have the given - * {@code address} as its network address - * @param inetAddress the network address that may not remain stored with other devices than the - * one identified by the given {@code deviceIdentification} + * @param networkAddress the network address that may not remain stored with other devices than + * the one identified by the given {@code deviceIdentification} */ public void clearDuplicateAddresses( - final String deviceIdentification, final InetAddress inetAddress) { + final String deviceIdentification, final String networkAddress) { - if (this.allowDuplicateEntries(inetAddress)) { - if (inetAddress != null) { + if (this.allowDuplicateEntries(networkAddress)) { + if (networkAddress != null) { if (this.allowMultipleDevicesPerNetworkAddress) { LOGGER.info( "Not clearing duplicate network addresses, as these are allowed by configuration."); } else { LOGGER.info( "Not clearing duplicate network addresses, as {} is part of a configured exception in: {}", - inetAddress.getHostAddress(), + networkAddress, this.ipRangesAllowingMultipleDevicesPerAddress); } } return; } - this.deviceRepository.findByNetworkAddress(inetAddress).stream() + this.deviceRepository.findByNetworkAddress(networkAddress).stream() .filter(this.clearAddressForDevice(deviceIdentification)) .forEach(this::clearNetworkAddress); } - public boolean allowDuplicateEntries(final InetAddress inetAddress) { + public boolean allowDuplicateEntries(final String networkAddress) { + final InetAddress inetAddress; + try { + inetAddress = InetAddress.getByName(networkAddress); + } catch (final UnknownHostException e) { + return false; + } return this.allowMultipleDevicesPerNetworkAddress || inetAddress == null || LOCALHOST.equals(inetAddress) @@ -240,7 +229,7 @@ private Predicate clearAddressForDevice(final String exceptForThisIdenti private void clearNetworkAddress(final Device device) { LOGGER.info( "Clearing duplicate network address {} with device {}", - device.getIpAddress(), + device.getNetworkAddress(), device.getDeviceIdentification()); device.clearNetworkAddress(); this.deviceRepository.save(device); diff --git a/osgp/platform/osgp-core/src/main/java/org/opensmartgridplatform/core/application/services/DeviceRegistrationMessageService.java b/osgp/platform/osgp-core/src/main/java/org/opensmartgridplatform/core/application/services/DeviceRegistrationMessageService.java index 39abe65885d..1b59ca9cddc 100644 --- a/osgp/platform/osgp-core/src/main/java/org/opensmartgridplatform/core/application/services/DeviceRegistrationMessageService.java +++ b/osgp/platform/osgp-core/src/main/java/org/opensmartgridplatform/core/application/services/DeviceRegistrationMessageService.java @@ -4,7 +4,6 @@ package org.opensmartgridplatform.core.application.services; -import java.net.InetAddress; import java.net.UnknownHostException; import org.opensmartgridplatform.core.domain.model.domain.DomainRequestService; import org.opensmartgridplatform.domain.core.entities.Device; @@ -39,7 +38,7 @@ public class DeviceRegistrationMessageService { * doesn't exist. * * @param deviceIdentification The device identification. - * @param ipAddress The IP address of the device. + * @param networkAddress The IP address of the device. * @param deviceType The type of the device, SSLD or PSLD. * @param hasSchedule In case the device has a schedule, this will be true. * @return Device with updated data @@ -48,21 +47,21 @@ public class DeviceRegistrationMessageService { @Transactional(value = "transactionManager") public Device updateRegistrationData( final String deviceIdentification, - final String ipAddress, + final String networkAddress, final String deviceType, final boolean hasSchedule) throws UnknownHostException { LOGGER.info( - "updateRegistrationData called for device: {} ipAddress: {}, deviceType: {} hasSchedule: {}.", + "updateRegistrationData called for device: {} network address: {}, deviceType: {} hasSchedule: {}.", deviceIdentification, - ipAddress, + networkAddress, deviceType, hasSchedule); // Check for existing IP addresses this.deviceNetworkAddressCleanupService.clearDuplicateAddresses( - deviceIdentification, ipAddress); + deviceIdentification, networkAddress); Device device = this.deviceRepository.findByDeviceIdentification(deviceIdentification); if (device == null) { @@ -70,15 +69,14 @@ public Device updateRegistrationData( device = this.createNewDevice(deviceIdentification, deviceType); } - final InetAddress inetAddress = InetAddress.getByName(ipAddress); - device.updateRegistrationData(inetAddress, deviceType); + device.updateRegistrationData(networkAddress, deviceType); device.updateConnectionDetailsToSuccess(); return this.deviceRepository.save(device); } private Device createNewDevice(final String deviceIdentification, final String deviceType) { - Device device; + final Device device; if (Ssld.SSLD_TYPE.equalsIgnoreCase(deviceType) || Ssld.PSLD_TYPE.equalsIgnoreCase(deviceType)) { device = new Ssld(deviceIdentification); diff --git a/osgp/platform/osgp-core/src/main/java/org/opensmartgridplatform/core/application/services/DeviceResponseMessageService.java b/osgp/platform/osgp-core/src/main/java/org/opensmartgridplatform/core/application/services/DeviceResponseMessageService.java index dc597482730..420f608590a 100644 --- a/osgp/platform/osgp-core/src/main/java/org/opensmartgridplatform/core/application/services/DeviceResponseMessageService.java +++ b/osgp/platform/osgp-core/src/main/java/org/opensmartgridplatform/core/application/services/DeviceResponseMessageService.java @@ -276,7 +276,7 @@ private ProtocolRequestMessage createProtocolRequestMessage(final ProtocolRespon message .messageMetadata() .builder() - .withIpAddress(getIpAddress(device)) + .withNetworkAddress(getNetworkAddress(device)) .withNetworkSegmentIds(device.getBtsId(), device.getCellId()) .withRetryCount(message.getRetryCount() + 1) .build()) @@ -284,11 +284,11 @@ private ProtocolRequestMessage createProtocolRequestMessage(final ProtocolRespon .build(); } - private static String getIpAddress(final Device device) { - if (device.getIpAddress() == null && device.getGatewayDevice() != null) { - return device.getGatewayDevice().getIpAddress(); + private static String getNetworkAddress(final Device device) { + if (device.getNetworkAddress() == null && device.getGatewayDevice() != null) { + return device.getGatewayDevice().getNetworkAddress(); } - return device.getIpAddress(); + return device.getNetworkAddress(); } private ScheduledTask createScheduledRetryTask(final ProtocolResponseMessage message) diff --git a/osgp/platform/osgp-core/src/main/java/org/opensmartgridplatform/core/application/services/EventNotificationMessageService.java b/osgp/platform/osgp-core/src/main/java/org/opensmartgridplatform/core/application/services/EventNotificationMessageService.java index 6651b2f512d..2a66b522e6c 100644 --- a/osgp/platform/osgp-core/src/main/java/org/opensmartgridplatform/core/application/services/EventNotificationMessageService.java +++ b/osgp/platform/osgp-core/src/main/java/org/opensmartgridplatform/core/application/services/EventNotificationMessageService.java @@ -5,15 +5,15 @@ package org.opensmartgridplatform.core.application.services; import java.io.Serializable; +import java.time.Instant; +import java.time.ZonedDateTime; import java.util.ArrayList; -import java.util.Date; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; import org.apache.commons.lang3.NotImplementedException; -import org.joda.time.DateTime; import org.opensmartgridplatform.core.domain.model.domain.DomainRequestService; import org.opensmartgridplatform.domain.core.entities.Device; import org.opensmartgridplatform.domain.core.entities.DeviceOutputSetting; @@ -32,6 +32,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @Service @@ -48,21 +49,25 @@ public class EventNotificationMessageService { @Autowired private EventNotificationHelperService eventNotificationHelperService; + @Value("${event.persist.enabled}") + private boolean eventPersistEnabled; + public void handleEvent( final String deviceIdentification, - final Date dateTime, + final Instant dateTime, final EventType eventType, final String description, final Integer index) throws UnknownEntityException { - this.eventNotificationHelperService.saveEvent( + final Event event = new Event( deviceIdentification, - dateTime != null ? dateTime : DateTime.now().toDate(), + dateTime != null ? dateTime : Instant.now(), eventType, description, - index)); + index); + this.saveEventIfRequired(event); if (this.isSwitchingEvent(eventType)) { this.handleSwitchingEvent(deviceIdentification, dateTime, eventType, index); @@ -89,8 +94,8 @@ public void handleEvent(final String deviceIdentification, final EventNotificati LOGGER.info("handleEvent() called for device: {} with event: {}", deviceIdentification, event); - final Date dateTime = - event.getDateTime() != null ? event.getDateTime().toDate() : DateTime.now().toDate(); + final Instant dateTime = + event.getDateTime() != null ? event.getDateTime().toInstant() : Instant.now(); final EventType eventType = EventType.valueOf(event.getEventType().name()); final String description = event.getDescription(); final Integer index = event.getIndex(); @@ -121,24 +126,17 @@ public void handleEvents( final List switchDeviceEvents = new ArrayList<>(); for (final EventNotificationDto eventNotification : eventNotifications) { - final DateTime eventTime = eventNotification.getDateTime(); + final ZonedDateTime eventTime = eventNotification.getDateTime(); final EventType eventType = EventType.valueOf(eventNotification.getEventType().name()); final Event event = new Event( deviceIdentification, - eventTime != null ? eventTime.toDate() : DateTime.now().toDate(), + eventTime != null ? eventTime.toInstant() : Instant.now(), eventType, eventNotification.getDescription(), eventNotification.getIndex()); - LOGGER.info( - "Saving event for device: {} with eventType: {} eventTime: {} description: {} index: {}", - deviceIdentification, - eventType.name(), - eventTime, - eventNotification.getDescription(), - eventNotification.getIndex()); - this.eventNotificationHelperService.saveEvent(event); + this.saveEventIfRequired(event); if (this.isSwitchingEvent(eventType)) { switchDeviceEvents.add(event); @@ -150,6 +148,20 @@ public void handleEvents( this.handleSwitchDeviceEvents(device, switchDeviceEvents); } + private void saveEventIfRequired(final Event event) { + if (!this.eventPersistEnabled) { + return; + } + LOGGER.info( + "Saving event for device: {} with eventType: {} eventTime: {} description: {} index: {}", + event.getDeviceIdentification(), + event.getEventType(), + event.getDateTime(), + event.getDescription(), + event.getIndex()); + this.eventNotificationHelperService.saveEvent(event); + } + private void handleSwitchDeviceEvents(final Device device, final List switchDeviceEvents) throws UnknownEntityException { @@ -217,7 +229,7 @@ private void handleLightMeasurementDeviceEvents( this.handleLightMeasurementDeviceEvent( deviceIdentification, - event.getDateTime().toDate(), + event.getDateTime().toInstant(), eventType, event.getDescription(), event.getIndex()); @@ -247,7 +259,7 @@ private void createRelayStatus( if (lastRelayStatusPerIndex.get(relayIndex) == null || switchingEvent .getDateTime() - .after(lastRelayStatusPerIndex.get(relayIndex).getLastSwitchingEventTime())) { + .isAfter(lastRelayStatusPerIndex.get(relayIndex).getLastSwitchingEventTime())) { final RelayStatus relayStatus = new RelayStatus.Builder(device, relayIndex) .withLastSwitchingEventState(isRelayOn, switchingEvent.getDateTime()) @@ -258,7 +270,7 @@ private void createRelayStatus( private void handleSwitchingEvent( final String deviceIdentification, - final Date dateTime, + final Instant dateTime, final EventType eventType, final int index) throws UnknownEntityException { @@ -284,7 +296,10 @@ private void handleSwitchingEvent( } private void updateRelayStatusForEvent( - final int index, final Ssld ssld, final Date dateTime, final EventType eventType) { + final int index, + final Ssld ssld, + final java.time.Instant dateTime, + final EventType eventType) { final boolean isRelayOn = EventType.LIGHT_EVENTS_LIGHT_ON.equals(eventType) @@ -294,8 +309,8 @@ private void updateRelayStatusForEvent( // if the timestamp of the event is after the timestamp of the last // switching event in the DB. final RelayStatus oldRelayStatus = ssld.getRelayStatusByIndex(index); - final Date eventTime = dateTime == null ? DateTime.now().toDate() : dateTime; - if (oldRelayStatus == null || eventTime.after(oldRelayStatus.getLastSwitchingEventTime())) { + final Instant eventTime = dateTime == null ? Instant.now() : dateTime; + if (oldRelayStatus == null || eventTime.isAfter(oldRelayStatus.getLastSwitchingEventTime())) { LOGGER.info( "Handling new event {} for device {} to update the relay status for index {} with date {}.", eventType.name(), @@ -304,7 +319,7 @@ private void updateRelayStatusForEvent( dateTime); if (ssld.getRelayStatusByIndex(index) == null - || eventTime.after(ssld.getRelayStatusByIndex(index).getLastSwitchingEventTime())) { + || eventTime.isAfter(ssld.getRelayStatusByIndex(index).getLastSwitchingEventTime())) { final RelayStatus newRelayState = new RelayStatus.Builder(ssld, index) .withLastSwitchingEventState(isRelayOn, eventTime) @@ -317,7 +332,7 @@ private void updateRelayStatusForEvent( private void handleLightMeasurementDeviceEvent( final String deviceIdentification, - final Date dateTime, + final Instant dateTime, final EventType eventType, final String description, final int index) { @@ -326,7 +341,7 @@ private void handleLightMeasurementDeviceEvent( final Event lightMeasurementDeviceEvent = new Event( deviceIdentification, - dateTime != null ? dateTime : DateTime.now().toDate(), + dateTime != null ? dateTime : Instant.now(), eventType, description, index); diff --git a/osgp/platform/osgp-core/src/main/java/org/opensmartgridplatform/core/application/tasks/ScheduledTaskExecutorService.java b/osgp/platform/osgp-core/src/main/java/org/opensmartgridplatform/core/application/tasks/ScheduledTaskExecutorService.java index 8bbabfd46d8..a814aeebfc8 100644 --- a/osgp/platform/osgp-core/src/main/java/org/opensmartgridplatform/core/application/tasks/ScheduledTaskExecutorService.java +++ b/osgp/platform/osgp-core/src/main/java/org/opensmartgridplatform/core/application/tasks/ScheduledTaskExecutorService.java @@ -7,10 +7,10 @@ import java.sql.Timestamp; import java.time.Instant; import java.time.temporal.ChronoUnit; +import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.function.Predicate; -import java.util.stream.Collectors; import org.opensmartgridplatform.core.application.config.ScheduledTaskExecutorJobConfig; import org.opensmartgridplatform.core.application.services.DeviceRequestMessageService; import org.opensmartgridplatform.domain.core.entities.Device; @@ -63,16 +63,31 @@ private void processStrandedScheduledTasks() { st -> st.getModificationTimeInstant().isBefore(ultimatePendingTime); final List strandedScheduledTasks = - scheduledTasks.stream().filter(pendingExceeded).collect(Collectors.toList()); + scheduledTasks.stream().filter(pendingExceeded).toList(); + + final List retryScheduledTasks = new ArrayList<>(); + final List deleteScheduledTasks = new ArrayList<>(); + strandedScheduledTasks.forEach( strandedScheduledTask -> { if (this.shouldBeRetried(strandedScheduledTask)) { strandedScheduledTask.retryOn(new Date()); + retryScheduledTasks.add(strandedScheduledTask); + LOGGER.info( + "Scheduled task for device {} with correlationUid {} will be retried", + strandedScheduledTask.getDeviceIdentification(), + strandedScheduledTask.getCorrelationId()); } else { - strandedScheduledTask.setFailed("No response received for scheduled task"); + LOGGER.info( + "Scheduled task for device {} with correlationUid {} will be removed", + strandedScheduledTask.getDeviceIdentification(), + strandedScheduledTask.getCorrelationId()); + deleteScheduledTasks.add(strandedScheduledTask); } - this.scheduledTaskRepository.save(strandedScheduledTask); }); + + this.scheduledTaskRepository.saveAll(retryScheduledTasks); + this.scheduledTaskRepository.deleteAll(deleteScheduledTasks); } private boolean shouldBeRetried(final ScheduledTask scheduledTask) { @@ -154,7 +169,7 @@ private static MessageMetadata messageMetadataFromScheduledTaskForDevice( .withMessageType(scheduledTask.getMessageType()) .withDomain(scheduledTask.getDomain()) .withDomainVersion(scheduledTask.getDomainVersion()) - .withIpAddress(getIpAddress(device)) + .withNetworkAddress(getIpAddress(device)) .withNetworkSegmentIds(device.getBtsId(), device.getCellId()) .withMessagePriority(scheduledTask.getMessagePriority()) .withScheduled(true) @@ -167,9 +182,9 @@ private static MessageMetadata messageMetadataFromScheduledTaskForDevice( } private static String getIpAddress(final Device device) { - if (device.getIpAddress() == null && device.getGatewayDevice() != null) { - return device.getGatewayDevice().getIpAddress(); + if (device.getNetworkAddress() == null && device.getGatewayDevice() != null) { + return device.getGatewayDevice().getNetworkAddress(); } - return device.getIpAddress(); + return device.getNetworkAddress(); } } diff --git a/osgp/platform/osgp-core/src/main/java/org/opensmartgridplatform/core/infra/jms/protocol/inbound/messageprocessors/PushNotificationAlarmMessageProcessor.java b/osgp/platform/osgp-core/src/main/java/org/opensmartgridplatform/core/infra/jms/protocol/inbound/messageprocessors/PushNotificationAlarmMessageProcessor.java index 1f1ca32ffed..15af91eca6a 100644 --- a/osgp/platform/osgp-core/src/main/java/org/opensmartgridplatform/core/infra/jms/protocol/inbound/messageprocessors/PushNotificationAlarmMessageProcessor.java +++ b/osgp/platform/osgp-core/src/main/java/org/opensmartgridplatform/core/infra/jms/protocol/inbound/messageprocessors/PushNotificationAlarmMessageProcessor.java @@ -4,7 +4,7 @@ package org.opensmartgridplatform.core.infra.jms.protocol.inbound.messageprocessors; -import java.util.Date; +import java.time.Instant; import java.util.List; import java.util.Optional; import javax.jms.JMSException; @@ -163,7 +163,7 @@ private void storeAlarmAsEvent(final PushNotificationAlarmDto pushNotificationAl */ this.eventNotificationMessageService.handleEvent( pushNotificationAlarm.getDeviceIdentification(), - new Date(), + Instant.now(), org.opensmartgridplatform.domain.core.valueobjects.EventType.ALARM_NOTIFICATION, pushNotificationAlarm.getAlarms().toString(), 0); diff --git a/osgp/platform/osgp-core/src/main/java/org/opensmartgridplatform/core/infra/jms/protocol/inbound/messageprocessors/PushNotificationSmsMessageProcessor.java b/osgp/platform/osgp-core/src/main/java/org/opensmartgridplatform/core/infra/jms/protocol/inbound/messageprocessors/PushNotificationSmsMessageProcessor.java index 6514b5115f8..1e03772d0b2 100644 --- a/osgp/platform/osgp-core/src/main/java/org/opensmartgridplatform/core/infra/jms/protocol/inbound/messageprocessors/PushNotificationSmsMessageProcessor.java +++ b/osgp/platform/osgp-core/src/main/java/org/opensmartgridplatform/core/infra/jms/protocol/inbound/messageprocessors/PushNotificationSmsMessageProcessor.java @@ -4,9 +4,7 @@ package org.opensmartgridplatform.core.infra.jms.protocol.inbound.messageprocessors; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Date; +import java.time.Instant; import javax.jms.JMSException; import javax.jms.ObjectMessage; import org.opensmartgridplatform.core.application.services.EventNotificationMessageService; @@ -73,10 +71,7 @@ public void processMessage(final ObjectMessage message) throws JMSException { requestMessage.getIpAddress(), pushNotificationSms.getIpAddress()); - // Convert the IP address from String to InetAddress. - final InetAddress address = InetAddress.getByName(pushNotificationSms.getIpAddress()); - - device.updateRegistrationData(address, device.getDeviceType()); + device.updateRegistrationData(pushNotificationSms.getIpAddress(), device.getDeviceType()); device.updateConnectionDetailsToSuccess(); this.deviceRepository.save(device); @@ -86,7 +81,7 @@ public void processMessage(final ObjectMessage message) throws JMSException { metadata.getDeviceIdentification()); } - } catch (final UnknownHostException | FunctionalException e) { + } catch (final FunctionalException e) { final String errorMessage = String.format("%s occurred, reason: %s", e.getClass().getName(), e.getMessage()); LOGGER.error(errorMessage, e); @@ -118,7 +113,7 @@ private void storeSmsAsEvent(final PushNotificationSmsDto pushNotificationSms) { */ this.eventNotificationMessageService.handleEvent( pushNotificationSms.getDeviceIdentification(), - new Date(), + Instant.now(), org.opensmartgridplatform.domain.core.valueobjects.EventType.SMS_NOTIFICATION, pushNotificationSms.getIpAddress(), 0); diff --git a/osgp/platform/osgp-core/src/main/java/org/opensmartgridplatform/core/infra/jms/protocol/outbound/ProtocolResponseMessageSender.java b/osgp/platform/osgp-core/src/main/java/org/opensmartgridplatform/core/infra/jms/protocol/outbound/ProtocolResponseMessageSender.java index 0b256201bd3..a248d203c3d 100644 --- a/osgp/platform/osgp-core/src/main/java/org/opensmartgridplatform/core/infra/jms/protocol/outbound/ProtocolResponseMessageSender.java +++ b/osgp/platform/osgp-core/src/main/java/org/opensmartgridplatform/core/infra/jms/protocol/outbound/ProtocolResponseMessageSender.java @@ -79,7 +79,8 @@ private void sendWithDestination( objectMessage.setStringProperty(Constants.DOMAIN, messageMetadata.getDomain()); objectMessage.setStringProperty( Constants.DOMAIN_VERSION, messageMetadata.getDomainVersion()); - objectMessage.setStringProperty(Constants.IP_ADDRESS, messageMetadata.getIpAddress()); + objectMessage.setStringProperty( + Constants.NETWORK_ADDRESS, messageMetadata.getNetworkAddress()); objectMessage.setBooleanProperty(Constants.IS_SCHEDULED, messageMetadata.isScheduled()); objectMessage.setIntProperty(Constants.RETRY_COUNT, messageMetadata.getRetryCount()); objectMessage.setBooleanProperty(Constants.BYPASS_RETRY, messageMetadata.isBypassRetry()); diff --git a/osgp/platform/osgp-core/src/main/resources/db/migration/V202308011603530000__clean_scheduled_tasks.sql b/osgp/platform/osgp-core/src/main/resources/db/migration/V202308011603530000__clean_scheduled_tasks.sql new file mode 100644 index 00000000000..b1a046bb0ef --- /dev/null +++ b/osgp/platform/osgp-core/src/main/resources/db/migration/V202308011603530000__clean_scheduled_tasks.sql @@ -0,0 +1,11 @@ +DO +$$ +BEGIN + +CREATE INDEX IF NOT EXISTS scheduled_task_status_idx on scheduled_task(status); +CREATE INDEX IF NOT EXISTS scheduled_task_scheduled_time_idx on scheduled_task(scheduled_time); + +DELETE FROM scheduled_task WHERE status = 3 AND error_log = 'No response received for scheduled task'; + +END; +$$ diff --git a/osgp/platform/osgp-core/src/main/resources/osgp-core.properties b/osgp/platform/osgp-core/src/main/resources/osgp-core.properties index 1728f9750ab..d3f8b1becb3 100644 --- a/osgp/platform/osgp-core/src/main/resources/osgp-core.properties +++ b/osgp/platform/osgp-core/src/main/resources/osgp-core.properties @@ -252,3 +252,6 @@ device.network.address.cleanup.never=false # This is a comma separated list of either literal IP addresses, or of # ranges with a from address and a to address separated by a dash (-). device.network.address.cleanup.duplicates.allowed= + +# Enable or disable persisting events to database. +event.persist.enabled=true diff --git a/osgp/platform/osgp-core/src/test/java/org/opensmartgridplatform/core/application/services/DeviceNetworkAddressCleanupServiceTest.java b/osgp/platform/osgp-core/src/test/java/org/opensmartgridplatform/core/application/services/DeviceNetworkAddressCleanupServiceTest.java index 064c0b90cef..ebdb79e54a0 100644 --- a/osgp/platform/osgp-core/src/test/java/org/opensmartgridplatform/core/application/services/DeviceNetworkAddressCleanupServiceTest.java +++ b/osgp/platform/osgp-core/src/test/java/org/opensmartgridplatform/core/application/services/DeviceNetworkAddressCleanupServiceTest.java @@ -11,7 +11,6 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import java.net.InetAddress; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -36,11 +35,11 @@ public class DeviceNetworkAddressCleanupServiceTest { private DeviceRepository deviceRepository; private DeviceNetworkAddressCleanupService deviceNetworkAddressCleanupService; private String host; - private InetAddress inetAddress; + private String networkAddress; - private void withHostAndInetAddress(final String host) throws Exception { + private void withHostAndInetAddress(final String host) { this.host = host; - this.inetAddress = InetAddress.getByName(host); + this.networkAddress = host; } private void setUpDeviceNetworkAddressCleanupService( @@ -71,17 +70,17 @@ private void withConfigurationAllowingDuplicatesFor(final String... configuredRa public void noDevicesAreCleanedWhenTheNetworkAddressIsNotUsed() throws Exception { this.withConfigurationNotAllowingDuplicates(); this.withHostAndInetAddress(IP_ADDRESS); - this.theNetworkAddressIsNotUsed(this.inetAddress); + this.theNetworkAddressIsNotUsed(this.networkAddress); this.deviceNetworkAddressCleanupService.clearDuplicateAddresses( DEVICE_IDENTIFICATION, this.host); - verify(this.deviceRepository, times(1)).findByNetworkAddress(this.inetAddress); + verify(this.deviceRepository, times(1)).findByNetworkAddress(this.networkAddress); verify(this.deviceRepository, never()).save(any(Device.class)); } - private void theNetworkAddressIsNotUsed(final InetAddress inetAddress) { - when(this.deviceRepository.findByNetworkAddress(inetAddress)) + private void theNetworkAddressIsNotUsed(final String networkAddress) { + when(this.deviceRepository.findByNetworkAddress(networkAddress)) .thenReturn(Collections.emptyList()); } @@ -93,7 +92,7 @@ public void noDevicesAreCleanedWhenDuplicateAddressesAreAllowed() throws Excepti this.deviceNetworkAddressCleanupService.clearDuplicateAddresses( DEVICE_IDENTIFICATION, this.host); - verify(this.deviceRepository, never()).findByNetworkAddress(this.inetAddress); + verify(this.deviceRepository, never()).findByNetworkAddress(this.networkAddress); verify(this.deviceRepository, never()).save(any(Device.class)); } @@ -106,7 +105,7 @@ public void noDevicesAreCleanedWhenTheNetworkAddressIsExplicitlyAllowedWithDupli this.deviceNetworkAddressCleanupService.clearDuplicateAddresses( DEVICE_IDENTIFICATION, this.host); - verify(this.deviceRepository, never()).findByNetworkAddress(this.inetAddress); + verify(this.deviceRepository, never()).findByNetworkAddress(this.networkAddress); verify(this.deviceRepository, never()).save(any(Device.class)); } @@ -122,7 +121,7 @@ public void noDevicesAreCleanedWhenTheNetworkAddressIsPartOfARangeAllowingDuplic this.deviceNetworkAddressCleanupService.clearDuplicateAddresses( DEVICE_IDENTIFICATION, this.host); - verify(this.deviceRepository, never()).findByNetworkAddress(this.inetAddress); + verify(this.deviceRepository, never()).findByNetworkAddress(this.networkAddress); verify(this.deviceRepository, never()).save(any(Device.class)); } @@ -134,7 +133,7 @@ public void localhostIsAlwaysAllowedToHaveDuplicates() throws Exception { this.deviceNetworkAddressCleanupService.clearDuplicateAddresses( DEVICE_IDENTIFICATION, this.host); - verify(this.deviceRepository, never()).findByNetworkAddress(this.inetAddress); + verify(this.deviceRepository, never()).findByNetworkAddress(this.networkAddress); verify(this.deviceRepository, never()).save(any(Device.class)); } @@ -143,12 +142,12 @@ public void devicesAreCleanedWhenTheNetworkAddressIsNotAllowedToHaveDuplicates() throws Exception { this.withConfigurationNotAllowingDuplicates(); this.withHostAndInetAddress(IP_ADDRESS); - this.theNetworkAddressIsUsedBy(this.inetAddress, "device1", "device2"); + this.theNetworkAddressIsUsedBy(this.networkAddress, "device1", "device2"); this.deviceNetworkAddressCleanupService.clearDuplicateAddresses( DEVICE_IDENTIFICATION, this.host); - verify(this.deviceRepository, times(1)).findByNetworkAddress(this.inetAddress); + verify(this.deviceRepository, times(1)).findByNetworkAddress(this.networkAddress); final ArgumentCaptor deviceCaptor = ArgumentCaptor.forClass(Device.class); verify(this.deviceRepository, times(2)).save(deviceCaptor.capture()); final List savedDevices = deviceCaptor.getAllValues(); @@ -157,17 +156,17 @@ public void devicesAreCleanedWhenTheNetworkAddressIsNotAllowedToHaveDuplicates() } private void theNetworkAddressIsUsedBy( - final InetAddress inetAddress, final String... deviceIdentifications) { + final String networkAddress, final String... deviceIdentifications) { final List devicesWithSameNetworkAddress = Arrays.stream(deviceIdentifications) .map( deviceIdentification -> { final Device device = new Device(deviceIdentification); - device.updateRegistrationData(inetAddress, "deviceType"); + device.updateRegistrationData(networkAddress, "deviceType"); return device; }) .collect(Collectors.toList()); - when(this.deviceRepository.findByNetworkAddress(inetAddress)) + when(this.deviceRepository.findByNetworkAddress(networkAddress)) .thenReturn(devicesWithSameNetworkAddress); } diff --git a/osgp/platform/osgp-core/src/test/java/org/opensmartgridplatform/core/application/services/EventNotificationMessageServiceTest.java b/osgp/platform/osgp-core/src/test/java/org/opensmartgridplatform/core/application/services/EventNotificationMessageServiceTest.java index f33624c3cff..226e61fd59c 100644 --- a/osgp/platform/osgp-core/src/test/java/org/opensmartgridplatform/core/application/services/EventNotificationMessageServiceTest.java +++ b/osgp/platform/osgp-core/src/test/java/org/opensmartgridplatform/core/application/services/EventNotificationMessageServiceTest.java @@ -9,7 +9,7 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verify; -import org.joda.time.DateTime; +import java.time.ZonedDateTime; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentMatcher; @@ -41,7 +41,7 @@ public class EventNotificationMessageServiceTest { void sendsLightSensorReportsLightEventToDomainTest() throws UnknownEntityException { final String deviceUid = "testUid"; final String deviceIdentification = "testIdentification"; - final DateTime dateTime = DateTime.now(); + final ZonedDateTime dateTime = ZonedDateTime.now(); final EventTypeDto eventTypeDto = EventTypeDto.LIGHT_SENSOR_REPORTS_LIGHT; final String description = "Sensor reports light"; final Integer index = 0; diff --git a/osgp/platform/osgp-core/src/test/java/org/opensmartgridplatform/core/application/tasks/ScheduledTaskExecutorServiceTest.java b/osgp/platform/osgp-core/src/test/java/org/opensmartgridplatform/core/application/tasks/ScheduledTaskExecutorServiceTest.java index e1b09df0232..2fde8e6b6be 100644 --- a/osgp/platform/osgp-core/src/test/java/org/opensmartgridplatform/core/application/tasks/ScheduledTaskExecutorServiceTest.java +++ b/osgp/platform/osgp-core/src/test/java/org/opensmartgridplatform/core/application/tasks/ScheduledTaskExecutorServiceTest.java @@ -9,11 +9,9 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import java.net.InetAddress; import java.net.UnknownHostException; import java.sql.Timestamp; import java.time.Instant; @@ -50,7 +48,7 @@ public class ScheduledTaskExecutorServiceTest { private static final String DATA_OBJECT = "data object"; - private static final Timestamp SCHEDULED_TIME = new Timestamp(System.currentTimeMillis()); + private static final Timestamp INITIAL_SCHEDULED_TIME = new Timestamp(System.currentTimeMillis()); @Mock private DeviceRequestMessageService deviceRequestMessageService; @@ -59,7 +57,7 @@ public class ScheduledTaskExecutorServiceTest { @InjectMocks private ScheduledTaskExecutorService scheduledTaskExecutorService; @Mock private ScheduledTaskExecutorJobConfig scheduledTaskExecutorJobConfig; - @Captor private ArgumentCaptor scheduledTaskCaptor; + @Captor private ArgumentCaptor> scheduledTaskCaptor; /** * Test the scheduled task runner for the case when the deviceRequestMessageService gives a @@ -85,7 +83,7 @@ void testRunFunctionalException() .thenReturn(new ArrayList()); final Device device = new Device(); - device.updateRegistrationData(InetAddress.getByName("127.0.0.1"), "deviceType"); + device.updateRegistrationData("127.0.0.1", "deviceType"); when(this.deviceRepository.findByDeviceIdentification(anyString())).thenReturn(device); when(this.scheduledTaskRepository.save(any(ScheduledTask.class))).thenReturn(scheduledTask); when(this.scheduledTaskExecutorJobConfig.scheduledTaskPageSize()).thenReturn(30); @@ -112,17 +110,19 @@ void testRetryStrandedPendingTask() { .thenReturn(-1L); when(this.scheduledTaskExecutorJobConfig.scheduledTaskPageSize()).thenReturn(30); this.whenFindByStatusAndScheduledTime( - expiredPendingTasks, new ArrayList(), new ArrayList()); + expiredPendingTasks, new ArrayList<>(), new ArrayList<>()); this.scheduledTaskExecutorService.processScheduledTasks(); - verify(this.scheduledTaskRepository, times(4)).save(this.scheduledTaskCaptor.capture()); - final List savedScheduledTasks = this.scheduledTaskCaptor.getAllValues(); + verify(this.scheduledTaskRepository).saveAll(this.scheduledTaskCaptor.capture()); + final List retryScheduledTasks = this.scheduledTaskCaptor.getValue(); + assertThat(retryScheduledTasks).hasSize(1); + assertThat(retryScheduledTasks.get(0).getStatus()).isEqualTo(ScheduledTaskStatusType.RETRY); + assertThat(retryScheduledTasks.get(0).getScheduledTime()).isAfter(INITIAL_SCHEDULED_TIME); - assertThat(savedScheduledTasks.get(0).getStatus()).isEqualTo(ScheduledTaskStatusType.FAILED); - assertThat(savedScheduledTasks.get(1).getStatus()).isEqualTo(ScheduledTaskStatusType.RETRY); - assertThat(savedScheduledTasks.get(2).getStatus()).isEqualTo(ScheduledTaskStatusType.FAILED); - assertThat(savedScheduledTasks.get(3).getStatus()).isEqualTo(ScheduledTaskStatusType.FAILED); + verify(this.scheduledTaskRepository).deleteAll(this.scheduledTaskCaptor.capture()); + final List deleteScheduledTasks = this.scheduledTaskCaptor.getValue(); + assertThat(deleteScheduledTasks).hasSize(3); } private void whenFindByStatusAndScheduledTime( @@ -152,20 +152,20 @@ private List createPendingTasks() { private ScheduledTask createScheduledTask( final boolean exceededMaxRetry, final boolean expiredTask) { - MessageMetadata messageMetadata; + final MessageMetadata messageMetadata; if (expiredTask) { messageMetadata = this.createExpiredMessageMetadata(); } else { messageMetadata = this.createMessageMetadata(); } final ScheduledTask expiredScheduledTask = - new ScheduledTask(messageMetadata, DOMAIN, DOMAIN, DATA_OBJECT, SCHEDULED_TIME); + new ScheduledTask(messageMetadata, DOMAIN, DOMAIN, DATA_OBJECT, INITIAL_SCHEDULED_TIME); // retryOn() will raise the number of retries. The retry time will not change since it is the // same as the retry time in the message metadata. State will be set RETRY and will be reset to // PENDING by the setPending method. This is the only way to raise the number of retry above the // maxRetries (0) if (exceededMaxRetry) { - expiredScheduledTask.retryOn(SCHEDULED_TIME); + expiredScheduledTask.retryOn(INITIAL_SCHEDULED_TIME); } expiredScheduledTask.setPending(); return expiredScheduledTask; diff --git a/osgp/platform/osgp-core/src/test/java/org/opensmartgridplatform/core/infra/jms/protocol/inbound/messageprocessors/PushNotificationAlarmMessageProcessorTest.java b/osgp/platform/osgp-core/src/test/java/org/opensmartgridplatform/core/infra/jms/protocol/inbound/messageprocessors/PushNotificationAlarmMessageProcessorTest.java index 42cabe7b120..6d73a3263b4 100644 --- a/osgp/platform/osgp-core/src/test/java/org/opensmartgridplatform/core/infra/jms/protocol/inbound/messageprocessors/PushNotificationAlarmMessageProcessorTest.java +++ b/osgp/platform/osgp-core/src/test/java/org/opensmartgridplatform/core/infra/jms/protocol/inbound/messageprocessors/PushNotificationAlarmMessageProcessorTest.java @@ -11,8 +11,8 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import java.time.Instant; import java.util.Collections; -import java.util.Date; import javax.jms.JMSException; import javax.jms.ObjectMessage; import org.junit.jupiter.api.BeforeEach; @@ -104,7 +104,7 @@ public void init() throws JMSException, UnknownEntityException { .when(this.eventNotificationMessageService) .handleEvent( any(String.class), - any(Date.class), + any(Instant.class), any(EventType.class), any(String.class), any(Integer.class)); diff --git a/osgp/platform/osgp-core/src/test/java/org/opensmartgridplatform/core/infra/jms/protocol/inbound/messageprocessors/PushNotificationSmsMessageProcessorTest.java b/osgp/platform/osgp-core/src/test/java/org/opensmartgridplatform/core/infra/jms/protocol/inbound/messageprocessors/PushNotificationSmsMessageProcessorTest.java index 1f706746c61..ff84d313112 100644 --- a/osgp/platform/osgp-core/src/test/java/org/opensmartgridplatform/core/infra/jms/protocol/inbound/messageprocessors/PushNotificationSmsMessageProcessorTest.java +++ b/osgp/platform/osgp-core/src/test/java/org/opensmartgridplatform/core/infra/jms/protocol/inbound/messageprocessors/PushNotificationSmsMessageProcessorTest.java @@ -11,7 +11,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import java.util.Date; +import java.time.Instant; import javax.jms.JMSException; import javax.jms.ObjectMessage; import org.junit.jupiter.api.BeforeEach; @@ -81,7 +81,7 @@ public void testProcessMessageSuccess() throws JMSException, UnknownEntityExcept .when(this.eventNotificationMessageService) .handleEvent( any(String.class), - any(Date.class), + any(Instant.class), any(EventType.class), any(String.class), any(Integer.class)); diff --git a/osgp/platform/osgp-domain-core/pom.xml b/osgp/platform/osgp-domain-core/pom.xml index 99c0be715ae..3c0d2c58bde 100644 --- a/osgp/platform/osgp-domain-core/pom.xml +++ b/osgp/platform/osgp-domain-core/pom.xml @@ -17,7 +17,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-platform - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-platform/pom.xml diff --git a/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/entities/Device.java b/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/entities/Device.java index 4afd89ec247..25ebc819d36 100644 --- a/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/entities/Device.java +++ b/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/entities/Device.java @@ -4,7 +4,6 @@ package org.opensmartgridplatform.domain.core.entities; -import java.net.InetAddress; import java.time.Instant; import java.util.ArrayList; import java.util.Collection; @@ -33,7 +32,6 @@ import javax.persistence.OneToMany; import javax.persistence.Transient; import org.hibernate.annotations.SortNatural; -import org.hibernate.annotations.Type; import org.opensmartgridplatform.domain.core.valueobjects.Address; import org.opensmartgridplatform.domain.core.valueobjects.CdmaSettings; import org.opensmartgridplatform.domain.core.valueobjects.DeviceFunctionGroup; @@ -89,8 +87,7 @@ public class Device extends AbstractEntity { /** IP address of a device. */ @Column(length = 50) - @Type(type = "org.opensmartgridplatform.shared.hibernate.InetAddressUserType") - protected InetAddress networkAddress; + protected String networkAddress; /** Cell ID on a Base Transceiver Station. */ @Column private Integer cellId; @@ -132,7 +129,7 @@ public class Device extends AbstractEntity { private DeviceModel deviceModel; /** Installation time of this entity. */ - @Column() protected Date technicalInstallationDate; + @Column() protected Instant technicalInstallationDate; /** DeviceLifecycleStatus of this entity */ @Column(nullable = false) @@ -261,15 +258,11 @@ public void setDeviceType(final String deviceType) { this.deviceType = deviceType; } - public String getIpAddress() { - return this.networkAddress == null ? null : this.networkAddress.getHostAddress(); - } - - public InetAddress getNetworkAddress() { + public String getNetworkAddress() { return this.networkAddress; } - public void setNetworkAddress(final InetAddress networkAddress) { + public void setNetworkAddress(final String networkAddress) { this.networkAddress = networkAddress; } @@ -372,7 +365,7 @@ public void updateProtocol(final ProtocolInfo protocolInfo) { this.protocolInfo = protocolInfo; } - public void updateRegistrationData(final InetAddress networkAddress, final String deviceType) { + public void updateRegistrationData(final String networkAddress, final String deviceType) { this.networkAddress = networkAddress; this.deviceType = deviceType; this.isActivated = true; @@ -383,11 +376,11 @@ public void updateGatewayDevice(final Device gatewayDevice) { this.gatewayDevice = gatewayDevice; } - public Date getTechnicalInstallationDate() { + public Instant getTechnicalInstallationDate() { return this.technicalInstallationDate; } - public void setTechnicalInstallationDate(final Date technicalInstallationDate) { + public void setTechnicalInstallationDate(final Instant technicalInstallationDate) { this.technicalInstallationDate = technicalInstallationDate; } diff --git a/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/entities/DeviceFirmwareFile.java b/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/entities/DeviceFirmwareFile.java index cd11b8e8717..4e57cf32156 100644 --- a/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/entities/DeviceFirmwareFile.java +++ b/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/entities/DeviceFirmwareFile.java @@ -4,7 +4,7 @@ package org.opensmartgridplatform.domain.core.entities; -import java.util.Date; +import java.time.Instant; import java.util.Objects; import javax.persistence.Column; import javax.persistence.Entity; @@ -19,7 +19,7 @@ public class DeviceFirmwareFile extends AbstractEntity implements Comparable findByNetworkAddress(InetAddress address); + List findByNetworkAddress(String address); @Query( "SELECT d " @@ -80,7 +79,7 @@ Device findByDeviceIdentificationWithFirmwareModules( + " auth.functionGroup = org.opensmartgridplatform.domain.core.valueobjects.DeviceFunctionGroup.INSTALLATION)" + ") AND " + "d.modificationTime >= ?2") - List findRecentDevices(Organisation organisation, Date fromDate); + List findRecentDevices(Organisation organisation, Instant fromDate); /* * We need these native queries below because these entities don't have an diff --git a/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/repositories/EventRepository.java b/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/repositories/EventRepository.java index dd4ab8aeb2e..8bc13676524 100644 --- a/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/repositories/EventRepository.java +++ b/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/repositories/EventRepository.java @@ -4,8 +4,8 @@ package org.opensmartgridplatform.domain.core.repositories; +import java.time.Instant; import java.util.Collection; -import java.util.Date; import java.util.List; import org.opensmartgridplatform.domain.core.entities.Device; import org.opensmartgridplatform.domain.core.entities.Event; @@ -32,9 +32,9 @@ public interface EventRepository List findTop2ByDeviceIdentificationOrderByDateTimeDesc(String deviceIdentification); - List findByDateTimeBefore(Date date); + List findByDateTimeBefore(Instant date); - Slice findByDateTimeBefore(Date date, Pageable pageable); + Slice findByDateTimeBefore(Instant date, Pageable pageable); @Modifying @Query("delete from Event e where e.id in :ids") diff --git a/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/repositories/SmartMeterRepository.java b/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/repositories/SmartMeterRepository.java index fdeebf4403a..7117169ef0e 100644 --- a/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/repositories/SmartMeterRepository.java +++ b/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/repositories/SmartMeterRepository.java @@ -36,4 +36,6 @@ SmartMeter findByMBusIdentificationNumber( @Query("select s from SmartMeter s where s.gatewayDevice = ?1 and s.channel = ?2") SmartMeter findByGatewayDeviceAndChannel(Device gatewayDevice, Short channel); + + List findByGatewayDevice(Device gatewayDevice); } diff --git a/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/services/SmartMeterDomainService.java b/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/services/SmartMeterDomainService.java index 327d9d4ac1f..1d7e719dfaf 100644 --- a/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/services/SmartMeterDomainService.java +++ b/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/services/SmartMeterDomainService.java @@ -4,6 +4,8 @@ package org.opensmartgridplatform.domain.core.services; +import com.google.common.collect.Lists; +import java.util.List; import org.opensmartgridplatform.domain.core.entities.SmartMeter; import org.opensmartgridplatform.domain.core.exceptions.InactiveDeviceException; import org.opensmartgridplatform.domain.core.exceptions.UnknownEntityException; @@ -66,4 +68,19 @@ public SmartMeter searchActiveSmartMeter( return smartMeter; } + + /** + * Search the MBus Devices coupled on this SmartMeter. + * + * @param smartMeter + * @return the active device for the given identification + * @throws FunctionalException when the device is not in the database or is not in use + */ + public List searchMBusDevicesFor(final SmartMeter smartMeter) { + + if (smartMeter.getChannel() == null || smartMeter.getChannel() == 0) { + return this.smartMeterRepository.findByGatewayDevice(smartMeter); + } + return Lists.newArrayList(); + } } diff --git a/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/specifications/EventSpecifications.java b/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/specifications/EventSpecifications.java index 395e6a74edb..896f5ed165b 100644 --- a/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/specifications/EventSpecifications.java +++ b/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/specifications/EventSpecifications.java @@ -4,7 +4,7 @@ package org.opensmartgridplatform.domain.core.specifications; -import java.util.Date; +import java.time.Instant; import java.util.List; import org.opensmartgridplatform.domain.core.entities.Event; import org.opensmartgridplatform.domain.core.entities.Organisation; @@ -12,9 +12,9 @@ import org.springframework.data.jpa.domain.Specification; public interface EventSpecifications { - Specification isCreatedAfter(final Date dateFrom); + Specification isCreatedAfter(final Instant dateFrom); - Specification isCreatedBefore(final Date dateUntil); + Specification isCreatedBefore(final Instant dateUntil); Specification isFromDevice(final String deviceIdentification); diff --git a/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/CdmaDevice.java b/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/CdmaDevice.java index c32e3efc23a..e0f961d5d27 100644 --- a/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/CdmaDevice.java +++ b/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/CdmaDevice.java @@ -4,19 +4,18 @@ package org.opensmartgridplatform.domain.core.valueobjects; -import java.net.InetAddress; import java.util.Objects; public class CdmaDevice { - private String deviceIdentification; - private InetAddress networkAddress; - private String mastSegmentName; - private Short batchNumber; + private final String deviceIdentification; + private final String networkAddress; + private final String mastSegmentName; + private final Short batchNumber; public CdmaDevice( final String deviceIdentification, - final InetAddress networkAddress, + final String networkAddress, final String mastSegmentName, final Short batchNumber) { this.deviceIdentification = deviceIdentification; @@ -29,7 +28,7 @@ public String getDeviceIdentification() { return this.deviceIdentification; } - public InetAddress getNetworkAddress() { + public String getNetworkAddress() { return this.networkAddress; } diff --git a/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/Configuration.java b/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/Configuration.java index d6cd903218a..59da645d300 100644 --- a/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/Configuration.java +++ b/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/Configuration.java @@ -5,9 +5,9 @@ package org.opensmartgridplatform.domain.core.valueobjects; import java.io.Serializable; +import java.time.ZonedDateTime; import java.util.List; import javax.validation.Valid; -import org.joda.time.DateTime; import org.opensmartgridplatform.domain.core.validation.LightTypeAndConfiguration; import org.opensmartgridplatform.domain.core.validation.TlsConfiguration; @@ -26,51 +26,51 @@ public class Configuration implements Serializable { private final LinkType preferredLinkType; - private Integer timeSyncFrequency; + private final Integer timeSyncFrequency; - private DeviceFixedIp deviceFixedIp; + private final DeviceFixedIp deviceFixedIp; - private Boolean dhcpEnabled; + private final Boolean dhcpEnabled; - private Boolean tlsEnabled; + private final Boolean tlsEnabled; - private Integer tlsPortNumber; + private final Integer tlsPortNumber; - private String commonNameString; + private final String commonNameString; - private Integer communicationTimeout; + private final Integer communicationTimeout; - private Integer communicationNumberOfRetries; + private final Integer communicationNumberOfRetries; - private Integer communicationPauseTimeBetweenConnectionTrials; + private final Integer communicationPauseTimeBetweenConnectionTrials; - private String osgpIpAddress; + private final String osgpIpAddress; - private Integer osgpPortNumber; + private final Integer osgpPortNumber; - private String ntpHost; + private final String ntpHost; - private Boolean ntpEnabled; + private final Boolean ntpEnabled; - private Integer ntpSyncInterval; + private final Integer ntpSyncInterval; - private Boolean testButtonEnabled; + private final Boolean testButtonEnabled; - private Boolean automaticSummerTimingEnabled; + private final Boolean automaticSummerTimingEnabled; - private Integer astroGateSunRiseOffset; + private final Integer astroGateSunRiseOffset; - private Integer astroGateSunSetOffset; + private final Integer astroGateSunSetOffset; - private List switchingDelays; + private final List switchingDelays; - private List relayLinking; + private final List relayLinking; - private Boolean relayRefreshing; + private final Boolean relayRefreshing; - private DateTime summerTimeDetails; + private final ZonedDateTime summerTimeDetails; - private DateTime winterTimeDetails; + private final ZonedDateTime winterTimeDetails; private Configuration(final Configuration.Builder builder) { this.lightType = builder.lightType; @@ -203,11 +203,11 @@ public List getRelayLinking() { return this.relayLinking; } - public DateTime getSummerTimeDetails() { + public ZonedDateTime getSummerTimeDetails() { return this.summerTimeDetails; } - public DateTime getWinterTimeDetails() { + public ZonedDateTime getWinterTimeDetails() { return this.winterTimeDetails; } @@ -237,8 +237,8 @@ public static class Builder { private List switchingDelays; private List relayLinking; private Boolean relayRefreshing; - private DateTime summerTimeDetails; - private DateTime winterTimeDetails; + private ZonedDateTime summerTimeDetails; + private ZonedDateTime winterTimeDetails; public Builder withLightType(final LightType lightType) { this.lightType = lightType; @@ -367,12 +367,12 @@ public Builder withRelayRefreshing(final Boolean relayRefreshing) { return this; } - public Builder withSummerTimeDetails(final DateTime summerTimeDetails) { + public Builder withSummerTimeDetails(final ZonedDateTime summerTimeDetails) { this.summerTimeDetails = summerTimeDetails; return this; } - public Builder withWinterTimeDetails(final DateTime winterTimeDetails) { + public Builder withWinterTimeDetails(final ZonedDateTime winterTimeDetails) { this.winterTimeDetails = winterTimeDetails; return this; } diff --git a/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/TransitionMessageDataContainer.java b/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/TransitionMessageDataContainer.java index 527bf9e8227..83d4ddf8a2d 100644 --- a/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/TransitionMessageDataContainer.java +++ b/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/TransitionMessageDataContainer.java @@ -5,7 +5,7 @@ package org.opensmartgridplatform.domain.core.valueobjects; import java.io.Serializable; -import org.joda.time.DateTime; +import java.time.ZonedDateTime; public class TransitionMessageDataContainer implements Serializable { @@ -13,13 +13,13 @@ public class TransitionMessageDataContainer implements Serializable { private static final long serialVersionUID = -6687122715307445705L; private TransitionType transitionType; - private DateTime dateTime; + private ZonedDateTime dateTime; public void setTransitionType(final TransitionType transitionType) { this.transitionType = transitionType; } - public void setDateTime(final DateTime dateTime) { + public void setDateTime(final ZonedDateTime dateTime) { this.dateTime = dateTime; } @@ -27,7 +27,7 @@ public TransitionType getTransitionType() { return this.transitionType; } - public DateTime getDateTime() { + public ZonedDateTime getDateTime() { return this.dateTime; } } diff --git a/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/smartmetering/BitErrorRateType.java b/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/smartmetering/BitErrorRateType.java deleted file mode 100644 index c270db07a46..00000000000 --- a/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/smartmetering/BitErrorRateType.java +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-FileCopyrightText: Copyright Contributors to the GXF project -// -// SPDX-License-Identifier: Apache-2.0 - -package org.opensmartgridplatform.domain.core.valueobjects.smartmetering; - -public enum BitErrorRateType { - RXQUAL_0, - RXQUAL_1, - RXQUAL_2, - RXQUAL_3, - RXQUAL_4, - RXQUAL_5, - RXQUAL_6, - RXQUAL_7, - NOT_KNOWN_OR_NOT_DETECTABLE; - - public String value() { - return this.name(); - } - - public static BitErrorRateType fromValue(final String v) { - return valueOf(v); - } -} diff --git a/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/smartmetering/CellInfo.java b/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/smartmetering/CellInfo.java index 868b44f4914..62bd2047606 100644 --- a/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/smartmetering/CellInfo.java +++ b/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/smartmetering/CellInfo.java @@ -16,7 +16,7 @@ public class CellInfo implements Serializable { private final SignalQualityType signalQuality; - private final BitErrorRateType bitErrorRate; + private final short bitErrorRate; private final int mobileCountryCode; @@ -28,7 +28,7 @@ public CellInfo( final long cellId, final int locationId, final SignalQualityType signalQuality, - final BitErrorRateType bitErrorRate, + final short bitErrorRate, final int mobileCountryCode, final int mobileNetworkCode, final long channelNumber) { @@ -53,7 +53,7 @@ public SignalQualityType getSignalQuality() { return this.signalQuality; } - public BitErrorRateType getBitErrorRate() { + public short getBitErrorRate() { return this.bitErrorRate; } diff --git a/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/smartmetering/ConfigurationFlagType.java b/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/smartmetering/ConfigurationFlagType.java index 965ac9c220a..5b69006f26f 100644 --- a/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/smartmetering/ConfigurationFlagType.java +++ b/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/smartmetering/ConfigurationFlagType.java @@ -9,12 +9,12 @@ public enum ConfigurationFlagType { DISCOVER_ON_POWER_ON, DYNAMIC_MBUS_ADDRESS, PO_ENABLE, - HLS_3_ON_P_3_ENABLE, - HLS_4_ON_P_3_ENABLE, - HLS_5_ON_P_3_ENABLE, - HLS_3_ON_PO_ENABLE, - HLS_4_ON_PO_ENABLE, - HLS_5_ON_PO_ENABLE, + HLS_3_ON_P3_ENABLE, + HLS_4_ON_P3_ENABLE, + HLS_5_ON_P3_ENABLE, + HLS_3_ON_P0_ENABLE, + HLS_4_ON_P0_ENABLE, + HLS_5_ON_P0_ENABLE, DIRECT_ATTACH_AT_POWER_ON, HLS_6_ON_P3_ENABLE, HLS_7_ON_P3_ENABLE, diff --git a/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/smartmetering/CosemDate.java b/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/smartmetering/CosemDate.java index 0c78bd3ae6e..21b96f2999b 100644 --- a/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/smartmetering/CosemDate.java +++ b/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/smartmetering/CosemDate.java @@ -5,7 +5,7 @@ package org.opensmartgridplatform.domain.core.valueobjects.smartmetering; import java.io.Serializable; -import org.joda.time.LocalDate; +import java.time.LocalDate; public class CosemDate implements Serializable, Comparable { @@ -43,7 +43,7 @@ public CosemDate(final int year, final int month, final int dayOfMonth) { } public CosemDate(final LocalDate date) { - this(date.getYear(), date.getMonthOfYear(), date.getDayOfMonth(), DAY_OF_WEEK_NOT_SPECIFIED); + this(date.getYear(), date.getMonthValue(), date.getDayOfMonth(), DAY_OF_WEEK_NOT_SPECIFIED); } public CosemDate(final CosemDate cosemDate) { @@ -259,7 +259,7 @@ public boolean isLocalDateSpecified() { */ public LocalDate asLocalDate() { if (this.isLocalDateSpecified()) { - return new LocalDate(this.year, this.month, this.dayOfMonth); + return LocalDate.of(this.year, this.month, this.dayOfMonth); } return null; } diff --git a/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/smartmetering/CosemDateTime.java b/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/smartmetering/CosemDateTime.java index fc0a95c0b35..11bf08136cb 100644 --- a/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/smartmetering/CosemDateTime.java +++ b/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/smartmetering/CosemDateTime.java @@ -5,14 +5,14 @@ package org.opensmartgridplatform.domain.core.valueobjects.smartmetering; import java.io.Serializable; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZonedDateTime; import java.util.EnumSet; import java.util.Objects; import java.util.Set; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.joda.time.LocalDate; -import org.joda.time.LocalDateTime; -import org.joda.time.LocalTime; +import org.opensmartgridplatform.shared.utils.JavaTimeHelpers; public class CosemDateTime implements Serializable, Comparable { @@ -69,7 +69,7 @@ public CosemDateTime(final LocalDateTime dateTime, final int deviation) { this(dateTime.toLocalDate(), dateTime.toLocalTime(), deviation); } - public CosemDateTime(final DateTime dateTime) { + public CosemDateTime(final ZonedDateTime dateTime) { this( dateTime.toLocalDate(), dateTime.toLocalTime(), @@ -99,20 +99,20 @@ private boolean isSpecificDeviation(final int deviation) { return deviation >= -720 && deviation <= 720; } - private static int determineDeviation(final DateTime dateTime) { - return -(dateTime.getZone().getOffset(dateTime.getMillis()) / MILLISECONDS_PER_MINUTE); + private static int determineDeviation(final ZonedDateTime dateTime) { + return -(JavaTimeHelpers.getOffsetForZonedDateTimeInMillis(dateTime) / MILLISECONDS_PER_MINUTE); } - private static ClockStatus determineClockStatus(final DateTime dateTime) { + private static ClockStatus determineClockStatus(final ZonedDateTime dateTime) { final Set statusBits = EnumSet.noneOf(ClockStatusBit.class); - if (!dateTime.getZone().isStandardOffset(dateTime.getMillis())) { + if (!JavaTimeHelpers.isDayLightSavingsActive(dateTime)) { statusBits.add(ClockStatusBit.DAYLIGHT_SAVING_ACTIVE); } return new ClockStatus(statusBits); } public CosemDateTime() { - this(DateTime.now()); + this(ZonedDateTime.now()); } @Override @@ -155,24 +155,6 @@ public boolean isDateTimeSpecified() { return this.isLocalDateTimeSpecified() && this.isDeviationSpecified(); } - /** - * Returns this {@link CosemDateTime} as {@link DateTime} if the date, time and deviation are - * specified. - * - * @return this {@link CosemDateTime} as {@link DateTime}, or {@code null} if not {@link - * #isDateTimeSpecified()}. - * @see #isDateTimeSpecified() - */ - public DateTime asDateTime() { - if (!this.isDateTimeSpecified()) { - return null; - } - final LocalDateTime localDateTime = this.asLocalDateTime(); - final DateTimeZone zone = - DateTimeZone.forOffsetMillis(-this.deviation * MILLISECONDS_PER_MINUTE); - return localDateTime.toDateTime(zone); - } - /** * @return {@code true} if the date and time are specified; {@code false} otherwise. * @see #isLocalDateSpecified() @@ -194,7 +176,7 @@ public LocalDateTime asLocalDateTime() { return null; } if (this.time.isSecondNotSpecified()) { - return new LocalDateTime( + return LocalDateTime.of( this.date.getYear(), this.date.getMonth(), this.date.getDayOfMonth(), @@ -202,7 +184,7 @@ public LocalDateTime asLocalDateTime() { this.time.getMinute()); } if (this.time.isHundredthsNotSpecified()) { - return new LocalDateTime( + return LocalDateTime.of( this.date.getYear(), this.date.getMonth(), this.date.getDayOfMonth(), @@ -210,7 +192,7 @@ public LocalDateTime asLocalDateTime() { this.time.getMinute(), this.time.getSecond()); } - return new LocalDateTime( + return LocalDateTime.of( this.date.getYear(), this.date.getMonth(), this.date.getDayOfMonth(), diff --git a/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/smartmetering/CosemTime.java b/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/smartmetering/CosemTime.java index 6b6284c80dd..bc55323950a 100644 --- a/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/smartmetering/CosemTime.java +++ b/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/smartmetering/CosemTime.java @@ -5,7 +5,8 @@ package org.opensmartgridplatform.domain.core.valueobjects.smartmetering; import java.io.Serializable; -import org.joda.time.LocalTime; +import java.time.LocalTime; +import java.time.temporal.ChronoField; public class CosemTime implements Serializable, Comparable { @@ -39,10 +40,10 @@ public CosemTime(final int hour, final int minute) { public CosemTime(final LocalTime time) { this( - time.getHourOfDay(), - time.getMinuteOfHour(), - time.getSecondOfMinute(), - time.getMillisOfSecond() / 10); + time.getHour(), + time.getMinute(), + time.getSecond(), + (int) (time.getLong(ChronoField.MILLI_OF_SECOND) / 10)); } public CosemTime(final CosemTime cosemTime) { @@ -193,12 +194,12 @@ public LocalTime asLocalTime() { return null; } if (SECOND_NOT_SPECIFIED == this.second) { - return new LocalTime(this.hour, this.minute); + return LocalTime.of(this.hour, this.minute); } if (HUNDREDTHS_NOT_SPECIFIED == this.hundredths) { - return new LocalTime(this.hour, this.minute, this.second); + return LocalTime.of(this.hour, this.minute, this.second); } - return new LocalTime(this.hour, this.minute, this.second, this.hundredths * 10); + return LocalTime.of(this.hour, this.minute, this.second, this.hundredths * 10); } public boolean isHourNotSpecified() { diff --git a/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/smartmetering/MeterReadsGas.java b/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/smartmetering/MeterReadsGas.java index aa3db257606..64569317b52 100644 --- a/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/smartmetering/MeterReadsGas.java +++ b/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/smartmetering/MeterReadsGas.java @@ -18,7 +18,7 @@ public class MeterReadsGas extends ActionResponse implements Serializable { public MeterReadsGas( final Date logTime, final OsgpMeterValue consumption, final Date captureTime) { this.logTime = new Date(logTime.getTime()); - this.captureTime = new Date(captureTime.getTime()); + this.captureTime = captureTime == null ? null : new Date(captureTime.getTime()); this.consumption = consumption; } @@ -27,7 +27,7 @@ public Date getLogTime() { } public Date getCaptureTime() { - return new Date(this.captureTime.getTime()); + return this.captureTime == null ? null : new Date(this.captureTime.getTime()); } public OsgpMeterValue getConsumption() { diff --git a/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/smartmetering/SmartMeteringDevice.java b/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/smartmetering/SmartMeteringDevice.java index af9aa277ad5..71993082844 100644 --- a/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/smartmetering/SmartMeteringDevice.java +++ b/osgp/platform/osgp-domain-core/src/main/java/org/opensmartgridplatform/domain/core/valueobjects/smartmetering/SmartMeteringDevice.java @@ -35,6 +35,8 @@ public class SmartMeteringDevice implements Serializable { private String supplier; + private boolean lls1Active; + private boolean hls3Active; private boolean hls4Active; diff --git a/osgp/platform/osgp-domain-distributionautomation/pom.xml b/osgp/platform/osgp-domain-distributionautomation/pom.xml index 02655162b30..ed687818620 100644 --- a/osgp/platform/osgp-domain-distributionautomation/pom.xml +++ b/osgp/platform/osgp-domain-distributionautomation/pom.xml @@ -21,7 +21,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-platform - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-platform/pom.xml diff --git a/osgp/platform/osgp-domain-logging/pom.xml b/osgp/platform/osgp-domain-logging/pom.xml index 52746428d0d..ebef8ece2bd 100644 --- a/osgp/platform/osgp-domain-logging/pom.xml +++ b/osgp/platform/osgp-domain-logging/pom.xml @@ -17,7 +17,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-platform - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-platform/pom.xml diff --git a/osgp/platform/osgp-domain-logging/src/main/java/org/opensmartgridplatform/logging/domain/repositories/DeviceLogItemPagingRepository.java b/osgp/platform/osgp-domain-logging/src/main/java/org/opensmartgridplatform/logging/domain/repositories/DeviceLogItemPagingRepository.java index 616fc35fbb6..9d08c266dc2 100644 --- a/osgp/platform/osgp-domain-logging/src/main/java/org/opensmartgridplatform/logging/domain/repositories/DeviceLogItemPagingRepository.java +++ b/osgp/platform/osgp-domain-logging/src/main/java/org/opensmartgridplatform/logging/domain/repositories/DeviceLogItemPagingRepository.java @@ -4,7 +4,7 @@ package org.opensmartgridplatform.logging.domain.repositories; -import java.util.Date; +import java.time.Instant; import org.opensmartgridplatform.logging.domain.entities.DeviceLogItem; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -21,5 +21,6 @@ public interface DeviceLogItemPagingRepository extends JpaRepository, JpaSpecificationExecutor { - Slice findByModificationTimeBefore(Date endDate, Pageable pageable); + Slice findByModificationTimeBefore(Instant endDate, Pageable pageable); @Modifying @Query("delete from DeviceLogItem d where d.id in :ids") diff --git a/osgp/platform/osgp-domain-microgrids/pom.xml b/osgp/platform/osgp-domain-microgrids/pom.xml index e0e95c27b9a..2061ccaeb28 100644 --- a/osgp/platform/osgp-domain-microgrids/pom.xml +++ b/osgp/platform/osgp-domain-microgrids/pom.xml @@ -18,7 +18,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-platform - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-platform/pom.xml diff --git a/osgp/platform/osgp-logging/pom.xml b/osgp/platform/osgp-logging/pom.xml index 0e7be8e6ddf..1d64c359993 100644 --- a/osgp/platform/osgp-logging/pom.xml +++ b/osgp/platform/osgp-logging/pom.xml @@ -17,7 +17,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-platform - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-platform/pom.xml diff --git a/osgp/platform/osgp-secret-management/pom.xml b/osgp/platform/osgp-secret-management/pom.xml index 47544d35349..ea000c731d1 100644 --- a/osgp/platform/osgp-secret-management/pom.xml +++ b/osgp/platform/osgp-secret-management/pom.xml @@ -16,23 +16,23 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-platform - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-platform/pom.xml 17 - 2.7.2 - 2.7.2 + 2.7.18 + 2.7.15 2.5.0 3.0.0 2.0.1 2.0.1 1.6.3 3.0.0-M5 - 2.7.2 + 2.7.15 ${project.parent.version} - 2.1.214 + 2.2.222 false diff --git a/osgp/platform/osgp-secret-management/src/integration-test/java/org/opensmartgridplatform/secretmanagement/application/SoapServiceSecretManagementIT.java b/osgp/platform/osgp-secret-management/src/integration-test/java/org/opensmartgridplatform/secretmanagement/application/SoapServiceSecretManagementIT.java index 82cc706c01f..30bfd59576e 100644 --- a/osgp/platform/osgp-secret-management/src/integration-test/java/org/opensmartgridplatform/secretmanagement/application/SoapServiceSecretManagementIT.java +++ b/osgp/platform/osgp-secret-management/src/integration-test/java/org/opensmartgridplatform/secretmanagement/application/SoapServiceSecretManagementIT.java @@ -10,7 +10,8 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; -import java.util.Date; +import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.Iterator; import java.util.List; import javax.persistence.EntityManager; @@ -338,15 +339,15 @@ public void generateAndStoreSecretsAlreadyNewSecretPresent() throws IOException */ private void createTestData() { final DbEncryptionKeyReference encryptionKey = new DbEncryptionKeyReference(); - encryptionKey.setCreationTime(new Date()); + encryptionKey.setCreationTime(Instant.now()); encryptionKey.setReference("1"); encryptionKey.setEncryptionProviderType(EncryptionProviderType.JRE); - encryptionKey.setValidFrom(new Date(System.currentTimeMillis() - 60000)); + encryptionKey.setValidFrom(Instant.now().minus(60000, ChronoUnit.MILLIS)); encryptionKey.setVersion(1L); this.testEntityManager.persist(encryptionKey); final DbEncryptedSecret encryptedSecret = new DbEncryptedSecret(); - encryptedSecret.setCreationTime(new Date()); + encryptedSecret.setCreationTime(Instant.now()); encryptedSecret.setDeviceIdentification(DEVICE_IDENTIFICATION); encryptedSecret.setSecretType( org.opensmartgridplatform.secretmanagement.application.domain.SecretType @@ -358,7 +359,7 @@ private void createTestData() { this.testEntityManager.persist(encryptedSecret); final DbEncryptedSecret encryptedSecret2 = new DbEncryptedSecret(); - encryptedSecret2.setCreationTime(new Date()); + encryptedSecret2.setCreationTime(Instant.now()); encryptedSecret2.setDeviceIdentification(DEVICE_IDENTIFICATION); encryptedSecret2.setSecretType( org.opensmartgridplatform.secretmanagement.application.domain.SecretType diff --git a/osgp/platform/osgp-secret-management/src/integration-test/java/org/opensmartgridplatform/secretmanagement/application/repository/DbEncryptedSecretRepositoryIT.java b/osgp/platform/osgp-secret-management/src/integration-test/java/org/opensmartgridplatform/secretmanagement/application/repository/DbEncryptedSecretRepositoryIT.java index a684ff297e5..c3e211f64e5 100644 --- a/osgp/platform/osgp-secret-management/src/integration-test/java/org/opensmartgridplatform/secretmanagement/application/repository/DbEncryptedSecretRepositoryIT.java +++ b/osgp/platform/osgp-secret-management/src/integration-test/java/org/opensmartgridplatform/secretmanagement/application/repository/DbEncryptedSecretRepositoryIT.java @@ -6,7 +6,8 @@ import static org.assertj.core.api.Assertions.assertThat; -import java.util.Date; +import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.List; import org.apache.tomcat.util.buf.HexUtils; import org.junit.jupiter.api.BeforeEach; @@ -29,10 +30,10 @@ public class DbEncryptedSecretRepositoryIT extends AbstractRepositoryIT { @BeforeEach public void persistTestData() { this.dbEncryptionKeyReference = new DbEncryptionKeyReference(); - this.dbEncryptionKeyReference.setCreationTime(new Date()); + this.dbEncryptionKeyReference.setCreationTime(Instant.now()); this.dbEncryptionKeyReference.setReference("keyRef1"); this.dbEncryptionKeyReference.setEncryptionProviderType(EncryptionProviderType.HSM); - this.dbEncryptionKeyReference.setValidFrom(new Date(System.currentTimeMillis() - 60000)); + this.dbEncryptionKeyReference.setValidFrom(Instant.now().minus(60000, ChronoUnit.MILLIS)); this.dbEncryptionKeyReference.setVersion(1L); this.dbEncryptionKeyReference = this.entityManager.persist(this.dbEncryptionKeyReference); final DbEncryptedSecret instance = new DbEncryptedSecret(); @@ -41,7 +42,7 @@ public void persistTestData() { instance.setSecretStatus(SecretStatus.ACTIVE); instance.setEncodedSecret(HexUtils.toHexString("$3cr3t".getBytes())); instance.setEncryptionKeyReference(this.dbEncryptionKeyReference); - instance.setCreationTime(new Date()); + instance.setCreationTime(Instant.now()); this.dbEncryptedSecret = this.entityManager.persist(instance); this.entityManager.flush(); } @@ -74,7 +75,7 @@ public void findSecrets() { @Test public void findSecretsOutdatedKeyRef() { - final Date now = new Date(); + final Instant now = Instant.now(); this.dbEncryptionKeyReference.setValidTo(now); this.dbEncryptionKeyReference = this.entityManager.persist(this.dbEncryptionKeyReference); diff --git a/osgp/platform/osgp-secret-management/src/integration-test/java/org/opensmartgridplatform/secretmanagement/application/repository/DbEncryptionKeyRepositoryIT.java b/osgp/platform/osgp-secret-management/src/integration-test/java/org/opensmartgridplatform/secretmanagement/application/repository/DbEncryptionKeyRepositoryIT.java index c8867f0ca09..46d9b6acf40 100644 --- a/osgp/platform/osgp-secret-management/src/integration-test/java/org/opensmartgridplatform/secretmanagement/application/repository/DbEncryptionKeyRepositoryIT.java +++ b/osgp/platform/osgp-secret-management/src/integration-test/java/org/opensmartgridplatform/secretmanagement/application/repository/DbEncryptionKeyRepositoryIT.java @@ -6,7 +6,8 @@ import static org.assertj.core.api.Assertions.assertThat; -import java.util.Date; +import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -20,26 +21,26 @@ public class DbEncryptionKeyRepositoryIT extends AbstractRepositoryIT { @BeforeEach public void persistTestData() { DbEncryptionKeyReference encryptionKey1 = new DbEncryptionKeyReference(); - encryptionKey1.setCreationTime(new Date()); + encryptionKey1.setCreationTime(Instant.now()); encryptionKey1.setReference("keyRef1"); encryptionKey1.setEncryptionProviderType(EncryptionProviderType.HSM); - encryptionKey1.setValidFrom(new Date(System.currentTimeMillis() - 60000)); + encryptionKey1.setValidFrom(Instant.now().minus(60000, ChronoUnit.MILLIS)); encryptionKey1.setVersion(1L); encryptionKey1 = this.entityManager.persist(encryptionKey1); DbEncryptionKeyReference encryptionKey2 = new DbEncryptionKeyReference(); - encryptionKey2.setCreationTime(new Date()); + encryptionKey2.setCreationTime(Instant.now()); encryptionKey2.setReference("keyRef2"); encryptionKey2.setEncryptionProviderType(EncryptionProviderType.JRE); - encryptionKey2.setValidFrom(new Date(System.currentTimeMillis() - 60000)); - encryptionKey2.setValidTo(new Date(System.currentTimeMillis() + 60000)); + encryptionKey2.setValidFrom(Instant.now().minus(60000, ChronoUnit.MILLIS)); + encryptionKey2.setValidTo(Instant.now().plus(60000, ChronoUnit.MILLIS)); encryptionKey2.setVersion(1L); encryptionKey2 = this.entityManager.persist(encryptionKey2); DbEncryptionKeyReference encryptionKey3 = new DbEncryptionKeyReference(); - encryptionKey3.setCreationTime(new Date()); + encryptionKey3.setCreationTime(Instant.now()); encryptionKey3.setReference("keyRef3"); encryptionKey3.setEncryptionProviderType(EncryptionProviderType.JRE); - encryptionKey3.setValidFrom(new Date(System.currentTimeMillis() - 3600000)); - encryptionKey3.setValidTo(new Date(System.currentTimeMillis() - 60000)); + encryptionKey3.setValidFrom(Instant.now().minus(3600000, ChronoUnit.MILLIS)); + encryptionKey3.setValidTo(Instant.now().minus(60000, ChronoUnit.MILLIS)); encryptionKey3.setVersion(1L); encryptionKey3 = this.entityManager.persist(encryptionKey3); this.entityManager.flush(); @@ -48,7 +49,7 @@ public void persistTestData() { @Test public void findNoValidTo() { final List results = - this.repository.findByTypeAndValid(EncryptionProviderType.HSM, new Date()); + this.repository.findByTypeAndValid(EncryptionProviderType.HSM, Instant.now()); assertThat(results.size()).isEqualTo(1); final DbEncryptionKeyReference keyReference = results.get(0); assertThat(keyReference).isNotNull(); @@ -60,7 +61,7 @@ public void findNoValidTo() { @Test public void findValidTo() { final List results = - this.repository.findByTypeAndValid(EncryptionProviderType.JRE, new Date()); + this.repository.findByTypeAndValid(EncryptionProviderType.JRE, Instant.now()); assertThat(results.size()).isEqualTo(1); final DbEncryptionKeyReference keyReference = results.get(0); assertThat(keyReference).isNotNull(); diff --git a/osgp/platform/osgp-secret-management/src/main/java/org/opensmartgridplatform/secretmanagement/application/domain/DbEncryptedSecret.java b/osgp/platform/osgp-secret-management/src/main/java/org/opensmartgridplatform/secretmanagement/application/domain/DbEncryptedSecret.java index 048b4c0d101..8222c4f2946 100644 --- a/osgp/platform/osgp-secret-management/src/main/java/org/opensmartgridplatform/secretmanagement/application/domain/DbEncryptedSecret.java +++ b/osgp/platform/osgp-secret-management/src/main/java/org/opensmartgridplatform/secretmanagement/application/domain/DbEncryptedSecret.java @@ -4,7 +4,7 @@ package org.opensmartgridplatform.secretmanagement.application.domain; -import java.util.Date; +import java.time.Instant; import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; @@ -35,7 +35,7 @@ public class DbEncryptedSecret { @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "encrypted_secret_seq_gen") private Long id; - private Date creationTime; + private Instant creationTime; private String deviceIdentification; @Enumerated(EnumType.STRING) diff --git a/osgp/platform/osgp-secret-management/src/main/java/org/opensmartgridplatform/secretmanagement/application/domain/DbEncryptionKeyReference.java b/osgp/platform/osgp-secret-management/src/main/java/org/opensmartgridplatform/secretmanagement/application/domain/DbEncryptionKeyReference.java index bf3761d283e..581acc7904d 100644 --- a/osgp/platform/osgp-secret-management/src/main/java/org/opensmartgridplatform/secretmanagement/application/domain/DbEncryptionKeyReference.java +++ b/osgp/platform/osgp-secret-management/src/main/java/org/opensmartgridplatform/secretmanagement/application/domain/DbEncryptionKeyReference.java @@ -4,7 +4,7 @@ package org.opensmartgridplatform.secretmanagement.application.domain; -import java.util.Date; +import java.time.Instant; import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; @@ -30,15 +30,15 @@ public class DbEncryptionKeyReference { @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "encryption_key_seq_gen") private Long id; - private Date creationTime; - private Date modificationTime; + private Instant creationTime; + private Instant modificationTime; private Long version; // for optimistic locking @Enumerated(EnumType.STRING) private EncryptionProviderType encryptionProviderType; private String reference; - private Date validFrom; - private Date validTo; + private Instant validFrom; + private Instant validTo; private String modifiedBy; } diff --git a/osgp/platform/osgp-secret-management/src/main/java/org/opensmartgridplatform/secretmanagement/application/repository/DbEncryptionKeyRepository.java b/osgp/platform/osgp-secret-management/src/main/java/org/opensmartgridplatform/secretmanagement/application/repository/DbEncryptionKeyRepository.java index 647a3bb270a..088d5a89091 100644 --- a/osgp/platform/osgp-secret-management/src/main/java/org/opensmartgridplatform/secretmanagement/application/repository/DbEncryptionKeyRepository.java +++ b/osgp/platform/osgp-secret-management/src/main/java/org/opensmartgridplatform/secretmanagement/application/repository/DbEncryptionKeyRepository.java @@ -4,7 +4,7 @@ package org.opensmartgridplatform.secretmanagement.application.repository; -import java.util.Date; +import java.time.Instant; import java.util.List; import org.opensmartgridplatform.secretmanagement.application.domain.DbEncryptionKeyReference; import org.opensmartgridplatform.shared.security.EncryptionProviderType; @@ -18,7 +18,8 @@ public interface DbEncryptionKeyRepository extends JpaRepository :date) " + "ORDER BY ekr.validFrom DESC") List findByTypeAndValid( - @Param("ept") EncryptionProviderType encryptionProviderType, @Param("date") Date validDate); + @Param("ept") EncryptionProviderType encryptionProviderType, + @Param("date") Instant validDate); @Query( "SELECT ekr FROM DbEncryptionKeyReference ekr WHERE ekr.encryptionProviderType = :ept " diff --git a/osgp/platform/osgp-secret-management/src/main/java/org/opensmartgridplatform/secretmanagement/application/services/EncryptionKeyReferenceCacheService.java b/osgp/platform/osgp-secret-management/src/main/java/org/opensmartgridplatform/secretmanagement/application/services/EncryptionKeyReferenceCacheService.java index c29a855925f..f468f251b8e 100644 --- a/osgp/platform/osgp-secret-management/src/main/java/org/opensmartgridplatform/secretmanagement/application/services/EncryptionKeyReferenceCacheService.java +++ b/osgp/platform/osgp-secret-management/src/main/java/org/opensmartgridplatform/secretmanagement/application/services/EncryptionKeyReferenceCacheService.java @@ -4,8 +4,8 @@ package org.opensmartgridplatform.secretmanagement.application.services; +import java.time.Instant; import java.util.Comparator; -import java.util.Date; import java.util.EnumMap; import java.util.List; import java.util.stream.Collectors; @@ -38,7 +38,7 @@ public DbEncryptionKeyReference getKeyByReference( } public List findAllByTypeAndValid( - final EncryptionProviderType encryptionProviderType, final Date date) { + final EncryptionProviderType encryptionProviderType, final Instant date) { this.initCache(); return this.encryptionKeyReferenceCache.get(encryptionProviderType).stream() @@ -48,10 +48,11 @@ public List findAllByTypeAndValid( .toList(); } - private boolean isValid(final DbEncryptionKeyReference encryptionKeyReference, final Date date) { - return !encryptionKeyReference.getValidFrom().after(date) + private boolean isValid( + final DbEncryptionKeyReference encryptionKeyReference, final Instant date) { + return !encryptionKeyReference.getValidFrom().isAfter(date) && (encryptionKeyReference.getValidTo() == null - || encryptionKeyReference.getValidTo().after(date)); + || encryptionKeyReference.getValidTo().isAfter(date)); } private void initCache() { diff --git a/osgp/platform/osgp-secret-management/src/main/java/org/opensmartgridplatform/secretmanagement/application/services/SecretManagementService.java b/osgp/platform/osgp-secret-management/src/main/java/org/opensmartgridplatform/secretmanagement/application/services/SecretManagementService.java index d3cb700c506..673ee7782af 100644 --- a/osgp/platform/osgp-secret-management/src/main/java/org/opensmartgridplatform/secretmanagement/application/services/SecretManagementService.java +++ b/osgp/platform/osgp-secret-management/src/main/java/org/opensmartgridplatform/secretmanagement/application/services/SecretManagementService.java @@ -9,10 +9,10 @@ import static java.util.stream.Collectors.groupingBy; import static java.util.stream.Collectors.toList; +import java.time.Instant; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; -import java.util.Date; import java.util.EnumMap; import java.util.List; import java.util.Map; @@ -147,7 +147,7 @@ public SecretManagementService( } private DbEncryptionKeyReference getCurrentKey() { - final Date now = new Date(); + final Instant now = Instant.now(); final List keyRefs = this.encryptionKeyReferenceCacheService.findAllByTypeAndValid( this.encryptionProviderType, now); @@ -180,7 +180,7 @@ private DbEncryptedSecret createDbEncrypted( final String deviceIdentification, final EncryptedTypedSecret secret, final DbEncryptionKeyReference keyReference) { - final Date now = new Date(); + final Instant now = Instant.now(); final DbEncryptedSecret dbEncryptedSecret = new DbEncryptedSecret(); dbEncryptedSecret.setDeviceIdentification(deviceIdentification); dbEncryptedSecret.setEncodedSecret(HexUtils.toHexString(secret.encryptedSecret)); diff --git a/osgp/platform/osgp-secret-management/src/main/resources/logback-spring.xml b/osgp/platform/osgp-secret-management/src/main/resources/logback-spring.xml index 5b43d6edd9e..fef9514feeb 100644 --- a/osgp/platform/osgp-secret-management/src/main/resources/logback-spring.xml +++ b/osgp/platform/osgp-secret-management/src/main/resources/logback-spring.xml @@ -35,7 +35,6 @@ SPDX-License-Identifier: Apache-2.0 - diff --git a/osgp/platform/osgp-secret-management/src/test/java/org/opensmartgridplatform/secretmanagement/application/services/EncryptionKeyReferenceCacheServiceTest.java b/osgp/platform/osgp-secret-management/src/test/java/org/opensmartgridplatform/secretmanagement/application/services/EncryptionKeyReferenceCacheServiceTest.java index 643d6701505..ec6d8617f36 100644 --- a/osgp/platform/osgp-secret-management/src/test/java/org/opensmartgridplatform/secretmanagement/application/services/EncryptionKeyReferenceCacheServiceTest.java +++ b/osgp/platform/osgp-secret-management/src/test/java/org/opensmartgridplatform/secretmanagement/application/services/EncryptionKeyReferenceCacheServiceTest.java @@ -9,8 +9,11 @@ import static org.opensmartgridplatform.shared.security.EncryptionProviderType.HSM; import static org.opensmartgridplatform.shared.security.EncryptionProviderType.JRE; +import java.time.LocalDate; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.temporal.ChronoUnit; import java.util.List; -import org.joda.time.DateTime; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; @@ -57,7 +60,10 @@ void findAllByTypeAndValid() { assertThat( this.service.findAllByTypeAndValid( - HSM, new DateTime(this.hsm1.getValidFrom()).minusMillis(1).toDate())) + HSM, + ZonedDateTime.ofInstant(this.hsm1.getValidFrom(), ZoneId.systemDefault()) + .minus(1, ChronoUnit.MILLIS) + .toInstant())) .isEqualTo(List.of()); assertThat(this.service.findAllByTypeAndValid(HSM, this.hsm1.getValidFrom())) .isEqualTo(List.of(this.hsm1)); @@ -67,12 +73,18 @@ HSM, new DateTime(this.hsm1.getValidFrom()).minusMillis(1).toDate())) .isEqualTo(List.of(this.hsm2)); assertThat( this.service.findAllByTypeAndValid( - HSM, new DateTime(this.hsm2.getValidTo()).plusSeconds(1).toDate())) + HSM, + ZonedDateTime.ofInstant(this.hsm2.getValidTo(), ZoneId.systemDefault()) + .plusSeconds(1) + .toInstant())) .isEqualTo(List.of()); assertThat( this.service.findAllByTypeAndValid( - JRE, new DateTime(this.jre1.getValidFrom()).minusSeconds(1).toDate())) + JRE, + ZonedDateTime.ofInstant(this.jre1.getValidFrom(), ZoneId.systemDefault()) + .minusSeconds(1) + .toInstant())) .isEqualTo(List.of()); assertThat(this.service.findAllByTypeAndValid(JRE, this.jre1.getValidFrom())) .isEqualTo(List.of(this.jre1)); @@ -82,7 +94,10 @@ JRE, new DateTime(this.jre1.getValidFrom()).minusSeconds(1).toDate())) .isEqualTo(List.of(this.jre2)); assertThat( this.service.findAllByTypeAndValid( - JRE, new DateTime(this.jre2.getValidFrom()).plusDays(100).toDate())) + JRE, + ZonedDateTime.ofInstant(this.jre2.getValidFrom(), ZoneId.systemDefault()) + .plusDays(100) + .toInstant())) .isEqualTo(List.of(this.jre2)); } @@ -95,10 +110,18 @@ private DbEncryptionKeyReference newDbEncryptionKeyReference( dbEncryptionKeyReference.setReference(reference); dbEncryptionKeyReference.setEncryptionProviderType(encryptionProviderType); dbEncryptionKeyReference.setValidFrom( - new DateTime().withTimeAtStartOfDay().plusDays(validFromDaysOffset).toDate()); + LocalDate.now() + .atStartOfDay() + .atZone(ZoneId.systemDefault()) + .plusDays(validFromDaysOffset) + .toInstant()); if (validToDaysOffset != null) { dbEncryptionKeyReference.setValidTo( - new DateTime().withTimeAtStartOfDay().plusDays(validToDaysOffset).toDate()); + LocalDate.now() + .atStartOfDay() + .atZone(ZoneId.systemDefault()) + .plusDays(validToDaysOffset) + .toInstant()); } return dbEncryptionKeyReference; } diff --git a/osgp/platform/osgp-secret-management/src/test/java/org/opensmartgridplatform/secretmanagement/application/services/SecretManagementServiceTest.java b/osgp/platform/osgp-secret-management/src/test/java/org/opensmartgridplatform/secretmanagement/application/services/SecretManagementServiceTest.java index 7ed5747b966..016fa0e6d70 100644 --- a/osgp/platform/osgp-secret-management/src/test/java/org/opensmartgridplatform/secretmanagement/application/services/SecretManagementServiceTest.java +++ b/osgp/platform/osgp-secret-management/src/test/java/org/opensmartgridplatform/secretmanagement/application/services/SecretManagementServiceTest.java @@ -14,8 +14,9 @@ import static org.opensmartgridplatform.secretmanagement.application.domain.SecretType.E_METER_AUTHENTICATION_KEY; import static org.opensmartgridplatform.secretmanagement.application.domain.SecretType.E_METER_MASTER_KEY; +import java.time.Instant; +import java.time.temporal.ChronoUnit; import java.util.Arrays; -import java.util.Date; import java.util.List; import java.util.NoSuchElementException; import org.apache.tomcat.util.buf.HexUtils; @@ -182,7 +183,7 @@ private DbEncryptedSecret getSecret(final SecretType secretType, final int minut secret.setDeviceIdentification(SOME_DEVICE); secret.setSecretStatus(SecretStatus.NEW); secret.setSecretType(secretType); - secret.setCreationTime(new Date(System.currentTimeMillis() - (minutesOld * 60000L))); + secret.setCreationTime(Instant.now().minus(minutesOld * 60000L, ChronoUnit.MILLIS)); secret.setEncodedSecret("1234567890abcdef"); final DbEncryptionKeyReference encryptionKeyReference = new DbEncryptionKeyReference(); encryptionKeyReference.setEncryptionProviderType(EncryptionProviderType.HSM); @@ -303,7 +304,7 @@ public void storeSecretsExistingSecret() throws Exception { final EncryptedSecret encryptedSecret = new EncryptedSecret(ENCRYPTION_PROVIDER_TYPE, "n3w$3cr3t0000001".getBytes()); final DbEncryptedSecret existingDbSecret = new DbEncryptedSecret(); - existingDbSecret.setCreationTime(new Date()); + existingDbSecret.setCreationTime(Instant.now()); existingDbSecret.setSecretType(E_METER_MASTER_KEY); existingDbSecret.setEncodedSecret("1234567890ABCDEF"); existingDbSecret.setDeviceIdentification(SOME_DEVICE); @@ -428,7 +429,7 @@ public void hasNoNewSecret() { @Test public void generateAndStoreSecrets() throws EncrypterException { - final Date now = new Date(); + final Instant now = Instant.now(); final String reference = "1"; final byte[] aesSecret = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; final byte[] secret = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; @@ -455,7 +456,7 @@ public void generateAndStoreSecrets() throws EncrypterException { @Test public void generateAndStoreSecretWhenNewSecretAlreadyExists() throws Exception { - final Date now = new Date(); + final Instant now = Instant.now(); final String reference = "1"; final byte[] aesSecret = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; final byte[] secret = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; @@ -463,7 +464,7 @@ public void generateAndStoreSecretWhenNewSecretAlreadyExists() throws Exception final DbEncryptedSecret dbEncryptedSecret = this.getSecret(SecretType.E_METER_ENCRYPTION_KEY_UNICAST, 100); - final Date originalCreationTime = dbEncryptedSecret.getCreationTime(); + final Instant originalCreationTime = dbEncryptedSecret.getCreationTime(); final DbEncryptionKeyReference keyReference = new DbEncryptionKeyReference(); keyReference.setReference(reference); keyReference.setEncryptionProviderType(ENCRYPTION_PROVIDER_TYPE); @@ -500,7 +501,7 @@ public void generateAndStoreSecretWhenNewSecretAlreadyExists() throws Exception @Test public void generateAndStoreSecretsWhenNewSecretsAlreadyExists() throws Exception { - final Date now = new Date(); + final Instant now = Instant.now(); final String reference = "1"; final byte[] aesSecret = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; final byte[] secret = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; @@ -514,9 +515,9 @@ public void generateAndStoreSecretsWhenNewSecretsAlreadyExists() throws Exceptio this.getSecret(SecretType.E_METER_ENCRYPTION_KEY_UNICAST, 100); final DbEncryptedSecret secretOlderEncryption = this.getSecret(SecretType.E_METER_ENCRYPTION_KEY_UNICAST, 1000); - final Date originalCreationTimeEncryptionSecret = secretOldEncryption.getCreationTime(); + final Instant originalCreationTimeEncryptionSecret = secretOldEncryption.getCreationTime(); - final Date olderCreationTime = secretOlderEncryption.getCreationTime(); + final Instant olderCreationTime = secretOlderEncryption.getCreationTime(); final SecretType encryptionSecretType = SecretType.E_METER_ENCRYPTION_KEY_UNICAST; final SecretType authenticationSecretType = E_METER_AUTHENTICATION_KEY; @@ -544,8 +545,8 @@ public void generateAndStoreSecretsWhenNewSecretsAlreadyExists() throws Exceptio assertThat(secretOldEncryption.getCreationTime()) .isEqualTo(originalCreationTimeEncryptionSecret); assertThat(secretOldEncryption.getSecretStatus()).isEqualTo(SecretStatus.WITHDRAWN); - assertThat(secretOlderEncryption.getCreationTime().getTime()) - .isEqualTo(olderCreationTime.getTime()); + assertThat(secretOlderEncryption.getCreationTime().toEpochMilli()) + .isEqualTo(olderCreationTime.toEpochMilli()); assertThat(secretOlderEncryption.getSecretStatus()).isEqualTo(SecretStatus.WITHDRAWN); } } diff --git a/osgp/platform/osgp-throttling-service/pom.xml b/osgp/platform/osgp-throttling-service/pom.xml index 39afc5ba9c8..aa4f8e35346 100644 --- a/osgp/platform/osgp-throttling-service/pom.xml +++ b/osgp/platform/osgp-throttling-service/pom.xml @@ -17,12 +17,12 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-platform - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-platform/pom.xml - 2.4.0 + 2.7.18 false diff --git a/osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/MaxConcurrencyByBtsCellConfig.java b/osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/MaxConcurrencyByBtsCellConfig.java new file mode 100644 index 00000000000..9e6e41ea7a6 --- /dev/null +++ b/osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/MaxConcurrencyByBtsCellConfig.java @@ -0,0 +1,88 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.throttling; + +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import javax.annotation.PostConstruct; +import org.opensmartgridplatform.throttling.entities.BtsCellConfig; +import org.opensmartgridplatform.throttling.repositories.BtsCellConfigRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import org.springframework.util.StopWatch; + +@Component +public class MaxConcurrencyByBtsCellConfig { + private static final Logger LOGGER = LoggerFactory.getLogger(MaxConcurrencyByBtsCellConfig.class); + + private static final int NO_VALUE_FOUND = -1; + + private final ConcurrentMap maxConcurrencyByBtsCell = new ConcurrentHashMap<>(); + + private final BtsCellConfigRepository btsCellConfigRepository; + + public MaxConcurrencyByBtsCellConfig(final BtsCellConfigRepository btsCellConfigRepository) { + + this.btsCellConfigRepository = btsCellConfigRepository; + } + + @PostConstruct + private void initialize() { + final StopWatch stopWatch = new StopWatch(this.getClass().getSimpleName()); + stopWatch.start(); + this.btsCellConfigRepository + .findAll() + .forEach( + btsCellConfig -> + this.maxConcurrencyByBtsCell.putIfAbsent( + this.getBtsCellKey( + btsCellConfig.getBaseTransceiverStationId(), btsCellConfig.getCellId()), + btsCellConfig.getMaxConcurrency())); + stopWatch.stop(); + LOGGER.info("Init took {}ms", stopWatch.getLastTaskTimeMillis()); + } + + /** + * Clears all cached throttling configuration and initializes the cached information from the + * database. + */ + void reset() { + this.maxConcurrencyByBtsCell.clear(); + this.initialize(); + } + + public void setMaxConcurrency( + final int baseTransceiverStationId, final int cellId, final int maxConcurrency) { + this.maxConcurrencyByBtsCell.put( + this.getBtsCellKey(baseTransceiverStationId, cellId), maxConcurrency); + } + + public Optional getMaxConcurrency(final int baseTransceiverStationId, final int cellId) { + final String btsCellKey = this.getBtsCellKey(baseTransceiverStationId, cellId); + Integer maxConcurrency = this.maxConcurrencyByBtsCell.get(btsCellKey); + if (maxConcurrency == null) { + maxConcurrency = this.updateMaxConcurrencyFromDatabase(baseTransceiverStationId, cellId); + } + return Optional.ofNullable(maxConcurrency != NO_VALUE_FOUND ? maxConcurrency : null); + } + + private int updateMaxConcurrencyFromDatabase( + final int baseTransceiverStationId, final int cellId) { + final int maxConcurrency = + this.btsCellConfigRepository + .findByBaseTransceiverStationIdAndCellId(baseTransceiverStationId, cellId) + .map(BtsCellConfig::getMaxConcurrency) + .orElse(NO_VALUE_FOUND); + final String btsCellKey = this.getBtsCellKey(baseTransceiverStationId, cellId); + this.maxConcurrencyByBtsCell.putIfAbsent(btsCellKey, maxConcurrency); + return this.maxConcurrencyByBtsCell.get(btsCellKey); + } + + private String getBtsCellKey(final int baseTransceiverStationId, final int cellId) { + return String.format("%s-%s", baseTransceiverStationId, cellId); + } +} diff --git a/osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/PermitsByThrottlingConfig.java b/osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/PermitsByThrottlingConfig.java index 96fc1332585..25cb232fd8e 100644 --- a/osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/PermitsByThrottlingConfig.java +++ b/osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/PermitsByThrottlingConfig.java @@ -15,6 +15,7 @@ import org.opensmartgridplatform.throttling.repositories.ThrottlingConfigRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.util.StopWatch; @@ -27,13 +28,16 @@ public class PermitsByThrottlingConfig { private final ThrottlingConfigRepository throttlingConfigRepository; private final PermitRepository permitRepository; + private final int maxWaitForHighPrioInMs; public PermitsByThrottlingConfig( final ThrottlingConfigRepository throttlingConfigRepository, - final PermitRepository permitRepository) { + final PermitRepository permitRepository, + @Value("${max.wait.for.high.prio.in.ms:5000}") final int maxWaitForHighPrioInMs) { this.throttlingConfigRepository = throttlingConfigRepository; this.permitRepository = permitRepository; + this.maxWaitForHighPrioInMs = maxWaitForHighPrioInMs; } /** Clears all cached permit counts and initializes the cached information from the database. */ @@ -49,7 +53,8 @@ public void initialize() { throttlingConfigIdsInDb.forEach( throttlingConfigId -> this.permitsPerSegmentByConfig.putIfAbsent( - throttlingConfigId, new PermitsPerNetworkSegment(this.permitRepository))); + throttlingConfigId, + new PermitsPerNetworkSegment(this.permitRepository, this.maxWaitForHighPrioInMs))); /* Update config */ this.permitsPerSegmentByConfig.entrySet().parallelStream() @@ -76,6 +81,7 @@ public boolean requestPermit( final int baseTransceiverStationId, final int cellId, final int requestId, + final int priority, final int maxConcurrency) { final PermitsPerNetworkSegment permitsPerNetworkSegment = @@ -83,12 +89,18 @@ public boolean requestPermit( throttlingConfigId, this::createAndInitialize); return permitsPerNetworkSegment.requestPermit( - throttlingConfigId, clientId, baseTransceiverStationId, cellId, requestId, maxConcurrency); + throttlingConfigId, + clientId, + baseTransceiverStationId, + cellId, + requestId, + priority, + maxConcurrency); } private PermitsPerNetworkSegment createAndInitialize(final short throttlingConfigId) { final PermitsPerNetworkSegment permitsPerNetworkSegment = - new PermitsPerNetworkSegment(this.permitRepository); + new PermitsPerNetworkSegment(this.permitRepository, this.maxWaitForHighPrioInMs); permitsPerNetworkSegment.initialize(throttlingConfigId); return permitsPerNetworkSegment; } @@ -100,7 +112,8 @@ public void newThrottlingConfigCreated(final short throttlingConfigId) { * throttling configuration. */ this.permitsPerSegmentByConfig.putIfAbsent( - throttlingConfigId, new PermitsPerNetworkSegment(this.permitRepository)); + throttlingConfigId, + new PermitsPerNetworkSegment(this.permitRepository, this.maxWaitForHighPrioInMs)); } public boolean releasePermit( diff --git a/osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/PermitsPerNetworkSegment.java b/osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/PermitsPerNetworkSegment.java index c5c69c6ac95..f4003f771e3 100644 --- a/osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/PermitsPerNetworkSegment.java +++ b/osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/PermitsPerNetworkSegment.java @@ -10,6 +10,7 @@ import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; +import org.opensmartgridplatform.shared.wsheaderattribute.priority.MessagePriorityEnum; import org.opensmartgridplatform.throttling.repositories.PermitRepository; import org.opensmartgridplatform.throttling.repositories.PermitRepository.PermitCountByNetworkSegment; import org.slf4j.Logger; @@ -26,9 +27,12 @@ public class PermitsPerNetworkSegment { new ConcurrentHashMap<>(); private final PermitRepository permitRepository; + private final int maxWaitForHighPrioInMs; - public PermitsPerNetworkSegment(final PermitRepository permitRepository) { + public PermitsPerNetworkSegment( + final PermitRepository permitRepository, final int maxWaitForHighPrioInMs) { this.permitRepository = permitRepository; + this.maxWaitForHighPrioInMs = maxWaitForHighPrioInMs; } public void initialize(final short throttlingConfigId) { @@ -96,16 +100,10 @@ public boolean requestPermit( final int baseTransceiverStationId, final int cellId, final int requestId, + final int priority, final int maxConcurrency) { - final AtomicInteger permitCounter = - this.permitsPerSegment - .computeIfAbsent(baseTransceiverStationId, key -> new ConcurrentHashMap<>()) - .computeIfAbsent(cellId, key -> new AtomicInteger(0)); - - final int numberOfPermitsIfGranted = permitCounter.incrementAndGet(); - if (numberOfPermitsIfGranted > maxConcurrency) { - permitCounter.decrementAndGet(); + if (!this.isPermitAvailable(baseTransceiverStationId, cellId, priority, maxConcurrency)) { return false; } @@ -120,10 +118,12 @@ public boolean releasePermit( final int cellId, final int requestId) { - final AtomicInteger permitCounter = - this.permitsPerSegment - .getOrDefault(baseTransceiverStationId, NO_PERMITS_FOR_STATION) - .getOrDefault(cellId, NO_PERMITS_FOR_CELL); + final AtomicInteger permitCounter = this.getPermitCounter(baseTransceiverStationId, cellId); + + // Notify that permit is released + synchronized (permitCounter) { + permitCounter.notifyAll(); + } final int numberOfPermitsIfReleased = permitCounter.decrementAndGet(); if (numberOfPermitsIfReleased < 0) { @@ -137,6 +137,62 @@ public boolean releasePermit( return numberOfReleasedPermits == 1; } + private boolean isPermitAvailable( + final int baseTransceiverStationId, + final int cellId, + final int priority, + final int maxConcurrency) { + final AtomicInteger permitCounter = this.getPermitCounter(baseTransceiverStationId, cellId); + + final int numberOfPermitsIfGranted = permitCounter.incrementAndGet(); + if (numberOfPermitsIfGranted > maxConcurrency) { + permitCounter.decrementAndGet(); + + if (priority <= MessagePriorityEnum.DEFAULT.getPriority()) { + return false; + } + + // Wait until permit is released + return this.waitUntilPermitIsAvailable( + baseTransceiverStationId, cellId, maxConcurrency, this.maxWaitForHighPrioInMs); + } + return true; + } + + private boolean waitUntilPermitIsAvailable( + final int baseTransceiverStationId, + final int cellId, + final int maxConcurrency, + final int maxWaitForHighPrioInMs) { + final AtomicInteger permitCounter = this.getPermitCounter(baseTransceiverStationId, cellId); + + synchronized (permitCounter) { + try { + final long startTime = System.currentTimeMillis(); + final int wait = 10; + while (System.currentTimeMillis() - startTime < maxWaitForHighPrioInMs) { + permitCounter.wait(wait); + + final int numberOfPermitsIfGranted = permitCounter.incrementAndGet(); + if (numberOfPermitsIfGranted > maxConcurrency) { + permitCounter.decrementAndGet(); + } else { + return true; + } + } + } catch (final InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + return false; + } + + private AtomicInteger getPermitCounter(final int baseTransceiverStationId, final int cellId) { + return this.permitsPerSegment + .computeIfAbsent(baseTransceiverStationId, key -> NO_PERMITS_FOR_STATION) + .computeIfAbsent(cellId, key -> NO_PERMITS_FOR_CELL); + } + @Override public String toString() { return String.format( diff --git a/osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/SegmentedNetworkThrottler.java b/osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/SegmentedNetworkThrottler.java index 09fb7525b64..57af6f2fe1a 100644 --- a/osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/SegmentedNetworkThrottler.java +++ b/osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/SegmentedNetworkThrottler.java @@ -4,19 +4,23 @@ package org.opensmartgridplatform.throttling; +import java.util.Optional; import org.springframework.stereotype.Component; @Component public class SegmentedNetworkThrottler { private final MaxConcurrencyByThrottlingConfig maxConcurrencyByThrottlingConfig; + private final MaxConcurrencyByBtsCellConfig maxConcurrencyByBtsCellConfig; private final PermitsByThrottlingConfig permitsByThrottlingConfig; public SegmentedNetworkThrottler( final MaxConcurrencyByThrottlingConfig maxConcurrencyByThrottlingConfig, + final MaxConcurrencyByBtsCellConfig maxConcurrencyByBtsCellConfig, final PermitsByThrottlingConfig permitsByThrottlingConfig) { this.maxConcurrencyByThrottlingConfig = maxConcurrencyByThrottlingConfig; + this.maxConcurrencyByBtsCellConfig = maxConcurrencyByBtsCellConfig; this.permitsByThrottlingConfig = permitsByThrottlingConfig; } @@ -25,16 +29,26 @@ public boolean requestPermit( final int clientId, final int baseTransceiverStationId, final int cellId, - final int requestId) { + final int requestId, + final int priority) { + final Optional maxConcurrencyBtsCell = + this.maxConcurrencyByBtsCellConfig.getMaxConcurrency(baseTransceiverStationId, cellId); final int maxConcurrency = - this.maxConcurrencyByThrottlingConfig.getMaxConcurrency(throttlingConfigId); + maxConcurrencyBtsCell.orElse( + this.maxConcurrencyByThrottlingConfig.getMaxConcurrency(throttlingConfigId)); if (maxConcurrency < 1) { return false; } return this.permitsByThrottlingConfig.requestPermit( - throttlingConfigId, clientId, baseTransceiverStationId, cellId, requestId, maxConcurrency); + throttlingConfigId, + clientId, + baseTransceiverStationId, + cellId, + requestId, + priority, + maxConcurrency); } public boolean releasePermit( diff --git a/osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/entities/BtsCellConfig.java b/osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/entities/BtsCellConfig.java new file mode 100644 index 00000000000..bb261cd59cc --- /dev/null +++ b/osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/entities/BtsCellConfig.java @@ -0,0 +1,74 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.throttling.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import lombok.EqualsAndHashCode; +import lombok.Getter; + +@Entity +@Getter +@EqualsAndHashCode(exclude = {"id", "maxConcurrency"}) +public class BtsCellConfig { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Short id; + + @Column(name = "bts_id", nullable = false, updatable = false) + private int baseTransceiverStationId; + + @Column(name = "cell_id", nullable = false, updatable = false) + private int cellId; + + @Column(nullable = false) + private int maxConcurrency; + + public BtsCellConfig() { + // no-arg constructor required by JPA specification + } + + public BtsCellConfig( + final int baseTransceiverStationId, final int cellId, final int maxConcurrency) { + this(null, baseTransceiverStationId, cellId, maxConcurrency); + } + + public BtsCellConfig( + final Short id, + final int baseTransceiverStationId, + final int cellId, + final int maxConcurrency) { + this.id = id; + this.baseTransceiverStationId = baseTransceiverStationId; + this.cellId = cellId; + this.maxConcurrency = this.requireNonNegativeMaxConcurrency(maxConcurrency); + } + + private int requireNonNegativeMaxConcurrency(final int maxConcurrency) { + if (maxConcurrency < 0) { + throw new IllegalArgumentException("maxConcurrency must be non-negative: " + maxConcurrency); + } + return maxConcurrency; + } + + public void setMaxConcurrency(final int maxConcurrency) { + this.maxConcurrency = this.requireNonNegativeMaxConcurrency(maxConcurrency); + } + + @Override + public String toString() { + return String.format( + "%s[id=%s, btsId=%s, cellId=%s, maxConcurrency=%d]", + BtsCellConfig.class.getSimpleName(), + this.id, + this.baseTransceiverStationId, + this.cellId, + this.maxConcurrency); + } +} diff --git a/osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/entities/Permit.java b/osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/entities/Permit.java index 38514d15cb6..4598562f6d2 100644 --- a/osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/entities/Permit.java +++ b/osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/entities/Permit.java @@ -41,16 +41,6 @@ protected Permit() { // no-arg constructor required by JPA specification } - public Permit( - final short throttlingConfigId, - final int clientId, - final int baseTransceiverStationId, - final int cellId, - final int requestId) { - - this(null, null, throttlingConfigId, clientId, baseTransceiverStationId, cellId, requestId); - } - public Permit( final Long id, final Instant createdAt, diff --git a/osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/repositories/BtsCellConfigRepository.java b/osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/repositories/BtsCellConfigRepository.java new file mode 100644 index 00000000000..b3e18322125 --- /dev/null +++ b/osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/repositories/BtsCellConfigRepository.java @@ -0,0 +1,17 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.throttling.repositories; + +import java.util.Optional; +import org.opensmartgridplatform.throttling.entities.BtsCellConfig; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface BtsCellConfigRepository extends JpaRepository { + + Optional findByBaseTransceiverStationIdAndCellId( + int baseTransceiverStationId, int cellId); +} diff --git a/osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/web/api/PermitController.java b/osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/web/api/PermitController.java index 540668d4b7f..ca15c6df533 100644 --- a/osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/web/api/PermitController.java +++ b/osgp/platform/osgp-throttling-service/src/main/java/org/opensmartgridplatform/throttling/web/api/PermitController.java @@ -5,6 +5,7 @@ package org.opensmartgridplatform.throttling.web.api; import java.util.Optional; +import org.opensmartgridplatform.shared.wsheaderattribute.priority.MessagePriorityEnum; import org.opensmartgridplatform.throttling.SegmentedNetworkThrottler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -15,6 +16,7 @@ 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.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController @@ -22,6 +24,7 @@ public class PermitController { private static final int NO_ID_PROVIDED = -1; + private static final int NO_PRIORITY_PROVIDED = MessagePriorityEnum.DEFAULT.getPriority(); private static final Logger LOGGER = LoggerFactory.getLogger(PermitController.class); @@ -48,6 +51,7 @@ public PermitController(final SegmentedNetworkThrottler segmentedNetworkThrottle * baseTransceiverStationId} * @param requestId a unique ID for this permit request in the context of the client identified by * {@code clientId} + * @param priority a priority for this permit request * @return an entity with the int value for the number of permits granted based on this request: * {@code 1} with HTTP status {@code 200 OK} if the permit is granted, {@code 0} with HTTP * status {@code 409 CONFLICT} if the request is denied @@ -62,11 +66,13 @@ public ResponseEntity requestPermit( @PathVariable final int clientId, @PathVariable(required = false) final Optional baseTransceiverStationId, @PathVariable(required = false) final Optional cellId, + @RequestParam(name = "priority", required = false) final Optional priority, @RequestBody(required = false) final Optional requestId) { final int actualBaseTransceiverStationId = baseTransceiverStationId.orElse(NO_ID_PROVIDED); final int actualCellId = cellId.orElse(NO_ID_PROVIDED); final int actualRequestId = requestId.orElse(NO_ID_PROVIDED); + final int actualPriority = priority.orElse(NO_PRIORITY_PROVIDED); final boolean granted = this.segmentedNetworkThrottler.requestPermit( @@ -74,13 +80,15 @@ public ResponseEntity requestPermit( clientId, actualBaseTransceiverStationId, actualCellId, - actualRequestId); + actualRequestId, + actualPriority); LOGGER.debug( - "Requesting permit for network segment ({}, {}) using requestId {} for clientId {} and throttlingConfigId {}, granted: {}", + "Requesting permit for network segment ({}, {}) using requestId {} with priority {} for clientId {} and throttlingConfigId {}, granted: {}", actualBaseTransceiverStationId, actualCellId, actualRequestId, + actualPriority, clientId, throttlingConfigId, granted); @@ -144,7 +152,7 @@ public ResponseEntity releasePermit( "Releasing permit for network segment ({}, {}) using requestId {} for clientId {} and throttlingConfigId {}, released: {}", actualBaseTransceiverStationId, actualCellId, - actualRequestId, + requestId, clientId, throttlingConfigId, released); diff --git a/osgp/platform/osgp-throttling-service/src/main/resources/db/migration/V20231120112206453__bts_cell_config.sql b/osgp/platform/osgp-throttling-service/src/main/resources/db/migration/V20231120112206453__bts_cell_config.sql new file mode 100644 index 00000000000..eb291f31525 --- /dev/null +++ b/osgp/platform/osgp-throttling-service/src/main/resources/db/migration/V20231120112206453__bts_cell_config.sql @@ -0,0 +1,17 @@ +CREATE TABLE IF NOT EXISTS bts_cell_config ( + id smallserial PRIMARY KEY, + bts_id integer NOT NULL, + cell_id integer NOT NULL, + max_concurrency integer NOT NULL, + CONSTRAINT bts_cell_config_max_concurrency_non_negative CHECK (max_concurrency > -1), + CONSTRAINT bts_cell_config_bts_id_cell_id_key UNIQUE (bts_id, cell_id) +); + +ALTER TABLE bts_cell_config OWNER TO osp_admin; + +COMMENT ON TABLE bts_cell_config IS 'Configuration for distributed shared database throttling per bts cell.'; + +COMMENT ON COLUMN bts_cell_config.id IS 'Unique technical id of this Bts Cell Config.'; +COMMENT ON COLUMN bts_cell_config.bts_id IS 'Identification of a Base Transceiver Station; determines a network segment with cell_id.'; +COMMENT ON COLUMN bts_cell_config.cell_id IS 'Identification of a Cell belonging with the Base Transceiver Station identified by bts_id.'; +COMMENT ON COLUMN bts_cell_config.max_concurrency IS 'Maximum number of concurrent permits to be granted by throttlers applying this Bts Cell Config.'; \ No newline at end of file diff --git a/osgp/platform/osgp-throttling-service/src/main/resources/osgp-throttling-service.properties b/osgp/platform/osgp-throttling-service/src/main/resources/osgp-throttling-service.properties index 328d307a094..fdc03907db6 100644 --- a/osgp/platform/osgp-throttling-service/src/main/resources/osgp-throttling-service.properties +++ b/osgp/platform/osgp-throttling-service/src/main/resources/osgp-throttling-service.properties @@ -31,5 +31,7 @@ scheduling.task.cleanup.permits.cron.expression=0 0/30 * * * ? # Releasing expired permits will happen in batches of the following size. cleanup.permits.batch.size=100 +max.wait.for.high.prio.in.ms=5000 + # The task to reset in memory counters with db state is executed by cron expression. scheduling.task.reinitialize.state.cron.expression=30 0/30 * * * ? diff --git a/osgp/platform/osgp-throttling-service/src/test/java/org/opensmartgridplatform/throttling/MaxConcurrencyByBtsCellConfigTest.java b/osgp/platform/osgp-throttling-service/src/test/java/org/opensmartgridplatform/throttling/MaxConcurrencyByBtsCellConfigTest.java new file mode 100644 index 00000000000..d1acd355644 --- /dev/null +++ b/osgp/platform/osgp-throttling-service/src/test/java/org/opensmartgridplatform/throttling/MaxConcurrencyByBtsCellConfigTest.java @@ -0,0 +1,66 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.throttling; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.when; + +import java.util.Optional; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.opensmartgridplatform.throttling.entities.BtsCellConfig; +import org.opensmartgridplatform.throttling.repositories.BtsCellConfigRepository; + +@ExtendWith(MockitoExtension.class) +class MaxConcurrencyByBtsCellConfigTest { + @InjectMocks private MaxConcurrencyByBtsCellConfig btsCellConfig; + @Mock private BtsCellConfigRepository btsCellConfigRepository; + + @Test + void shouldFetchFromCache() { + final int btsId = 5; + final int cellId = 6; + final int maxConcurrency = 9; + this.btsCellConfig.setMaxConcurrency(btsId, cellId, maxConcurrency); + + assertThat(this.btsCellConfig.getMaxConcurrency(btsId, cellId)) + .isEqualTo(Optional.of(maxConcurrency)); + verifyNoInteractions(this.btsCellConfigRepository); + } + + @Test + void shouldFetchFromDatabase() { + final short cachedBtsId = 3; + final short cachedCellId = 4; + final int cachedMaxConcurrency = 9; + final short nonCachedBtsId = 5; + final short nonCachedCellId = 6; + final int nonCachedMaxConcurrency = 11; + + this.btsCellConfig.setMaxConcurrency(cachedBtsId, cachedCellId, cachedMaxConcurrency); + when(this.btsCellConfigRepository.findByBaseTransceiverStationIdAndCellId( + nonCachedBtsId, nonCachedCellId)) + .thenReturn( + Optional.of( + new BtsCellConfig(nonCachedBtsId, nonCachedCellId, nonCachedMaxConcurrency))); + + assertThat(this.btsCellConfig.getMaxConcurrency(nonCachedBtsId, nonCachedCellId)) + .isEqualTo(Optional.of(nonCachedMaxConcurrency)); + } + + @Test + void shouldReturnEmptyNonExistent() { + final short btsId = 3; + final short cellId = 4; + when(this.btsCellConfigRepository.findByBaseTransceiverStationIdAndCellId(btsId, cellId)) + .thenReturn(Optional.empty()); + + assertThat(this.btsCellConfig.getMaxConcurrency(btsId, cellId)).isEmpty(); + } +} diff --git a/osgp/platform/osgp-throttling-service/src/test/java/org/opensmartgridplatform/throttling/NetworkTask.java b/osgp/platform/osgp-throttling-service/src/test/java/org/opensmartgridplatform/throttling/NetworkTask.java index c2db9bf9900..8ac31539277 100644 --- a/osgp/platform/osgp-throttling-service/src/test/java/org/opensmartgridplatform/throttling/NetworkTask.java +++ b/osgp/platform/osgp-throttling-service/src/test/java/org/opensmartgridplatform/throttling/NetworkTask.java @@ -10,20 +10,25 @@ public class NetworkTask { - private Random random = new SecureRandom(); + private final Random random = new SecureRandom(); public final int baseTransceiverStationId; public final int cellId; + public final int priority; public final int maxDurationInMillis; public volatile boolean finished = false; public volatile Throwable throwable = null; public NetworkTask( - final int baseTransceiverStationId, final int cellId, final int maxDurationInMillis) { + final int baseTransceiverStationId, + final int cellId, + final int priority, + final int maxDurationInMillis) { this.baseTransceiverStationId = baseTransceiverStationId; this.cellId = cellId; + this.priority = priority; this.maxDurationInMillis = maxDurationInMillis; } diff --git a/osgp/platform/osgp-throttling-service/src/test/java/org/opensmartgridplatform/throttling/NetworkUser.java b/osgp/platform/osgp-throttling-service/src/test/java/org/opensmartgridplatform/throttling/NetworkUser.java index ef8fda6aae8..6c44c936604 100644 --- a/osgp/platform/osgp-throttling-service/src/test/java/org/opensmartgridplatform/throttling/NetworkUser.java +++ b/osgp/platform/osgp-throttling-service/src/test/java/org/opensmartgridplatform/throttling/NetworkUser.java @@ -91,8 +91,10 @@ private void executeThrottled( final int baseTransceiverStationId = networkTask.baseTransceiverStationId; final int cellId = networkTask.cellId; final int clientRequestId = this.requestCounter.incrementAndGet(); + final int priority = networkTask.priority; - final boolean granted = this.requestPermit(baseTransceiverStationId, cellId, clientRequestId); + final boolean granted = + this.requestPermit(baseTransceiverStationId, cellId, clientRequestId, priority); if (!granted) { actionIfPermitDenied.run(); @@ -151,17 +153,21 @@ private void unregisterThrottlingClient() { } private boolean requestPermit( - final int baseTransceiverStationId, final int cellId, final int requestId) { + final int baseTransceiverStationId, + final int cellId, + final int requestId, + final int priority) { final ResponseEntity permitRequestResponse = this.restTemplate.postForEntity( - "/permits/{throttlingConfigId}/{clientId}/{baseTransceiverStationId}/{cellId}", + "/permits/{throttlingConfigId}/{clientId}/{baseTransceiverStationId}/{cellId}?priority={priority}", requestId, Integer.class, this.throttlingConfigId, this.clientId, baseTransceiverStationId, - cellId); + cellId, + priority); return permitRequestResponse.getStatusCode().is2xxSuccessful() && permitRequestResponse.getBody() != null diff --git a/osgp/platform/osgp-throttling-service/src/test/java/org/opensmartgridplatform/throttling/PermitsByThrottlingConfigTest.java b/osgp/platform/osgp-throttling-service/src/test/java/org/opensmartgridplatform/throttling/PermitsByThrottlingConfigTest.java index 5bcd7d37e4c..ee42dfe1e29 100644 --- a/osgp/platform/osgp-throttling-service/src/test/java/org/opensmartgridplatform/throttling/PermitsByThrottlingConfigTest.java +++ b/osgp/platform/osgp-throttling-service/src/test/java/org/opensmartgridplatform/throttling/PermitsByThrottlingConfigTest.java @@ -12,9 +12,9 @@ import java.util.List; import java.util.Map; import org.assertj.core.util.Lists; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.opensmartgridplatform.throttling.entities.ThrottlingConfig; @@ -23,10 +23,18 @@ @ExtendWith(MockitoExtension.class) class PermitsByThrottlingConfigTest { + private static final int MAX_WAIT_FOR_HIGH_PRIO = 1000; @Mock private ThrottlingConfigRepository throttlingConfigRepository; @Mock private PermitRepository permitRepository; - @InjectMocks private PermitsByThrottlingConfig permitsByThrottlingConfig; + private PermitsByThrottlingConfig permitsByThrottlingConfig; + + @BeforeEach + void setUp() { + this.permitsByThrottlingConfig = + new PermitsByThrottlingConfig( + this.throttlingConfigRepository, this.permitRepository, this.MAX_WAIT_FOR_HIGH_PRIO); + } @Test void testInitializeEmpty() { diff --git a/osgp/platform/osgp-throttling-service/src/test/java/org/opensmartgridplatform/throttling/PermitsPerNetworkSegmentTest.java b/osgp/platform/osgp-throttling-service/src/test/java/org/opensmartgridplatform/throttling/PermitsPerNetworkSegmentTest.java index 4600e51d016..cd39cf64d3b 100644 --- a/osgp/platform/osgp-throttling-service/src/test/java/org/opensmartgridplatform/throttling/PermitsPerNetworkSegmentTest.java +++ b/osgp/platform/osgp-throttling-service/src/test/java/org/opensmartgridplatform/throttling/PermitsPerNetworkSegmentTest.java @@ -10,9 +10,9 @@ import java.util.List; import org.assertj.core.util.Lists; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.opensmartgridplatform.throttling.repositories.PermitRepository; @@ -20,9 +20,15 @@ @ExtendWith(MockitoExtension.class) class PermitsPerNetworkSegmentTest { - + private static final int MAX_WAIT_FOR_HIGH_PRIO = 1000; @Mock private PermitRepository permitRepository; - @InjectMocks private PermitsPerNetworkSegment permitsPerNetworkSegment; + private PermitsPerNetworkSegment permitsPerNetworkSegment; + + @BeforeEach + void setUp() { + this.permitsPerNetworkSegment = + new PermitsPerNetworkSegment(this.permitRepository, this.MAX_WAIT_FOR_HIGH_PRIO); + } @Test void testInitializeEmpty() { diff --git a/osgp/platform/osgp-throttling-service/src/test/java/org/opensmartgridplatform/throttling/ThrottlingServiceApplicationIT.java b/osgp/platform/osgp-throttling-service/src/test/java/org/opensmartgridplatform/throttling/ThrottlingServiceApplicationIT.java index 633de4d57b4..3450ee39281 100644 --- a/osgp/platform/osgp-throttling-service/src/test/java/org/opensmartgridplatform/throttling/ThrottlingServiceApplicationIT.java +++ b/osgp/platform/osgp-throttling-service/src/test/java/org/opensmartgridplatform/throttling/ThrottlingServiceApplicationIT.java @@ -16,17 +16,24 @@ import java.util.List; import java.util.Map; import java.util.Random; +import java.util.Timer; +import java.util.TimerTask; import java.util.TreeMap; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +import lombok.extern.slf4j.Slf4j; import org.junit.ClassRule; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import org.opensmartgridplatform.throttling.api.ThrottlingConfig; +import org.opensmartgridplatform.throttling.entities.BtsCellConfig; import org.opensmartgridplatform.throttling.mapping.ThrottlingMapper; +import org.opensmartgridplatform.throttling.repositories.BtsCellConfigRepository; import org.opensmartgridplatform.throttling.repositories.PermitRepository; import org.opensmartgridplatform.throttling.repositories.ThrottlingConfigRepository; import org.springframework.beans.factory.annotation.Autowired; @@ -44,11 +51,13 @@ import org.springframework.test.context.jdbc.Sql; import org.testcontainers.containers.PostgreSQLContainer; +@Slf4j @SpringBootTest( classes = ThrottlingServiceApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) @ContextConfiguration(initializers = ThrottlingServiceApplicationIT.Initializer.class) class ThrottlingServiceApplicationIT { + private static final int MAX_WAIT_FOR_HIGH_PRIO = 1000; @ClassRule private static final PostgreSQLContainer postgreSQLContainer = @@ -68,7 +77,8 @@ public void initialize(final ConfigurableApplicationContext configurableApplicat "spring.datasource.url=" + postgreSQLContainer.getJdbcUrl(), "spring.datasource.username=" + postgreSQLContainer.getUsername(), "spring.datasource.password=" + postgreSQLContainer.getPassword(), - "spring.jpa.show-sql=false") + "spring.jpa.show-sql=false", + "max.wait.for.high.prio.in.ms=" + MAX_WAIT_FOR_HIGH_PRIO) .applyTo(configurableApplicationContext.getEnvironment()); } } @@ -97,11 +107,17 @@ static void afterAll() { private static final String THROTTLING_AND_CLIENT_PATH = "/{throttlingConfigId}/{clientId}"; private static final String NETWORK_SEGMENT_PATH = "/{baseTransceiverStationId}/{cellId}"; private static final String DISCARD_PATH = "/discard/{clientId}/{requestId}"; + private static final String PRIORITY_PARAM = "?priority={priority}"; private static final String PERMITS_URL_FOR_THROTTLING_AND_CLIENT = PERMITS_URL + THROTTLING_AND_CLIENT_PATH; + private static final String PERMITS_URL_FOR_THROTTLING_AND_CLIENT_FOR_REQUEST = + PERMITS_URL_FOR_THROTTLING_AND_CLIENT + PRIORITY_PARAM; private static final String PERMITS_URL_FOR_THROTTLING_AND_CLIENT_AND_NETWORK_SEGMENT = PERMITS_URL_FOR_THROTTLING_AND_CLIENT + NETWORK_SEGMENT_PATH; + private static final String + PERMITS_URL_FOR_THROTTLING_AND_CLIENT_AND_NETWORK_SEGMENT_FOR_REQUEST = + PERMITS_URL_FOR_THROTTLING_AND_CLIENT_AND_NETWORK_SEGMENT + PRIORITY_PARAM; private static final String PERMITS_URL_FOR_DISCARD = PERMITS_URL + DISCARD_PATH; private static final AtomicInteger requestIdCounter = new AtomicInteger(0); @@ -113,10 +129,12 @@ static void afterAll() { @Autowired private ThrottlingMapper throttlingMapper; @Autowired private ThrottlingConfigRepository throttlingConfigRepository; + @Autowired private BtsCellConfigRepository btsCellConfigRepository; @Autowired private PermitRepository permitRepository; @Autowired private MaxConcurrencyByThrottlingConfig maxConcurrencyByThrottlingConfig; + @Autowired private MaxConcurrencyByBtsCellConfig maxConcurrencyByBtsCellConfig; @Autowired private PermitsByThrottlingConfig permitsByThrottlingConfig; @@ -138,6 +156,7 @@ void beforeEach() { void afterEach() { this.permitRepository.deleteAllInBatch(); this.throttlingConfigRepository.deleteAllInBatch(); + this.btsCellConfigRepository.deleteAllInBatch(); } @Test @@ -311,19 +330,222 @@ private ResponseEntity unregisterClient(final int clientId) { void requestPermitForNetworkSegment() { final int baseTransceiverStationId = 98549874; final int cellId = 0; + final int priority = 4; + this.successfullyRequestPermit( + this.existingThrottlingConfigId, + this.registeredClientId, + baseTransceiverStationId, + cellId, + priority); + } + + @ParameterizedTest + @ValueSource(ints = {0, 1}) + void requestPermitForBtsCell(final int maxConcurrency) { + this.maxConcurrencyByBtsCellConfig.reset(); + + final int baseTransceiverStationId = 123; + final int cellId = 1; + final int requestId = 2; + final int priority = 4; + + this.btsCellConfigRepository.save( + new BtsCellConfig(baseTransceiverStationId, cellId, maxConcurrency)); + + if (maxConcurrency == 0) { + this.unsuccessfullyRequestPermit( + this.existingThrottlingConfigId, + this.registeredClientId, + baseTransceiverStationId, + cellId, + requestId, + priority); + } else { + this.successfullyRequestPermit( + this.existingThrottlingConfigId, + this.registeredClientId, + baseTransceiverStationId, + cellId, + priority); + } + } + + @Test + void lowPrioDenyPermit() { + this.maxConcurrencyByBtsCellConfig.reset(); + + final int baseTransceiverStationId = 123; + final int cellId = 1; + final int requestId = 2; + final int maxConcurrency = 1; + final int priority = 4; + + this.btsCellConfigRepository.save( + new BtsCellConfig(baseTransceiverStationId, cellId, maxConcurrency)); this.successfullyRequestPermit( + this.existingThrottlingConfigId, + this.registeredClientId, + baseTransceiverStationId, + cellId, + priority); + + this.unsuccessfullyRequestPermit( + this.existingThrottlingConfigId, + this.registeredClientId, + baseTransceiverStationId, + cellId, + requestId, + priority); + } + + @Test + void highPrioDenyManyRequests() { + this.maxConcurrencyByBtsCellConfig.reset(); + + final int baseTransceiverStationId = 123; + final int cellId = 1; + final int maxConcurrency = 1; + final int priority = 7; + + this.btsCellConfigRepository.save( + new BtsCellConfig(baseTransceiverStationId, cellId, maxConcurrency)); + + assertThat(this.permitRepository.count()).isZero(); + + final int nrOfPermits = 100; + for (int i = 0; i < nrOfPermits - 1; i++) { + log.debug("successfullyReleasePermitWithDelay"); + this.successfullyReleasePermitWithDelay( + this.existingThrottlingConfigId, + this.registeredClientId, + baseTransceiverStationId, + cellId, + (100 + i * 50)); + } + + for (int i = 0; i < nrOfPermits; i++) { + this.successfullyRequestPermit( + this.existingThrottlingConfigId, + this.registeredClientId, + baseTransceiverStationId, + cellId, + priority); + } + // release last permit + this.successfullyReleasePermit( this.existingThrottlingConfigId, this.registeredClientId, baseTransceiverStationId, cellId); + + assertThat(this.permitRepository.count()).isZero(); + } + + @Test + void highPrioDenyPermit() { + this.maxConcurrencyByBtsCellConfig.reset(); + + final int baseTransceiverStationId = 123; + final int cellId = 1; + final int maxConcurrency = 1; + final int priority = 7; + + this.btsCellConfigRepository.save( + new BtsCellConfig(baseTransceiverStationId, cellId, maxConcurrency)); + + this.successfullyRequestPermit( + this.existingThrottlingConfigId, + this.registeredClientId, + baseTransceiverStationId, + cellId, + priority); + + // low prio not possible + this.unsuccessfullyRequestPermit( + this.existingThrottlingConfigId, + this.registeredClientId, + baseTransceiverStationId, + cellId, + requestIdCounter.incrementAndGet(), + 4); + + final int delay = 100; + final long startTime = System.currentTimeMillis(); + // release after delay + this.successfullyReleasePermitWithDelay( + this.existingThrottlingConfigId, + this.registeredClientId, + baseTransceiverStationId, + cellId, + delay); + + // high prio not possible after delay + this.successfullyRequestPermit( + this.existingThrottlingConfigId, + this.registeredClientId, + baseTransceiverStationId, + cellId, + priority); + assertThat(System.currentTimeMillis() - startTime).isGreaterThanOrEqualTo(delay); + } + + @Test + void highPrioDenyPermitMaxTime() { + this.maxConcurrencyByBtsCellConfig.reset(); + + final int baseTransceiverStationId = 123; + final int cellId = 1; + final int maxConcurrency = 1; + final int priority = 7; + + this.btsCellConfigRepository.save( + new BtsCellConfig(baseTransceiverStationId, cellId, maxConcurrency)); + + this.successfullyRequestPermit( + this.existingThrottlingConfigId, + this.registeredClientId, + baseTransceiverStationId, + cellId, + priority); + + final long startTime = System.currentTimeMillis(); + // high prio not possible + this.unsuccessfullyRequestPermit( + this.existingThrottlingConfigId, + this.registeredClientId, + baseTransceiverStationId, + cellId, + requestIdCounter.incrementAndGet(), + priority); + assertThat(System.currentTimeMillis() - startTime) + .isGreaterThanOrEqualTo(MAX_WAIT_FOR_HIGH_PRIO); + } + + private void successfullyReleasePermitWithDelay( + final short existingThrottlingConfigId, + final int registeredClientId, + final int baseTransceiverStationId, + final int cellId, + final long delay) { + final Timer timer = new Timer(); + final TimerTask task = + new TimerTask() { + @Override + public void run() { + ThrottlingServiceApplicationIT.this.successfullyReleasePermit( + existingThrottlingConfigId, registeredClientId, baseTransceiverStationId, cellId); + } + }; // creating timer task + timer.schedule(task, delay); // scheduling the task after the delay } private void successfullyRequestPermit( final short throttlingConfigId, final int clientId, final int baseTransceiverStationId, - final int cellId) { + final int cellId, + final int priority) { this.successfullyRequestPermit( - throttlingConfigId, clientId, baseTransceiverStationId, cellId, null); + throttlingConfigId, clientId, baseTransceiverStationId, cellId, null, priority); } private void successfullyRequestPermit( @@ -331,11 +553,12 @@ private void successfullyRequestPermit( final int clientId, final int baseTransceiverStationId, final int cellId, - final Integer requestId) { + final Integer requestId, + final int priority) { final ResponseEntity responseEntity = this.requestPermit( - throttlingConfigId, clientId, baseTransceiverStationId, cellId, requestId); + throttlingConfigId, clientId, baseTransceiverStationId, cellId, requestId, priority); assertThat(responseEntity.getStatusCode().series()).isEqualTo(HttpStatus.Series.SUCCESSFUL); assertThat(this.numberOfGrantedPermits(responseEntity)).isOne(); @@ -346,11 +569,12 @@ private void unsuccessfullyRequestPermit( final int clientId, final int baseTransceiverStationId, final int cellId, - final Integer requestId) { + final Integer requestId, + final int priority) { final ResponseEntity responseEntity = this.requestPermit( - throttlingConfigId, clientId, baseTransceiverStationId, cellId, requestId); + throttlingConfigId, clientId, baseTransceiverStationId, cellId, requestId, priority); assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.CONFLICT); assertThat(this.numberOfGrantedPermits(responseEntity)).isZero(); @@ -361,17 +585,19 @@ private void nonUniqueRequestIdOnRequestPermit( final int clientId, final int baseTransceiverStationId, final int cellId, - final Integer requestId) { + final Integer requestId, + final int priority) { final ResponseEntity responseEntity = this.testRestTemplate.postForEntity( - PERMITS_URL_FOR_THROTTLING_AND_CLIENT_AND_NETWORK_SEGMENT, + PERMITS_URL_FOR_THROTTLING_AND_CLIENT_AND_NETWORK_SEGMENT_FOR_REQUEST, requestId, JsonNode.class, throttlingConfigId, clientId, baseTransceiverStationId, - cellId); + cellId, + priority); assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.CONFLICT); final JsonNode errorBody = responseEntity.getBody(); @@ -393,9 +619,11 @@ private int numberOfGrantedPermits(final ResponseEntity responseEntity) void requestPermitForUnknownNetworkSegment() { final int requestId = 5534879; + final int priority = 4; final ResponseEntity responseEntity = - this.requestPermit(this.existingThrottlingConfigId, this.registeredClientId, requestId); + this.requestPermit( + this.existingThrottlingConfigId, this.registeredClientId, requestId, priority); assertThat(responseEntity.getStatusCode().series()).isEqualTo(HttpStatus.Series.SUCCESSFUL); } @@ -408,13 +636,24 @@ void requestIdForTheClientMustBeUniqueAcrossPermitRequests() { final int cellId1 = 1; final int baseTransceiverStationId2 = 45; final int cellId2 = 3; + final int priority = 4; final int reusedRequestId = requestIdCounter.incrementAndGet(); this.successfullyRequestPermit( - throttlingConfigId, clientId, baseTransceiverStationId1, cellId1, reusedRequestId); + throttlingConfigId, + clientId, + baseTransceiverStationId1, + cellId1, + reusedRequestId, + priority); this.nonUniqueRequestIdOnRequestPermit( - throttlingConfigId, clientId, baseTransceiverStationId2, cellId2, reusedRequestId); + throttlingConfigId, + clientId, + baseTransceiverStationId2, + cellId2, + reusedRequestId, + priority); } @Test @@ -427,6 +666,7 @@ void atMostMaxConcurrencyPermitsPerNetworkSegmentAreGranted() { final int baseTransceiverStationId = 45910; final int cellId = 2; + final int priority = 4; this.requestPermitsThatAreGranted( throttlingConfigId, clientId, baseTransceiverStationId, cellId, maxConcurrency); @@ -436,7 +676,8 @@ void atMostMaxConcurrencyPermitsPerNetworkSegmentAreGranted() { clientId, baseTransceiverStationId, cellId, - requestIdCounter.incrementAndGet()); + requestIdCounter.incrementAndGet(), + priority); } private void requestPermitsThatAreGranted( @@ -463,8 +704,11 @@ void releasePermitForNetworkSegment() { final int baseTransceiverStationId = 846574; final int cellId = 1; final int requestId = 299164; + final int priority = 4; - this.requestPermit(throttlingConfigId, clientId, baseTransceiverStationId, cellId, requestId); + final ResponseEntity resp = + this.requestPermit( + throttlingConfigId, clientId, baseTransceiverStationId, cellId, requestId, priority); final ResponseEntity responseEntity = this.releasePermit( @@ -478,8 +722,9 @@ void releasePermitForUnknownNetworkSegment() { final short throttlingConfigId = this.existingThrottlingConfigId; final int clientId = this.registeredClientId; final Integer requestId = null; + final int priority = 4; - this.requestPermit(throttlingConfigId, clientId, requestId); + this.requestPermit(throttlingConfigId, clientId, requestId, priority); final ResponseEntity responseEntity = this.releasePermit(throttlingConfigId, clientId, requestId); @@ -507,8 +752,10 @@ void aRequestedPermitIsOnlyReleasedSuccessfullyOnce() { final int clientId = this.registeredClientId; final int baseTransceiverStationId = 59; final int cellId = 1; + final int priority = 4; - this.successfullyRequestPermit(throttlingConfigId, clientId, baseTransceiverStationId, cellId); + this.successfullyRequestPermit( + throttlingConfigId, clientId, baseTransceiverStationId, cellId, priority); this.successfullyReleasePermit(throttlingConfigId, clientId, baseTransceiverStationId, cellId); this.unsuccessfullyReleasePermit( throttlingConfigId, clientId, baseTransceiverStationId, cellId); @@ -521,10 +768,12 @@ void releasePermitAlwaysRemoveDbRecord() { final int baseTransceiverStationId = 59; final int cellId = 1; final int requestId = requestIdCounter.incrementAndGet(); + final int priority = 4; final double secondsSinceEpoch = System.currentTimeMillis() / 1000.0; // First do one successful request/release, so config exist - this.successfullyRequestPermit(throttlingConfigId, clientId, baseTransceiverStationId, cellId); + this.successfullyRequestPermit( + throttlingConfigId, clientId, baseTransceiverStationId, cellId, priority); this.successfullyReleasePermit(throttlingConfigId, clientId, baseTransceiverStationId, cellId); assertThat(this.permitRepository.findAll()).isEmpty(); @@ -552,9 +801,10 @@ void aPermitThatWasGrantedWhereTheClientMissedTheResponseCanBeDiscarded() { final int baseTransceiverStationId = 4375; final int cellId = 3; final int requestId = requestIdCounter.incrementAndGet(); + final int priority = 4; this.successfullyRequestPermit( - throttlingConfigId, clientId, baseTransceiverStationId, cellId, requestId); + throttlingConfigId, clientId, baseTransceiverStationId, cellId, requestId, priority); this.discardPermitThatWasGranted(clientId, requestId); @@ -611,6 +861,9 @@ private void successfullyReleasePermit( this.releasePermit( throttlingConfigId, clientId, baseTransceiverStationId, cellId, requestId); + if (responseEntity.getStatusCode().series() != HttpStatus.Series.SUCCESSFUL) { + log.error(responseEntity.toString()); + } assertThat(responseEntity.getStatusCode().series()).isEqualTo(HttpStatus.Series.SUCCESSFUL); } @@ -639,14 +892,18 @@ private void unsuccessfullyReleasePermit( } private ResponseEntity requestPermit( - final short throttlingConfigId, final int clientId, final Integer requestId) { + final short throttlingConfigId, + final int clientId, + final Integer requestId, + final int priority) { return this.testRestTemplate.postForEntity( - PERMITS_URL_FOR_THROTTLING_AND_CLIENT, + PERMITS_URL_FOR_THROTTLING_AND_CLIENT_FOR_REQUEST, requestId, Integer.class, throttlingConfigId, - clientId); + clientId, + priority); } private ResponseEntity requestPermit( @@ -654,16 +911,18 @@ private ResponseEntity requestPermit( final int clientId, final int baseTransceiverStationId, final int cellId, - final Integer requestId) { + final Integer requestId, + final int priority) { return this.testRestTemplate.postForEntity( - PERMITS_URL_FOR_THROTTLING_AND_CLIENT_AND_NETWORK_SEGMENT, + PERMITS_URL_FOR_THROTTLING_AND_CLIENT_AND_NETWORK_SEGMENT_FOR_REQUEST, requestId, Integer.class, throttlingConfigId, clientId, baseTransceiverStationId, - cellId); + cellId, + priority); } private ResponseEntity releasePermit( @@ -824,6 +1083,7 @@ void multipleWorkersPerformNetworkTasksObservingThrottlingConstraints() { final int maximumBaseTransceiverStationId = 4; final int minimumCellId = 1; final int maximumCellId = 2; + final int priority = 4; final FakeConcurrencyRestrictedNetwork network = new FakeConcurrencyRestrictedNetwork(maxConcurrency); final List networkTasks = @@ -833,7 +1093,8 @@ void multipleWorkersPerformNetworkTasksObservingThrottlingConstraints() { minimumBaseTransceiverStationId, maximumBaseTransceiverStationId, minimumCellId, - maximumCellId); + maximumCellId, + priority); final NetworkTaskQueue networkTaskQueue = new NetworkTaskQueue(); for (final NetworkTask networkTask : networkTasks) { networkTaskQueue.add(networkTask); @@ -894,7 +1155,8 @@ private List createNetworkTasks( final int minimumBaseTransceiverStationId, final int maximumBaseTransceiverStationId, final int minimumCellId, - final int maximumCellId) { + final int maximumCellId, + final int priority) { final List networkTasks = new ArrayList<>(numberOfNetworkTasks); for (int i = 0; i < numberOfNetworkTasks; i++) { @@ -904,6 +1166,7 @@ private List createNetworkTasks( + this.random.nextInt( 1 + maximumBaseTransceiverStationId - minimumBaseTransceiverStationId), minimumCellId + this.random.nextInt(1 + maximumCellId - minimumCellId), + priority, maxDurationInMillis)); } return networkTasks; diff --git a/osgp/platform/parent-platform/pom.xml b/osgp/platform/parent-platform/pom.xml index 7eb18fc3e36..515d830a08c 100644 --- a/osgp/platform/parent-platform/pom.xml +++ b/osgp/platform/parent-platform/pom.xml @@ -13,7 +13,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform super-osgp - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../../../super/pom.xml diff --git a/osgp/platform/pom.xml b/osgp/platform/pom.xml index 4934d1c72e5..d9ea53b5635 100644 --- a/osgp/platform/pom.xml +++ b/osgp/platform/pom.xml @@ -10,7 +10,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform platform - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT pom diff --git a/osgp/pom.xml b/osgp/pom.xml index 1ddb2d37944..39c986592fd 100644 --- a/osgp/pom.xml +++ b/osgp/pom.xml @@ -13,7 +13,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform super-osgp - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../super/pom.xml diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/README.md b/osgp/protocol-adapter-dlms/osgp-dlms/README.md new file mode 100644 index 00000000000..de646cdbba4 --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-dlms/README.md @@ -0,0 +1,58 @@ + + +# DLMS object config module +The DLMS Object Config defined by json files. + +# Object config json file description + +## Objectconfig + + | Path | Description | + |-------------|--------------------------------------------| + | profile | profile name for a protocol type, like SMR | + | version | version of the protocol | + | description | Decription of this profile | + | properties | General property for the complete config | + | objects | List of CosemObjects | + + +## Object + + | Path | Description | + |-------------|---------------------------------------------------------------------------------------------------------------------------------------| + | tag | Tag to be able to lookup the object | + | description | Description of the CosemObject | + | note | Special note to indicate exceptions, like specified in an Addendum | + | class-id | The id of the used class | + | version | The version of the clas | + | obis | obiscode with or without channel replace character 'x' | + | group | one of Abstract objects (ABSTRACT), Electricity related objects (ELECTRICITY), M-bus related objects (MBUS) and Miscellaneous objects | + | meterTypes | Single Phase (SP) or Polyphase (PP) | + | attributes | Attributes. Should match the attributes for this class, as defined in DLMS. | + | properties | Additional properties for handling this object | + + +## Attribute + + | Path | Description | + |-------------------|-----------------------------------------------------| + | id | id of attribute | + | description | description of attribute | + | datatype | datatype name | + | valuetype | defines the source of the value | + | value | the fixed value or null | + | valuebasedonmodel | defines the values if it depends on the devicemodel | + | access | access to attribute - read (R) write (W) | + +### ValueType + +Valuetype can be one of the following: +- DYNAMIC: This value can be updated by the meter, e.g. a meter value +- FIXED_IN_PROFILE: A fixed value, defined in the profile, e.g. a scaler/unit defined in SMR5.0. +- FIXED_IN_METER: A fixed value set in the factory +- SET_BY_CLIENT: A fixed value set by the client during installation +- BASED_ON_MODEL: The value depends on the device model, as defined in the valuesbasedonmodel block diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/pom.xml b/osgp/protocol-adapter-dlms/osgp-dlms/pom.xml index b8943cd5e5f..75bbde77bc7 100644 --- a/osgp/protocol-adapter-dlms/osgp-dlms/pom.xml +++ b/osgp/protocol-adapter-dlms/osgp-dlms/pom.xml @@ -16,7 +16,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-pa-dlms - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-pa-dlms/pom.xml @@ -30,6 +30,13 @@ SPDX-License-Identifier: Apache-2.0 org.apache.maven.plugins maven-jar-plugin ${maven.jar.plugin.version} + + + + test-jar + + + maven-surefire-plugin @@ -92,6 +99,11 @@ SPDX-License-Identifier: Apache-2.0 junit-jupiter-engine test + + org.junit.jupiter + junit-jupiter-params + test + org.assertj assertj-core diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/interfaceclass/InterfaceClass.java b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/interfaceclass/InterfaceClass.java index 9a2946fd364..39123e6e9da 100644 --- a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/interfaceclass/InterfaceClass.java +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/interfaceclass/InterfaceClass.java @@ -30,6 +30,7 @@ public enum InterfaceClass { STATUS_MAPPING(63, 0), DISCONNECT_CONTROL(70, 0), MBUS_CLIENT(72, 1), + MBUS_DIAGNOSTIC(77, 0), // Protocol related interface classes IEC_LOCAL_PORT_SETUP(19, 1), diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/interfaceclass/attribute/MbusDiagnosticAttribute.java b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/interfaceclass/attribute/MbusDiagnosticAttribute.java new file mode 100644 index 00000000000..4da7965bf54 --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/interfaceclass/attribute/MbusDiagnosticAttribute.java @@ -0,0 +1,44 @@ +// Copyright 2023 Alliander N.V. +// SPDX-FileCopyrightText: Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.dlms.interfaceclass.attribute; + +import org.opensmartgridplatform.dlms.interfaceclass.InterfaceClass; + +/** This class contains the attributes defined for IC MbusDiagnostic. */ +public enum MbusDiagnosticAttribute implements AttributeClass { + LOGICAL_NAME(1), + RECEIVED_SIGNAL_STRENGTH(2), + CHANNEL_ID(3), + LINK_STATUS(4), + BROADCAST_FRAMES_COUNT(5), + TRANSMISSIONS_COUNTER(6), + FCS_OK_FRAMES_COUNTER(7), + FCS_NOK_FRAMES_COUNTER(8), + CAPTURE_TIME(9); + + static final InterfaceClass INTERFACE_CLASS = InterfaceClass.MBUS_DIAGNOSTIC; + + private final int attributeId; + + private MbusDiagnosticAttribute(final int attributeId) { + this.attributeId = attributeId; + } + + @Override + public int attributeId() { + return this.attributeId; + } + + @Override + public String attributeName() { + return this.name(); + } + + @Override + public InterfaceClass interfaceClass() { + return INTERFACE_CLASS; + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/Attribute.java b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/Attribute.java index ebccb6883c9..841110cacee 100644 --- a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/Attribute.java +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/Attribute.java @@ -4,14 +4,62 @@ package org.opensmartgridplatform.dlms.objectconfig; -import lombok.Data; +import lombok.Getter; +import lombok.NoArgsConstructor; -@Data +@Getter +@NoArgsConstructor public class Attribute { private int id; private String description; + private String note; private DlmsDataType datatype; private ValueType valuetype; private String value; + private ValueBasedOnModel valuebasedonmodel; private AccessType access; + + public Attribute( + final int id, + final String description, + final String note, + final DlmsDataType datatype, + final ValueType valuetype, + final String value, + final ValueBasedOnModel valuebasedonmodel, + final AccessType access) { + this.id = id; + this.description = description; + this.note = note; + this.datatype = datatype; + this.valuetype = valuetype; + this.value = value; + this.valuebasedonmodel = valuebasedonmodel; + this.access = access; + } + + public Attribute copy() { + return new Attribute( + this.id, + this.description, + this.note, + this.datatype, + this.valuetype, + this.value, + this.valuebasedonmodel == null ? null : this.valuebasedonmodel.copy(), + this.access); + } + + public Attribute copyWithNewValue(final String newValue) { + final Attribute newAttribute = this.copy(); + newAttribute.value = newValue; + return newAttribute; + } + + public Attribute copyWithNewValueAndType(final String newValue, final ValueType newValueType) { + final Attribute newAttribute = this.copy(); + newAttribute.value = newValue; + newAttribute.valuetype = newValueType; + return newAttribute; + } } diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/CaptureObject.java b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/CaptureObject.java new file mode 100644 index 00000000000..b35723228db --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/CaptureObject.java @@ -0,0 +1,26 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.dlms.objectconfig; + +import lombok.Getter; + +@Getter +public class CaptureObject { + private final CosemObject cosemObject; + private final int attributeId; + + public CaptureObject(final CosemObject cosemObject, final int attributeId) { + this.cosemObject = cosemObject; + this.attributeId = attributeId; + } + + public CaptureObject copy() { + return new CaptureObject(this.cosemObject.copy(), this.attributeId); + } + + public CaptureObject copyWithNewAttribute(final Attribute newAttribute) { + return new CaptureObject(this.cosemObject.copyWithNewAttribute(newAttribute), this.attributeId); + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/CosemObject.java b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/CosemObject.java index 7fbc6911445..32106e6eceb 100644 --- a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/CosemObject.java +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/CosemObject.java @@ -5,25 +5,107 @@ package org.opensmartgridplatform.dlms.objectconfig; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeInfo.Id; +import java.util.ArrayList; import java.util.Collections; +import java.util.EnumMap; import java.util.List; import java.util.Map; -import lombok.Data; +import java.util.stream.Collectors; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.opensmartgridplatform.dlms.exceptions.ObjectConfigException; +import org.opensmartgridplatform.dlms.objectconfig.dlmsclasses.Data; +import org.opensmartgridplatform.dlms.objectconfig.dlmsclasses.ExtendedRegister; +import org.opensmartgridplatform.dlms.objectconfig.dlmsclasses.ProfileGeneric; +import org.opensmartgridplatform.dlms.objectconfig.dlmsclasses.Register; -@Data +@Getter +@NoArgsConstructor +@JsonTypeInfo(use = Id.NAME, property = "class-id", visible = true, defaultImpl = CosemObject.class) +@JsonSubTypes({ + @JsonSubTypes.Type(value = Data.class, name = "1"), + @JsonSubTypes.Type(value = Register.class, name = "3"), + @JsonSubTypes.Type(value = ExtendedRegister.class, name = "4"), + @JsonSubTypes.Type(value = ProfileGeneric.class, name = "7"), +}) public class CosemObject { - private String tag; - private String description; + protected String tag; + protected String description; @JsonProperty("class-id") - private int classId; + protected int classId; - private int version; - private String obis; - private String group; - private List meterTypes; - private Map properties; - private List attributes; + protected int version; + protected String obis; + protected String group; + protected String note; + protected List meterTypes; + protected Map properties; + protected List attributes; + + public CosemObject( + final String tag, + final String description, + final int classId, + final int version, + final String obis, + final String group, + final String note, + final List meterTypes, + final Map properties, + final List attributes) { + this.tag = tag; + this.description = description; + this.classId = classId; + this.version = version; + this.obis = obis; + this.group = group; + this.note = note; + this.meterTypes = meterTypes; + this.properties = properties; + this.attributes = attributes; + } + + public CosemObject copy() { + return new CosemObject( + this.tag, + this.description, + this.classId, + this.version, + this.obis, + this.group, + this.note, + new ArrayList<>(this.meterTypes), + this.properties == null || this.properties.isEmpty() + ? null + : new EnumMap<>(this.properties), + this.attributes.stream().map(Attribute::copy).toList()); + } + + public CosemObject copyWithNewObis(final String newObis) { + final CosemObject newCosemObject = this.copy(); + newCosemObject.obis = newObis; + return newCosemObject; + } + + public CosemObject copyWithNewAttribute(final Attribute newAttribute) { + final CosemObject newCosemObject = this.copy(); + + // Remove attribute with same id as newAttribute + final List copiedAttributes = + newCosemObject.attributes.stream() + .filter(attr -> attr.getId() != newAttribute.getId()) + .collect(Collectors.toList()); + copiedAttributes.add(newAttribute); + + // Add new attribute + newCosemObject.attributes = copiedAttributes; + + return newCosemObject; + } public Attribute getAttribute(final int id) { return this.attributes.stream() @@ -32,6 +114,13 @@ public Attribute getAttribute(final int id) { .orElseThrow(() -> new IllegalArgumentException("Attribute " + id + " not found")); } + public boolean hasAttribute(final int id) { + if (this.attributes == null) { + return false; + } + return this.attributes.stream().anyMatch(attribute -> attribute.getId() == id); + } + public Object getProperty(final ObjectProperty objectProperty) { if (this.properties == null) { return null; @@ -47,4 +136,25 @@ public List getListProperty(final ObjectProperty objectProperty) { return Collections.emptyList(); } + + public int getChannel() throws ObjectConfigException { + final String[] obisParts = this.getObisInParts(); + if (obisParts[1].equals("x")) { + throw new ObjectConfigException("Can't get channel from " + this.obis); + } + return Integer.parseInt(obisParts[1]); + } + + public boolean hasWildcardChannel() throws ObjectConfigException { + final String[] obisParts = this.getObisInParts(); + return obisParts[1].equals("x"); + } + + private String[] getObisInParts() throws ObjectConfigException { + final String[] obisParts = this.obis.split("\\."); + if (obisParts.length != 6) { + throw new ObjectConfigException("Invalid obiscode " + this.obis); + } + return obisParts; + } } diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/DlmsDataType.java b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/DlmsDataType.java index db93cb4092c..7c4b71d172a 100644 --- a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/DlmsDataType.java +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/DlmsDataType.java @@ -58,6 +58,8 @@ public enum DlmsDataType { TIME, @JsonProperty("dont-care") DONT_CARE, + @JsonProperty("script") + SCRIPT, // Data types for specific classes diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/DlmsObjectType.java b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/DlmsObjectType.java index 04cd42ffb07..b46432e07ed 100644 --- a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/DlmsObjectType.java +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/DlmsObjectType.java @@ -55,7 +55,37 @@ public enum DlmsObjectType { LTE_DIAGNOSTIC, MBUS_CLIENT_SETUP, MBUS_DIAGNOSTIC, - PUSH_SETUP_UDP; + PUSH_SETUP_UDP, + ALARM_REGISTER_1, + ALARM_REGISTER_2, + ALARM_REGISTER_3, + INTERVAL_VALUES_E, + INTERVAL_VALUES_G, + DAILY_VALUES_E, + DAILY_VALUES_G, + DAILY_VALUES_COMBINED, + MONTHLY_VALUES_E, + MONTHLY_VALUES_G, + MONTHLY_VALUES_COMBINED, + AMR_PROFILE_STATUS, + AMR_PROFILE_STATUS_HOURLY_G, + AMR_PROFILE_STATUS_DAILY_G, + AMR_PROFILE_STATUS_MONTHLY_G, + MBUS_MASTER_VALUE, + ACTIVE_ENERGY_IMPORT_RATE_1, + ACTIVE_ENERGY_IMPORT_RATE_2, + ACTIVE_ENERGY_EXPORT_RATE_1, + ACTIVE_ENERGY_EXPORT_RATE_2, + ALARM_FILTER_1, + ALARM_FILTER_2, + ALARM_FILTER_3, + READ_MBUS_STATUS, + CLEAR_MBUS_STATUS, + PHASE_OUTAGE_TEST, + LAST_GASP_TEST, + CONFIGURATION_OBJECT, + RANDOMISATION_SETTINGS, + ACTIVITY_CALENDAR; public String value() { return this.name(); diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/DlmsProfile.java b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/DlmsProfile.java index 7c46381241c..e8e0ea0c5a4 100644 --- a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/DlmsProfile.java +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/DlmsProfile.java @@ -8,10 +8,10 @@ import java.util.EnumMap; import java.util.List; import java.util.Map; -import lombok.Data; +import lombok.Getter; import lombok.ToString; -@Data +@Getter @ToString public class DlmsProfile { private String profile; diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/DlmsProfileValidator.java b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/DlmsProfileValidator.java index b052fa41dee..7207b8a3499 100644 --- a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/DlmsProfileValidator.java +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/DlmsProfileValidator.java @@ -20,9 +20,13 @@ import org.opensmartgridplatform.dlms.exceptions.ObjectConfigException; import org.opensmartgridplatform.dlms.interfaceclass.InterfaceClass; import org.opensmartgridplatform.dlms.interfaceclass.attribute.RegisterAttribute; +import org.opensmartgridplatform.dlms.services.ObjectConfigService; @Slf4j public class DlmsProfileValidator { + private static final String PQ_ERROR = " PQ validation error: "; + private static final String CAPTURE_OBJECTS_ERROR = " Capture objects validation error: "; + private DlmsProfileValidator() { // Static class } @@ -32,7 +36,7 @@ public static void validate(final List dlmsProfiles) throws ObjectC dlmsProfiles.stream() .map(DlmsProfileValidator::validateProfile) .flatMap(Collection::stream) - .collect(Collectors.toList()); + .toList(); if (!validationErrors.isEmpty()) { throw new ObjectConfigException(String.join("\n", validationErrors)); @@ -41,10 +45,14 @@ public static void validate(final List dlmsProfiles) throws ObjectC private static List validateProfile(final DlmsProfile dlmsProfile) { final List validationErrors = new ArrayList<>(); + dlmsProfile.createMap(); try { allRegistersShouldHaveAUnit(dlmsProfile, validationErrors); allPQProfilesShouldHaveSelectableObjects(dlmsProfile, validationErrors); + allPqPeriodicShouldBeInAProfileSelectableObjects(dlmsProfile, validationErrors); + allPqRequestsShouldMatchType(dlmsProfile, validationErrors); + allCaptureObjectsShouldExist(dlmsProfile, validationErrors); return validationErrors; } catch (final Exception e) { @@ -56,13 +64,92 @@ private static List validateProfile(final DlmsProfile dlmsProfile) { } } + private static void allPqRequestsShouldMatchType( + final DlmsProfile dlmsProfile, final List validationErrors) { + final String validationError = + dlmsProfile.getObjects().stream() + .filter(DlmsProfileValidator::isPeriodicRequest) + .map(DlmsProfileValidator::pqRequestShouldMatchMeterType) + .filter(error -> !error.isEmpty()) + .collect(Collectors.joining(", ")); + + if (!validationError.isEmpty()) { + validationErrors.add(createErrorMessage(dlmsProfile, PQ_ERROR, validationError)); + } + } + + private static void allPqPeriodicShouldBeInAProfileSelectableObjects( + final DlmsProfile dlmsProfile, final List validationErrors) { + final String validationError = + dlmsProfile.getObjects().stream() + .filter(DlmsProfileValidator::isPeriodicRequest) + .map(object -> pqObjectShouldBeInAProfileSelectableObjects(object, dlmsProfile)) + .filter(error -> !error.isEmpty()) + .collect(Collectors.joining(", ")); + + if (!validationError.isEmpty()) { + validationErrors.add(createErrorMessage(dlmsProfile, PQ_ERROR, validationError)); + } + } + + private static boolean isPeriodicRequest(final CosemObject object) { + return object.getProperty(ObjectProperty.PQ_REQUEST) != null + && (object + .getListProperty(ObjectProperty.PQ_REQUEST) + .contains(PowerQualityRequest.PERIODIC_SP.name()) + || object + .getListProperty(ObjectProperty.PQ_REQUEST) + .contains(PowerQualityRequest.PERIODIC_PP.name())); + } + + private static String pqObjectShouldBeInAProfileSelectableObjects( + final CosemObject pqObject, final DlmsProfile dlmsProfile) { + final List selectableObjects = + dlmsProfile.getObjects().stream() + .filter( + object -> + Arrays.asList( + DEFINABLE_LOAD_PROFILE.name(), + POWER_QUALITY_PROFILE_1.name(), + POWER_QUALITY_PROFILE_2.name()) + .contains(object.getTag())) + .flatMap(object -> object.getListProperty(ObjectProperty.SELECTABLE_OBJECTS).stream()) + .toList(); + + if (!selectableObjects.contains(pqObject.getTag())) { + return pqObject.getTag() + " cannot be found in a selectable object list of a PQ Profile"; + } + return ""; + } + + private static String pqRequestShouldMatchMeterType(final CosemObject pqObject) { + final List pqRequests = pqObject.getListProperty(ObjectProperty.PQ_REQUEST); + if (pqRequests.contains(PowerQualityRequest.ACTUAL_SP.name()) + && !pqObject.getMeterTypes().contains(MeterType.SP)) { + return pqObject.getTag() + " has request ACTUAL_SP, but meter type does not have SP"; + } + if (pqRequests.contains(PowerQualityRequest.PERIODIC_SP.name()) + && !pqObject.getMeterTypes().contains(MeterType.SP)) { + return pqObject.getTag() + " has request PERIODIC_SP, but meter type does not have SP"; + } + if (pqRequests.contains(PowerQualityRequest.ACTUAL_PP.name()) + && !pqObject.getMeterTypes().contains(MeterType.PP)) { + return pqObject.getTag() + " has request ACTUAL_PP, but meter type does not have PP"; + } + if (pqRequests.contains(PowerQualityRequest.PERIODIC_PP.name()) + && !pqObject.getMeterTypes().contains(MeterType.PP)) { + return pqObject.getTag() + " has request PERIODIC_PP, but meter type does not have PP"; + } + return ""; + } + private static void allRegistersShouldHaveAUnit( final DlmsProfile dlmsProfile, final List validationErrors) { final List registersWithoutUnit = dlmsProfile.getObjects().stream() .filter(object -> object.getClassId() == InterfaceClass.REGISTER.id()) .filter(object -> !registerHasScalerUnit(object)) - .collect(Collectors.toList()); + .toList(); if (!registersWithoutUnit.isEmpty()) { final String tags = @@ -95,12 +182,8 @@ private static void allPQProfilesShouldHaveSelectableObjects( .filter(error -> !error.isEmpty()) .collect(Collectors.joining(", ")); - if (!validationError.equals("")) { - validationErrors.add( - "DlmsProfile " - + dlmsProfile.getProfileWithVersion() - + " PQ validation error: " - + validationError); + if (!validationError.isEmpty()) { + validationErrors.add(createErrorMessage(dlmsProfile, PQ_ERROR, validationError)); } } @@ -129,7 +212,7 @@ private static String selectableObjectShouldHavePQProfileDefined( .filter(object -> object.getTag().equals(tagForSelectableObject)) .findFirst(); - if (!optionalCosemObject.isPresent()) { + if (optionalCosemObject.isEmpty()) { return "Profile doesn't contain object for " + tagForSelectableObject; } @@ -139,7 +222,42 @@ private static String selectableObjectShouldHavePQProfileDefined( if (pqProfile == null) { return tagForSelectableObject + " doesn't contain PQ Profile"; } + final List pqRequest = selectableObject.getListProperty(ObjectProperty.PQ_REQUEST); + if (pqRequest == null) { + return tagForSelectableObject + " doesn't contain PQ Request"; + } return ""; } + + private static void allCaptureObjectsShouldExist( + final DlmsProfile dlmsProfile, final List validationErrors) { + final String validationError = + dlmsProfile.getObjects().stream() + .filter(object -> object.getClassId() == InterfaceClass.PROFILE_GENERIC.id()) + .map(ObjectConfigService::getCaptureObjectDefinitions) + .flatMap(Collection::stream) + .map(ObjectConfigService::getCosemObjectTypeFromCaptureObjectDefinition) + .map(tag -> objectShouldExist(dlmsProfile, tag)) + .filter(error -> !error.isEmpty()) + .collect(Collectors.joining(", ")); + + if (!validationError.isEmpty()) { + validationErrors.add(createErrorMessage(dlmsProfile, CAPTURE_OBJECTS_ERROR, validationError)); + } + } + + private static String objectShouldExist( + final DlmsProfile dlmsProfile, final DlmsObjectType type) { + if (!dlmsProfile.getObjectMap().containsKey(type)) { + return "Profile doesn't contain object for " + type.name(); + } + + return ""; + } + + private static String createErrorMessage( + final DlmsProfile dlmsProfile, final String validationType, final String validationError) { + return "DlmsProfile " + dlmsProfile.getProfileWithVersion() + validationType + validationError; + } } diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/ParentProfile.java b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/ParentProfile.java index 9a7e504b1c7..f4cdd737f83 100644 --- a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/ParentProfile.java +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/ParentProfile.java @@ -4,10 +4,10 @@ package org.opensmartgridplatform.dlms.objectconfig; -import lombok.Data; +import lombok.Getter; import lombok.ToString; -@Data +@Getter @ToString public class ParentProfile { private String profile; diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/PowerQualityRequest.java b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/PowerQualityRequest.java index 42df554c9f7..5712157b7c4 100644 --- a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/PowerQualityRequest.java +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/PowerQualityRequest.java @@ -5,7 +5,8 @@ package org.opensmartgridplatform.dlms.objectconfig; public enum PowerQualityRequest { - ONDEMAND, - PERIODIC, - BOTH + ACTUAL_SP, + ACTUAL_PP, + PERIODIC_SP, + PERIODIC_PP } diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/ProfileProperty.java b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/ProfileProperty.java index 5a49cae0af1..693a5ccf0ba 100644 --- a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/ProfileProperty.java +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/ProfileProperty.java @@ -4,7 +4,7 @@ package org.opensmartgridplatform.dlms.objectconfig; -import lombok.Data; +import lombok.Getter; -@Data +@Getter public class ProfileProperty {} diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/TypeBasedValue.java b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/TypeBasedValue.java new file mode 100644 index 00000000000..89bac684812 --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/TypeBasedValue.java @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.dlms.objectconfig; + +import java.util.List; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class TypeBasedValue { + private List types; + private String value; + + public TypeBasedValue(final List types, final String value) { + this.types = types; + this.value = value; + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/ValueBasedOnModel.java b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/ValueBasedOnModel.java new file mode 100644 index 00000000000..b8374384951 --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/ValueBasedOnModel.java @@ -0,0 +1,27 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.dlms.objectconfig; + +import java.util.ArrayList; +import java.util.List; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class ValueBasedOnModel { + protected String type; + protected List values; + + public ValueBasedOnModel(final String type, final List values) { + this.type = type; + this.values = values; + } + + public ValueBasedOnModel copy() { + return new ValueBasedOnModel( + this.type, this.getValues() == null ? null : new ArrayList<>(this.getValues())); + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/ValueType.java b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/ValueType.java index b1204893ef7..5e8fbe40e16 100644 --- a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/ValueType.java +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/ValueType.java @@ -8,5 +8,6 @@ public enum ValueType { FIXED_IN_PROFILE, FIXED_IN_METER, DYNAMIC, - SET_BY_CLIENT + SET_BY_CLIENT, + BASED_ON_MODEL } diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/configlookup/ConfigLookupGroup.java b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/configlookup/ConfigLookupGroup.java new file mode 100644 index 00000000000..d30cfdaa795 --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/configlookup/ConfigLookupGroup.java @@ -0,0 +1,29 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.dlms.objectconfig.configlookup; + +import java.util.List; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class ConfigLookupGroup { + protected String name; + protected String defaulttype; + protected List configlookuptypes; + + public String getMatchingType(final String deviceModel) { + String matchingType = this.defaulttype; + + for (final ConfigLookupType configLookupType : this.configlookuptypes) { + if (configLookupType.matches(deviceModel)) { + matchingType = configLookupType.type; + } + } + + return matchingType; + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/configlookup/ConfigLookupType.java b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/configlookup/ConfigLookupType.java new file mode 100644 index 00000000000..798dec4c0e1 --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/configlookup/ConfigLookupType.java @@ -0,0 +1,20 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.dlms.objectconfig.configlookup; + +import java.util.List; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class ConfigLookupType { + protected String type; + protected List match; + + public boolean matches(final String deviceModel) { + return this.match.stream().anyMatch(deviceModel::contains); + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/dlmsclasses/Data.java b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/dlmsclasses/Data.java new file mode 100644 index 00000000000..65a7b078e0c --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/dlmsclasses/Data.java @@ -0,0 +1,34 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.dlms.objectconfig.dlmsclasses; + +import java.util.List; +import java.util.Map; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.opensmartgridplatform.dlms.objectconfig.Attribute; +import org.opensmartgridplatform.dlms.objectconfig.CosemObject; +import org.opensmartgridplatform.dlms.objectconfig.MeterType; +import org.opensmartgridplatform.dlms.objectconfig.ObjectProperty; + +@Getter +@NoArgsConstructor +public class Data extends CosemObject { + + public Data( + final String tag, + final String description, + final int classId, + final int version, + final String obis, + final String group, + final String note, + final List meterTypes, + final Map properties, + final List attributes) { + super( + tag, description, classId, version, obis, group, note, meterTypes, properties, attributes); + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/dlmsclasses/ExtendedRegister.java b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/dlmsclasses/ExtendedRegister.java new file mode 100644 index 00000000000..b787fe25c3a --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/dlmsclasses/ExtendedRegister.java @@ -0,0 +1,77 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.dlms.objectconfig.dlmsclasses; + +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.opensmartgridplatform.dlms.objectconfig.Attribute; +import org.opensmartgridplatform.dlms.objectconfig.MeterType; +import org.opensmartgridplatform.dlms.objectconfig.ObjectProperty; + +@Getter +@NoArgsConstructor +public class ExtendedRegister extends Register { + + public ExtendedRegister( + final String tag, + final String description, + final int classId, + final int version, + final String obis, + final String group, + final String note, + final List meterTypes, + final Map properties, + final List attributes) { + super( + tag, description, classId, version, obis, group, note, meterTypes, properties, attributes); + } + + @Override + public ExtendedRegister copy() { + return new ExtendedRegister( + this.tag, + this.description, + this.classId, + this.version, + this.obis, + this.group, + this.note, + new ArrayList<>(this.meterTypes), + this.properties == null || this.properties.isEmpty() + ? null + : new EnumMap<>(this.properties), + this.attributes.stream().map(Attribute::copy).toList()); + } + + @Override + public ExtendedRegister copyWithNewObis(final String newObis) { + final ExtendedRegister newExtendedRegister = this.copy(); + newExtendedRegister.obis = newObis; + return newExtendedRegister; + } + + @Override + public ExtendedRegister copyWithNewAttribute(final Attribute newAttribute) { + final ExtendedRegister newExtendedRegister = this.copy(); + + // Remove attribute with same id as newAttribute + final List copiedAttributes = + newExtendedRegister.attributes.stream() + .filter(attr -> attr.getId() != newAttribute.getId()) + .collect(Collectors.toList()); + copiedAttributes.add(newAttribute); + + // Add new attribute + newExtendedRegister.attributes = copiedAttributes; + + return newExtendedRegister; + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/dlmsclasses/ProfileGeneric.java b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/dlmsclasses/ProfileGeneric.java new file mode 100644 index 00000000000..1e64a310810 --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/dlmsclasses/ProfileGeneric.java @@ -0,0 +1,103 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.dlms.objectconfig.dlmsclasses; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.opensmartgridplatform.dlms.exceptions.ObjectConfigException; +import org.opensmartgridplatform.dlms.objectconfig.Attribute; +import org.opensmartgridplatform.dlms.objectconfig.CaptureObject; +import org.opensmartgridplatform.dlms.objectconfig.CosemObject; +import org.opensmartgridplatform.dlms.objectconfig.MeterType; +import org.opensmartgridplatform.dlms.objectconfig.ObjectProperty; +import org.opensmartgridplatform.dlms.services.ObjectConfigService; + +@Getter +@NoArgsConstructor +public class ProfileGeneric extends CosemObject { + + public ProfileGeneric( + final String tag, + final String description, + final int classId, + final int version, + final String obis, + final String group, + final String note, + final List meterTypes, + final Map properties, + final List attributes) { + super( + tag, description, classId, version, obis, group, note, meterTypes, properties, attributes); + } + + public List getCaptureObjects( + final ObjectConfigService service, + final String protocol, + final String version, + final Integer channel, + final String deviceModel) + throws ObjectConfigException { + final List captureObjects = new ArrayList<>(); + + final List channels; + if (this.hasWildcardChannel()) { + // If the profile has an x for the channel in the obis code, then return all capture objects + // with the specified channel. + channels = List.of(channel); + } else { + // If the profile has no x for channel, then each capture objects with an x in the config + // should be handled as 4 different capture objects, one for each channel 1..4. + channels = List.of(1, 2, 3, 4); + } + + final List captureObjectsWithWildcardChannel = new ArrayList<>(); + final List captureObjectsWithoutWildcardChannel = new ArrayList<>(); + + final List captureObjectsFromConfig = + service.getCaptureObjects(this, protocol, version, deviceModel); + + for (final CaptureObject captureObject : captureObjectsFromConfig) { + if (captureObject.getCosemObject().hasWildcardChannel()) { + captureObjectsWithWildcardChannel.add(captureObject); + } else { + captureObjectsWithoutWildcardChannel.add(captureObject); + } + } + + captureObjects.addAll(captureObjectsWithoutWildcardChannel); + + captureObjects.addAll( + channels.stream() + .map(c -> this.addChannel(captureObjectsWithWildcardChannel, c)) + .flatMap(List::stream) + .toList()); + + return captureObjects; + } + + private List addChannel( + final List captureObjects, final int channel) { + final List captureObjectsWithChannel = new ArrayList<>(); + + for (final CaptureObject captureObject : captureObjects) { + final CosemObject cosemObject = captureObject.getCosemObject(); + captureObjectsWithChannel.add( + new CaptureObject( + this.updateCosemObjectWithChannel(cosemObject, channel), + captureObject.getAttributeId())); + } + + return captureObjectsWithChannel; + } + + private CosemObject updateCosemObjectWithChannel( + final CosemObject cosemObject, final int channel) { + return cosemObject.copyWithNewObis(cosemObject.getObis().replace("x", String.valueOf(channel))); + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/dlmsclasses/Register.java b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/dlmsclasses/Register.java new file mode 100644 index 00000000000..e34d93eed3d --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/objectconfig/dlmsclasses/Register.java @@ -0,0 +1,55 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.dlms.objectconfig.dlmsclasses; + +import java.util.List; +import java.util.Map; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.opensmartgridplatform.dlms.interfaceclass.attribute.RegisterAttribute; +import org.opensmartgridplatform.dlms.objectconfig.Attribute; +import org.opensmartgridplatform.dlms.objectconfig.MeterType; +import org.opensmartgridplatform.dlms.objectconfig.ObjectProperty; +import org.opensmartgridplatform.dlms.objectconfig.ValueType; + +@Getter +@NoArgsConstructor +public class Register extends Data { + + public Register( + final String tag, + final String description, + final int classId, + final int version, + final String obis, + final String group, + final String note, + final List meterTypes, + final Map properties, + final List attributes) { + super( + tag, description, classId, version, obis, group, note, meterTypes, properties, attributes); + } + + public boolean needsScalerUnitFromMeter() { + final Attribute scalerUnitAttribute = + this.getAttribute(RegisterAttribute.SCALER_UNIT.attributeId()); + + if (scalerUnitAttribute == null + || scalerUnitAttribute.getValue() == null + || scalerUnitAttribute.getValue().isEmpty()) { + return true; + } + + return scalerUnitAttribute.getValuetype() == ValueType.DYNAMIC; + } + + public String getScalerUnit() { + final Attribute scalerUnitAttribute = + this.getAttribute(RegisterAttribute.SCALER_UNIT.attributeId()); + + return scalerUnitAttribute.getValue(); + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/services/ObjectConfigService.java b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/services/ObjectConfigService.java index 82c133760d8..3202d91c7df 100644 --- a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/services/ObjectConfigService.java +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/java/org/opensmartgridplatform/dlms/services/ObjectConfigService.java @@ -4,21 +4,30 @@ package org.opensmartgridplatform.dlms.services; +import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.stream.Stream; import lombok.extern.slf4j.Slf4j; import org.opensmartgridplatform.dlms.exceptions.ObjectConfigException; +import org.opensmartgridplatform.dlms.interfaceclass.InterfaceClass; +import org.opensmartgridplatform.dlms.interfaceclass.attribute.ProfileGenericAttribute; +import org.opensmartgridplatform.dlms.objectconfig.Attribute; +import org.opensmartgridplatform.dlms.objectconfig.CaptureObject; import org.opensmartgridplatform.dlms.objectconfig.CosemObject; import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; import org.opensmartgridplatform.dlms.objectconfig.DlmsProfile; import org.opensmartgridplatform.dlms.objectconfig.DlmsProfileValidator; import org.opensmartgridplatform.dlms.objectconfig.ObjectProperty; import org.opensmartgridplatform.dlms.objectconfig.ParentProfile; +import org.opensmartgridplatform.dlms.objectconfig.TypeBasedValue; +import org.opensmartgridplatform.dlms.objectconfig.ValueType; +import org.opensmartgridplatform.dlms.objectconfig.configlookup.ConfigLookupGroup; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.stereotype.Service; @@ -27,40 +36,61 @@ @Slf4j public class ObjectConfigService { - private final List dlmsProfiles; - - ObjectConfigService() throws IOException { - this.dlmsProfiles = this.getDlmsProfileListFromResources(); - } + public final List dlmsProfiles; + public final List configLookupGroups; /* - * Provide a list of DlmsProfile to the constructor or add a null value and profiles are loaded from the classpath resource '/dlmsprofiles'. + * Profiles are loaded from the classpath resource '/dlmsprofiles'. */ - public ObjectConfigService(final List dlmsProfiles) - throws ObjectConfigException, IOException { - if (dlmsProfiles == null) { - this.dlmsProfiles = this.getDlmsProfileListFromResources(); - } else { - this.dlmsProfiles = dlmsProfiles; - } - - this.handleInheritance(); + public ObjectConfigService() throws ObjectConfigException, IOException { + this.dlmsProfiles = this.getDlmsProfileListFromResources(); DlmsProfileValidator.validate(this.dlmsProfiles); this.dlmsProfiles.forEach(DlmsProfile::createMap); + + this.configLookupGroups = this.getConfigLookupGroupsFromResources(); } public CosemObject getCosemObject( final String protocolName, final String protocolVersion, final DlmsObjectType dlmsObjectType) throws IllegalArgumentException, ObjectConfigException { + return this.getCosemObject(protocolName, protocolVersion, dlmsObjectType, null); + } + + public CosemObject getCosemObject( + final String protocolName, + final String protocolVersion, + final DlmsObjectType dlmsObjectType, + final String deviceModel) + throws IllegalArgumentException, ObjectConfigException { + final Optional optionalCosemObject = + this.getOptionalCosemObject(protocolName, protocolVersion, dlmsObjectType, deviceModel); + return optionalCosemObject.orElseThrow( + () -> + new IllegalArgumentException( + String.format( + "No object found of type %s in profile %s version %s", + dlmsObjectType.value(), protocolName, protocolVersion))); + } + + public Optional getOptionalCosemObject( + final String protocolName, final String protocolVersion, final DlmsObjectType dlmsObjectType) + throws ObjectConfigException { + return this.getOptionalCosemObject(protocolName, protocolVersion, dlmsObjectType, null); + } + + public Optional getOptionalCosemObject( + final String protocolName, + final String protocolVersion, + final DlmsObjectType dlmsObjectType, + final String deviceModel) + throws ObjectConfigException { final Map cosemObjects = this.getCosemObjects(protocolName, protocolVersion); if (cosemObjects.containsKey(dlmsObjectType)) { - return cosemObjects.get(dlmsObjectType); + final CosemObject cosemObject = cosemObjects.get(dlmsObjectType); + return Optional.of(this.handleValueBasedOnModel(cosemObject, deviceModel)); } else { - throw new IllegalArgumentException( - String.format( - "No object found of type %s in profile %s version %s", - dlmsObjectType.value(), protocolName, protocolVersion)); + return Optional.empty(); } } @@ -92,7 +122,7 @@ public List getCosemObjects( public List getCosemObjectsWithProperties( final String protocolName, final String protocolVersion, - final Map> properties) + final Map> properties) throws ObjectConfigException { final Map cosemObjects = this.getCosemObjects(protocolName, protocolVersion); @@ -102,20 +132,6 @@ public List getCosemObjectsWithProperties( .toList(); } - public List getCosemObjectsWithProperty( - final String protocolName, - final String protocolVersion, - final ObjectProperty wantedProperty, - final List wantedPropertyValues) - throws ObjectConfigException { - final Map cosemObjects = - this.getCosemObjects(protocolName, protocolVersion); - - return cosemObjects.values().stream() - .filter(object -> this.hasProperty(object, wantedProperty, wantedPropertyValues)) - .toList(); - } - public Map getCosemObjects( final String protocolName, final String protocolVersion) throws ObjectConfigException { @@ -135,29 +151,51 @@ public Map getCosemObjects( return dlmsProfile.get().getObjectMap(); } + private String getConfigLookupType(final String matchGroup, final String deviceModel) + throws ObjectConfigException { + + final Optional configLookupGroupOptional = + this.configLookupGroups.stream() + .filter(group -> group.getName().equals(matchGroup)) + .findFirst(); + + if (configLookupGroupOptional.isEmpty()) { + throw new ObjectConfigException("Matchgroup " + matchGroup + " not found"); + } else { + return configLookupGroupOptional.get().getMatchingType(deviceModel); + } + } + private boolean hasProperty( final CosemObject object, final ObjectProperty wantedProperty, - final List wantedPropertyValues) { - final Object property = object.getProperty(wantedProperty); + final List wantedPropertyValues) { + final Object objectPropertyValue = object.getProperty(wantedProperty); - if (property == null) { + if (objectPropertyValue == null) { return false; } else if (wantedPropertyValues != null && !wantedPropertyValues.isEmpty()) { - return wantedPropertyValues.contains(property); + if (objectPropertyValue instanceof String) { + return wantedPropertyValues.contains(objectPropertyValue); + } else if (objectPropertyValue instanceof List) { + final List objectProperyValues = object.getListProperty(wantedProperty); + return new HashSet<>(objectProperyValues).containsAll(wantedPropertyValues); + } + throw new IllegalArgumentException("Unexpected type"); } return true; } private boolean hasProperties( - final CosemObject object, final Map> properties) { + final CosemObject object, final Map> properties) { return properties.entrySet().stream() .allMatch(entry -> this.hasProperty(object, entry.getKey(), entry.getValue())); } - private List getDlmsProfileListFromResources() throws IOException { + private List getDlmsProfileListFromResources() + throws IOException, ObjectConfigException { final String scannedPackage = "dlmsprofiles/*"; final PathMatchingResourcePatternResolver scanner = new PathMatchingResourcePatternResolver(); final Resource[] resources = scanner.getResources(scannedPackage); @@ -168,7 +206,10 @@ private List getDlmsProfileListFromResources() throws IOException { Stream.of(resources) .filter( - resource -> resource.getFilename() != null && resource.getFilename().endsWith(".json")) + resource -> + resource.getFilename() != null + && resource.getFilename().endsWith(".json") + && !resource.getFilename().equals("configlookup.json")) .forEach( resource -> { try { @@ -180,42 +221,175 @@ private List getDlmsProfileListFromResources() throws IOException { } }); + this.handleInheritance(dlmsProfilesFromResources); + return dlmsProfilesFromResources; } - private void handleInheritance() throws ObjectConfigException { - for (final DlmsProfile dlmsProfile : this.dlmsProfiles) { - this.getInheritedObjects(dlmsProfile); + private void handleInheritance(final List dlmsProfilesFromResources) + throws ObjectConfigException { + for (final DlmsProfile dlmsProfile : dlmsProfilesFromResources) { + final ParentProfile parentProfile = dlmsProfile.getInherit(); + if (parentProfile != null) { + log.info( + "Handle inheritance of " + + parentProfile.getVersion() + + " for profile: " + + dlmsProfile.getProfileWithVersion()); + + this.addInheritedObjects(parentProfile, dlmsProfilesFromResources, dlmsProfile); + } } } - private void getInheritedObjects(final DlmsProfile dlmsProfile) throws ObjectConfigException { - final ParentProfile parentProfile = dlmsProfile.getInherit(); + private void addInheritedObjects( + final ParentProfile parentProfile, + final List dlmsProfilesFromResources, + final DlmsProfile dlmsProfile) + throws ObjectConfigException { - if (parentProfile != null) { - final Optional parentDlmsProfile = - this.dlmsProfiles.stream() - .filter(profile -> parentProfile.getVersion().equalsIgnoreCase(profile.getVersion())) - .filter(profile -> parentProfile.getProfile().equalsIgnoreCase(profile.getProfile())) - .findAny(); + final DlmsProfile parentDlmsProfile = + this.getDlmsProfile(parentProfile, dlmsProfilesFromResources); - if (parentDlmsProfile.isPresent()) { - dlmsProfile.getObjects().addAll(parentDlmsProfile.get().getObjects()); - } else { - throw new ObjectConfigException( - "Parent profile " - + parentProfile - + " for profile " - + dlmsProfile.getProfileWithVersion() - + " not found."); - } + parentDlmsProfile + .getObjects() + .forEach( + parentCosemObject -> { + final boolean objectAlreadyDefined = + dlmsProfile.getObjects().stream() + .anyMatch( + cosemObject -> cosemObject.getTag().equals(parentCosemObject.getTag())); + if (!objectAlreadyDefined) { + dlmsProfile.getObjects().add(parentCosemObject); + } + }); + if (parentDlmsProfile.getInherit() != null) { + this.addInheritedObjects( + parentDlmsProfile.getInherit(), dlmsProfilesFromResources, dlmsProfile); } } + private DlmsProfile getDlmsProfile( + final ParentProfile parentProfile, final List dlmsProfilesFromResources) + throws ObjectConfigException { + return dlmsProfilesFromResources.stream() + .filter(profile -> parentProfile.getVersion().equalsIgnoreCase(profile.getVersion())) + .filter(profile -> parentProfile.getProfile().equalsIgnoreCase(profile.getProfile())) + .findFirst() + .orElseThrow( + () -> new ObjectConfigException("Parent profile " + parentProfile + " not found.")); + } + /* * Get a list of configured DlmsProfile. */ public List getConfiguredDlmsProfiles() { return this.dlmsProfiles; } + + public static List getCaptureObjectDefinitions(final CosemObject profile) { + if (profile.getClassId() != InterfaceClass.PROFILE_GENERIC.id()) { + throw new IllegalArgumentException( + "Can't get capture objects, object " + profile.getTag() + " is not a Profile Generic"); + } + + final Attribute captureObjectsAttribute = + profile.getAttribute(ProfileGenericAttribute.CAPTURE_OBJECTS.attributeId()); + + final String captureObjectsAttributeValue = captureObjectsAttribute.getValue(); + + if (captureObjectsAttributeValue == null || captureObjectsAttributeValue.isEmpty()) { + return List.of(); + } + + final String[] captureObjectDefinitions = captureObjectsAttribute.getValue().split("\\|"); + + return List.of(captureObjectDefinitions); + } + + public static DlmsObjectType getCosemObjectTypeFromCaptureObjectDefinition( + final String captureObjectDefinition) { + return DlmsObjectType.fromValue(captureObjectDefinition.split(",")[0]); + } + + public static int getAttributeIdFromCaptureObjectDefinition( + final String captureObjectDefinition) { + return Integer.parseInt(captureObjectDefinition.split(",")[1]); + } + + public List getCaptureObjects( + final CosemObject profile, + final String protocol, + final String version, + final String deviceModel) + throws ObjectConfigException { + final List captureObjectDefinitions = getCaptureObjectDefinitions(profile); + + final List captureObjects = new ArrayList<>(); + + for (final String def : captureObjectDefinitions) { + try { + final DlmsObjectType objectType = getCosemObjectTypeFromCaptureObjectDefinition(def); + final int attributeId = getAttributeIdFromCaptureObjectDefinition(def); + final CosemObject cosemObject = + this.getCosemObject(protocol, version, objectType, deviceModel); + captureObjects.add(new CaptureObject(cosemObject, attributeId)); + } catch (final ObjectConfigException e) { + throw new ObjectConfigException("Capture object " + def + " not found in object config", e); + } + } + return captureObjects; + } + + protected CosemObject handleValueBasedOnModel( + final CosemObject cosemObject, final String deviceModel) throws ObjectConfigException { + if (deviceModel == null) { + return cosemObject; + } + + final Optional attributeOptional = + cosemObject.getAttributes().stream() + .filter(attr -> attr.getValuetype() == ValueType.BASED_ON_MODEL) + .findFirst(); + + if (attributeOptional.isEmpty()) { + return cosemObject; + } else { + final Attribute originalAttribute = attributeOptional.get(); + + final String configLookupType = + this.getConfigLookupType(originalAttribute.getValuebasedonmodel().getType(), deviceModel); + + final Optional typeBasedValueOptional = + originalAttribute.getValuebasedonmodel().getValues().stream() + .filter(tbv -> tbv.getTypes().contains(configLookupType)) + .findFirst(); + + if (typeBasedValueOptional.isPresent()) { + final String value = typeBasedValueOptional.get().getValue(); + final Attribute newAttribute = + originalAttribute.copyWithNewValueAndType(value, ValueType.FIXED_IN_METER); + return cosemObject.copyWithNewAttribute(newAttribute); + } else { + // If no value was found for this device model, then set the value to Dynamic and log a + // warning. The command executor should get the value from the meter. + log.warn( + "Could not find value for devicemodel {} for {}", + deviceModel, + originalAttribute.getValuebasedonmodel().getType()); + final Attribute newAttribute = + originalAttribute.copyWithNewValueAndType(null, ValueType.DYNAMIC); + return cosemObject.copyWithNewAttribute(newAttribute); + } + } + } + + private List getConfigLookupGroupsFromResources() throws IOException { + final PathMatchingResourcePatternResolver scanner = new PathMatchingResourcePatternResolver(); + final Resource resource = scanner.getResource("dlmsprofiles/configlookup.json"); + + final ObjectMapper objectMapper = new ObjectMapper(); + + return objectMapper.readValue(resource.getInputStream(), new TypeReference<>() {}); + } } diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/configlookup.json b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/configlookup.json new file mode 100644 index 00000000000..0f68ccd2505 --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/configlookup.json @@ -0,0 +1,43 @@ +[ + { + "name": "GAS_METER_TYPE", + "configlookuptypes": [ + { + "type": "G4-G6", + "match": [ + "G4", + "G6" + ] + }, + { + "type": "G10-G25", + "match": [ + "G10", + "G16", + "G25" + ] + }, + { + "type": "unknown gas meter type", + "match": [ + "elster-instromet", + "flonidan-gasmeter", + "G4SRT 1.2L" + ] + } + ], + "defaulttype": "unknown gas meter type" + }, + { + "name": "INSTANTANEOUS_VOLTAGE_DSMR4", + "configlookuptypes": [ + { + "type": "Scaler -1", + "match": [ + "Kaifa" + ] + } + ], + "defaulttype": "Scaler 0" + } +] diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-dsmr422.json b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-dsmr22.json similarity index 53% rename from osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-dsmr422.json rename to osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-dsmr22.json index 8d32f62b241..4a432fe1502 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-dsmr422.json +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-dsmr22.json @@ -1,12 +1,13 @@ { "profile": "DSMR", - "version": "4.2.2", - "description": "Profile for Smart Meter Requirements 4.2.2", + "version": "2.2", + "description": "Profile for Smart Meter Requirements 2.2", "properties": [], "objects": [ { "tag": "CLOCK", "description": "Clock", + "note": null, "class-id": 8, "version": 0, "obis": "0.0.1.0.0.255", @@ -40,169 +41,121 @@ ] }, { - "tag": "DEFINABLE_LOAD_PROFILE", - "description": "Definable load profile", - "class-id": 7, - "version": 1, - "obis": "0.1.94.31.6.255", + "tag": "ACTIVE_ENERGY_IMPORT_RATE_1", + "description": "Active energy import (+A) rate 1", + "note": null, + "class-id": 3, + "version": 0, + "obis": "1.0.1.8.1.255", "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "SELECTABLE_OBJECTS": [ - "CLOCK", - "GPRS_DIAGNOSTIC", - "NUMBER_OF_VOLTAGE_SWELLS_FOR_L1", - "NUMBER_OF_VOLTAGE_SAGS_FOR_L1", - "NUMBER_OF_POWER_FAILURES", - "INSTANTANEOUS_VOLTAGE_L1", - "INSTANTANEOUS_VOLTAGE_L2", - "INSTANTANEOUS_VOLTAGE_L3", - "AVERAGE_VOLTAGE_L1", - "AVERAGE_VOLTAGE_L2", - "AVERAGE_VOLTAGE_L3", - "INSTANTANEOUS_CURRENT_L1", - "AVERAGE_CURRENT_L1", - "INSTANTANEOUS_ACTIVE_CURRENT_TOTAL_OVER_ALL_PHASES", - "AVERAGE_ACTIVE_POWER_IMPORT_L1", - "AVERAGE_ACTIVE_POWER_IMPORT_L2", - "AVERAGE_ACTIVE_POWER_IMPORT_L3", - "AVERAGE_ACTIVE_POWER_EXPORT_L1", - "AVERAGE_ACTIVE_POWER_EXPORT_L2", - "AVERAGE_ACTIVE_POWER_EXPORT_L3", - "AVERAGE_REACTIVE_POWER_IMPORT_L1", - "AVERAGE_REACTIVE_POWER_IMPORT_L2", - "AVERAGE_REACTIVE_POWER_IMPORT_L3", - "AVERAGE_REACTIVE_POWER_EXPORT_L1", - "AVERAGE_REACTIVE_POWER_EXPORT_L2", - "AVERAGE_REACTIVE_POWER_EXPORT_L3" - ] - }, + "meterTypes": [ + "SP", + "PP" + ], "attributes": [ { "id": 2, - "description": "buffer", - "datatype": "array", + "description": "value", + "datatype": "double-long-unsigned", "valuetype": "DYNAMIC", - "value": "EMPTY", "access": "R" }, { "id": 3, - "description": "capture objects", - "datatype": "array", - "valuetype": "SET_BY_CLIENT", - "value": "EMPTY", - "access": "RW" - }, - { - "id": 4, - "description": "capture period in sec", - "datatype": "double-long-unsigned", - "valuetype": "SET_BY_CLIENT", - "value": "900", - "access": "RW" - }, - { - "id": 5, - "description": "sort method", - "datatype": "enum", - "valuetype": "FIXED_IN_METER", - "value": "1", - "access": "R" - }, - { - "id": 6, - "description": "sort object", - "datatype": "object_definition", - "valuetype": "FIXED_IN_METER", - "value": "NONE", - "access": "R" - }, - { - "id": 7, - "description": "entries in use", - "datatype": "double-long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", + "description": "scaler_unit", + "datatype": "scal_unit_type", + "valuetype": "FIXED_IN_PROFILE", + "value": "0, WH", "access": "R" - }, - { - "id": 8, - "description": "profile entries", - "datatype": "double-long-unsigned", - "valuetype": "SET_BY_CLIENT", - "value": "960", - "access": "RW" } ] }, { - "tag": "GPRS_DIAGNOSTIC", - "description": "GPRS Diagnostic", - "class-id": 47, + "tag": "ACTIVE_ENERGY_IMPORT_RATE_2", + "description": "Active energy import (+A) rate 2", + "note": null, + "class-id": 3, "version": 0, - "obis": "0.0.25.6.0.255", + "obis": "1.0.1.8.2.255", "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "PERIODIC" - }, + "meterTypes": [ + "SP", + "PP" + ], "attributes": [ { "id": 2, - "description": "operator", - "datatype": "visible-string", + "description": "value", + "datatype": "double-long-unsigned", "valuetype": "DYNAMIC", - "value": "EMPTY", "access": "R" }, { "id": 3, - "description": "status", - "datatype": "enum", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 4, - "description": "cs attachment", - "datatype": "enum", - "valuetype": "DYNAMIC", - "value": "0", + "description": "scaler_unit", + "datatype": "scal_unit_type", + "valuetype": "FIXED_IN_PROFILE", + "value": "0, WH", "access": "R" - }, + } + ] + }, + { + "tag": "ACTIVE_ENERGY_EXPORT_RATE_1", + "description": "Active energy export (-A) rate 1", + "note": null, + "class-id": 3, + "version": 0, + "obis": "1.0.2.8.1.255", + "group": "ELECTRICITY", + "meterTypes": [ + "SP", + "PP" + ], + "attributes": [ { - "id": 5, - "description": "ps status", - "datatype": "enum", + "id": 2, + "description": "value", + "datatype": "double-long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { - "id": 6, - "description": "cell info", - "datatype": "cell_info_type", - "valuetype": "DYNAMIC", - "value": "EMPTY", + "id": 3, + "description": "scaler_unit", + "datatype": "scal_unit_type", + "valuetype": "FIXED_IN_PROFILE", + "value": "0, WH", "access": "R" - }, + } + ] + }, + { + "tag": "ACTIVE_ENERGY_EXPORT_RATE_2", + "description": "Active energy export (-A) rate 2", + "note": null, + "class-id": 3, + "version": 0, + "obis": "1.0.2.8.2.255", + "group": "ELECTRICITY", + "meterTypes": [ + "SP", + "PP" + ], + "attributes": [ { - "id": 7, - "description": "adjacent cells", - "datatype": "array", + "id": 2, + "description": "value", + "datatype": "double-long-unsigned", "valuetype": "DYNAMIC", - "value": "EMPTY", "access": "R" }, { - "id": 8, - "description": "capture time", - "datatype": "date-time", - "valuetype": "DYNAMIC", - "value": "EMPTY", + "id": 3, + "description": "scaler_unit", + "datatype": "scal_unit_type", + "valuetype": "FIXED_IN_PROFILE", + "value": "0, WH", "access": "R" } ] @@ -210,6 +163,7 @@ { "tag": "NUMBER_OF_VOLTAGE_SWELLS_FOR_L1", "description": "Number of voltage swells in phase L1", + "note": null, "class-id": 1, "version": 0, "obis": "1.0.32.36.0.255", @@ -217,7 +171,7 @@ "meterTypes": ["SP","PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_SP","ACTUAL_PP"] }, "attributes": [ { @@ -225,7 +179,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" } ] @@ -233,6 +186,7 @@ { "tag": "NUMBER_OF_VOLTAGE_SWELLS_FOR_L2", "description": "Number of voltage swells in phase L2", + "note": null, "class-id": 1, "version": 0, "obis": "1.0.52.36.0.255", @@ -240,7 +194,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "ONDEMAND" + "PQ_REQUEST": ["ACTUAL_PP"] }, "attributes": [ { @@ -248,7 +202,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" } ] @@ -256,6 +209,7 @@ { "tag": "NUMBER_OF_VOLTAGE_SWELLS_FOR_L3", "description": "Number of voltage swells in phase L3", + "note": null, "class-id": 1, "version": 0, "obis": "1.0.72.36.0.255", @@ -263,7 +217,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "ONDEMAND" + "PQ_REQUEST": ["ACTUAL_PP"] }, "attributes": [ { @@ -271,7 +225,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" } ] @@ -279,6 +232,7 @@ { "tag": "NUMBER_OF_VOLTAGE_SAGS_FOR_L1", "description": "Number of voltage sags in phase L1", + "note": null, "class-id": 1, "version": 0, "obis": "1.0.32.32.0.255", @@ -286,7 +240,7 @@ "meterTypes": ["SP","PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_SP","ACTUAL_PP"] }, "attributes": [ { @@ -294,7 +248,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" } ] @@ -302,6 +255,7 @@ { "tag": "NUMBER_OF_VOLTAGE_SAGS_FOR_L2", "description": "Number of voltage sags in phase L2", + "note": null, "class-id": 1, "version": 0, "obis": "1.0.52.32.0.255", @@ -309,7 +263,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "ONDEMAND" + "PQ_REQUEST": ["ACTUAL_PP"] }, "attributes": [ { @@ -317,7 +271,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" } ] @@ -325,6 +278,7 @@ { "tag": "NUMBER_OF_VOLTAGE_SAGS_FOR_L3", "description": "Number of voltage sags in phase L3", + "note": null, "class-id": 1, "version": 0, "obis": "1.0.72.32.0.255", @@ -332,7 +286,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "ONDEMAND" + "PQ_REQUEST": ["ACTUAL_PP"] }, "attributes": [ { @@ -340,7 +294,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" } ] @@ -348,6 +301,7 @@ { "tag": "NUMBER_OF_LONG_POWER_FAILURES", "description": "Number of long power failures in any phases", + "note": null, "class-id": 1, "version": 0, "obis": "0.0.96.7.9.255", @@ -355,7 +309,7 @@ "meterTypes": ["SP","PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_SP","ACTUAL_PP"] }, "attributes": [ { @@ -363,7 +317,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" } ] @@ -371,6 +324,7 @@ { "tag": "NUMBER_OF_POWER_FAILURES", "description": "Number of power failures in any phases", + "note": null, "class-id": 1, "version": 0, "obis": "0.0.96.7.21.255", @@ -378,7 +332,7 @@ "meterTypes": ["SP","PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_SP","ACTUAL_PP"] }, "attributes": [ { @@ -386,7 +340,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" } ] @@ -394,6 +347,7 @@ { "tag": "INSTANTANEOUS_VOLTAGE_L1", "description": "Instantaneous voltage L1", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.32.7.0.255", @@ -401,7 +355,7 @@ "meterTypes": ["SP","PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_SP","ACTUAL_PP"] }, "attributes": [ { @@ -409,7 +363,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -425,6 +378,7 @@ { "tag": "INSTANTANEOUS_VOLTAGE_L2", "description": "Instantaneous voltage L2", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.52.7.0.255", @@ -432,7 +386,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_PP"] }, "attributes": [ { @@ -440,7 +394,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -456,6 +409,7 @@ { "tag": "INSTANTANEOUS_VOLTAGE_L3", "description": "Instantaneous voltage L3", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.72.7.0.255", @@ -463,7 +417,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_PP"] }, "attributes": [ { @@ -471,7 +425,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -487,6 +440,7 @@ { "tag": "AVERAGE_VOLTAGE_L1", "description": "Average voltage L1", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.32.24.0.255", @@ -494,7 +448,7 @@ "meterTypes": ["SP","PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_SP","ACTUAL_PP"] }, "attributes": [ { @@ -502,7 +456,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -518,6 +471,7 @@ { "tag": "AVERAGE_VOLTAGE_L2", "description": "Average voltage L2", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.52.24.0.255", @@ -525,7 +479,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_PP"] }, "attributes": [ { @@ -533,7 +487,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -549,6 +502,7 @@ { "tag": "AVERAGE_VOLTAGE_L3", "description": "Average voltage L3", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.72.24.0.255", @@ -556,7 +510,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_PP"] }, "attributes": [ { @@ -564,7 +518,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -580,6 +533,7 @@ { "tag": "INSTANTANEOUS_CURRENT_L1", "description": "Instantaneous current L1", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.31.7.0.255", @@ -587,7 +541,7 @@ "meterTypes": ["SP","PP"], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_SP","ACTUAL_PP"] }, "attributes": [ { @@ -595,7 +549,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -611,6 +564,7 @@ { "tag": "INSTANTANEOUS_CURRENT_L2", "description": "Instantaneous current L2", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.51.7.0.255", @@ -618,7 +572,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "ONDEMAND" + "PQ_REQUEST": ["ACTUAL_PP"] }, "attributes": [ { @@ -626,7 +580,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -642,6 +595,7 @@ { "tag": "INSTANTANEOUS_CURRENT_L3", "description": "Instantaneous current L3", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.71.7.0.255", @@ -649,7 +603,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "ONDEMAND" + "PQ_REQUEST": ["ACTUAL_PP"] }, "attributes": [ { @@ -657,7 +611,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -671,16 +624,17 @@ ] }, { - "tag": "AVERAGE_CURRENT_L1", - "description": "Average current L1", + "tag": "INSTANTANEOUS_ACTIVE_CURRENT_TOTAL_OVER_ALL_PHASES", + "description": "Instantaneous current total", + "note": null, "class-id": 3, "version": 0, - "obis": "1.0.31.24.0.255", + "obis": "1.0.90.7.0.255", "group": "ELECTRICITY", "meterTypes": ["SP","PP"], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_SP","ACTUAL_PP"] }, "attributes": [ { @@ -688,7 +642,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -702,715 +655,413 @@ ] }, { - "tag": "AVERAGE_CURRENT_L2", - "description": "Average current L2", - "class-id": 3, + "tag": "ALARM_REGISTER_1", + "description": "Alarm register 1", + "note": null, + "class-id": 1, "version": 0, - "obis": "1.0.51.24.0.255", + "obis": "0.0.97.98.0.255", "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "ONDEMAND" - }, + "meterTypes": ["SP","PP"], + "properties": {}, "attributes": [ { "id": 2, "description": "value", - "datatype": "long-unsigned", + "datatype": "double-long-unsigned", "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, A", - "access": "R" + "access": "RW" } ] }, { - "tag": "AVERAGE_CURRENT_L3", - "description": "Average current L3", - "class-id": 3, + "tag": "ALARM_FILTER_1", + "description": "Alarm filter 1", + "note": null, + "class-id": 1, "version": 0, - "obis": "1.0.71.24.0.255", + "obis": "0.0.97.98.10.255", "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, + "meterTypes": [ + "SP", + "PP" + ], + "properties": {}, "attributes": [ { "id": 2, "description": "value", - "datatype": "long-unsigned", + "datatype": "double-long-unsigned", "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, A", - "access": "R" + "access": "RW" } ] }, { - "tag": "INSTANTANEOUS_ACTIVE_CURRENT_TOTAL_OVER_ALL_PHASES", - "description": "Instantaneous current total", - "class-id": 3, - "version": 0, - "obis": "1.0.90.7.0.255", - "group": "ELECTRICITY", + "tag": "INTERVAL_VALUES_G", + "description": "Hourly interval readings of M-Bus device", + "class-id": 7, + "version": 1, + "obis": "0.x.24.3.0.255", + "group": "GAS", "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, + "properties": {}, "attributes": [ { "id": 2, - "description": "value", - "datatype": "long-unsigned", + "description": "buffer", + "datatype": "array", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", + "description": "capture objects", + "datatype": "array", "valuetype": "FIXED_IN_PROFILE", - "value": "0, A", + "value": "CLOCK,2|AMR_PROFILE_STATUS_HOURLY_G,2|MBUS_MASTER_VALUE,2", "access": "R" - } - ] - }, - { - "tag": "INSTANTANEOUS_ACTIVE_POWER_IMPORT", - "description": "Instantaneous active power (+P)", - "class-id": 3, - "version": 0, - "obis": "1.0.1.7.0.255", - "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "ONDEMAND" - }, - "attributes": [ + }, { - "id": 2, - "description": "value", - "datatype": "long-unsigned", + "id": 4, + "description": "capture period in sec", + "datatype": "double-long-unsigned", + "valuetype": "FIXED_IN_PROFILE", + "value": "3600", + "access": "R" + }, + { + "id": 5, + "description": "sort method", + "datatype": "enum", + "valuetype": "FIXED_IN_METER", + "value": "1", + "access": "R" + }, + { + "id": 6, + "description": "sort object", + "datatype": "object_definition", + "valuetype": "FIXED_IN_METER", + "value": "NONE", + "access": "R" + }, + { + "id": 7, + "description": "entries in use", + "datatype": "double-long-unsigned", "valuetype": "DYNAMIC", "value": "0", "access": "R" }, { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", + "id": 8, + "description": "profile entries", + "datatype": "double-long-unsigned", "valuetype": "FIXED_IN_PROFILE", - "value": "0, W", + "value": "240", "access": "R" } ] }, { - "tag": "INSTANTANEOUS_ACTIVE_POWER_EXPORT", - "description": "Instantaneous active power (-P)", - "class-id": 3, - "version": 0, - "obis": "1.0.2.7.0.255", + "tag": "DAILY_VALUES_COMBINED", + "description": "Daily combined billing", + "note": "To support MT382 meter, G values are added to this profile. DSMR2.2 spec for this profile is E values only.", + "class-id": 7, + "version": 1, + "obis": "1.0.99.2.0.255", "group": "ELECTRICITY", "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "ONDEMAND" - }, + "properties": {}, "attributes": [ { "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", + "description": "buffer", + "datatype": "array", + "valuetype": "DYNAMIC", "access": "R" }, { "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", + "description": "capture objects", + "datatype": "array", "valuetype": "FIXED_IN_PROFILE", - "value": "0, W", - "access": "R" - } - ] - }, - { - "tag": "INSTANTANEOUS_ACTIVE_POWER_IMPORT_L1", - "description": "Instantaneous active power L1 (+P)", - "class-id": 3, - "version": 0, - "obis": "1.0.21.7.0.255", - "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "ONDEMAND" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", + "value": "CLOCK,2|AMR_PROFILE_STATUS,2|ACTIVE_ENERGY_IMPORT_RATE_1,2|ACTIVE_ENERGY_IMPORT_RATE_2,2|ACTIVE_ENERGY_EXPORT_RATE_1,2|ACTIVE_ENERGY_EXPORT_RATE_1,2|MBUS_MASTER_VALUE,2", "access": "R" }, { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", + "id": 4, + "description": "capture period in sec", + "datatype": "double-long-unsigned", "valuetype": "FIXED_IN_PROFILE", - "value": "0, W", + "value": "86400", "access": "R" - } - ] - }, - { - "tag": "INSTANTANEOUS_ACTIVE_POWER_IMPORT_L2", - "description": "Instantaneous active power L2 (+P)", - "class-id": 3, - "version": 0, - "obis": "1.0.41.7.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "ONDEMAND" - }, - "attributes": [ + }, { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", + "id": 5, + "description": "sort method", + "datatype": "enum", + "valuetype": "FIXED_IN_METER", + "value": "1", "access": "R" }, { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, W", + "id": 6, + "description": "sort object", + "datatype": "object_definition", + "valuetype": "FIXED_IN_METER", + "value": "NONE", "access": "R" - } - ] - }, - { - "tag": "INSTANTANEOUS_ACTIVE_POWER_IMPORT_L3", - "description": "Instantaneous active power L3 (+P)", - "class-id": 3, - "version": 0, - "obis": "1.0.61.7.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "ONDEMAND" - }, - "attributes": [ + }, { - "id": 2, - "description": "value", - "datatype": "long-unsigned", + "id": 7, + "description": "entries in use", + "datatype": "double-long-unsigned", "valuetype": "DYNAMIC", "value": "0", "access": "R" }, { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", + "id": 8, + "description": "profile entries", + "datatype": "double-long-unsigned", "valuetype": "FIXED_IN_PROFILE", - "value": "0, W", + "value": "40", "access": "R" } ] }, { - "tag": "INSTANTANEOUS_ACTIVE_POWER_EXPORT_L1", - "description": "Instantaneous active power L1 (-P)", - "class-id": 3, - "version": 0, - "obis": "1.0.22.7.0.255", - "group": "ELECTRICITY", + "tag": "MONTHLY_VALUES_COMBINED", + "description": "Monthly billing values", + "class-id": 7, + "version": 1, + "obis": "0.0.98.1.0.255", + "group": "ABSTRACT", "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "ONDEMAND" - }, + "properties": {}, "attributes": [ { "id": 2, - "description": "value", - "datatype": "long-unsigned", + "description": "buffer", + "datatype": "array", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", + "description": "capture objects", + "datatype": "array", "valuetype": "FIXED_IN_PROFILE", - "value": "0, W", - "access": "R" - } - ] - }, - { - "tag": "INSTANTANEOUS_ACTIVE_POWER_EXPORT_L2", - "description": "Instantaneous active power L2 (-P)", - "class-id": 3, - "version": 0, - "obis": "1.0.42.7.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "ONDEMAND" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", + "value": "CLOCK,2|ACTIVE_ENERGY_IMPORT_RATE_1,2|ACTIVE_ENERGY_IMPORT_RATE_2,2|ACTIVE_ENERGY_EXPORT_RATE_1,2|ACTIVE_ENERGY_EXPORT_RATE_1,2|MBUS_MASTER_VALUE,2", "access": "R" }, { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", + "id": 4, + "description": "capture period in sec", + "datatype": "double-long-unsigned", "valuetype": "FIXED_IN_PROFILE", - "value": "0, W", - "access": "R" - } - ] - }, - { - "tag": "INSTANTANEOUS_ACTIVE_POWER_EXPORT_L3", - "description": "Instantaneous active power L3 (-P)", - "class-id": 3, - "version": 0, - "obis": "1.0.62.7.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "ONDEMAND" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", "value": "0", "access": "R" }, { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, W", - "access": "R" - } - ] - }, - { - "tag": "AVERAGE_ACTIVE_POWER_IMPORT_L1", - "description": "Average active power (+P) L1", - "class-id": 3, - "version": 0, - "obis": "1.0.21.24.0.255", - "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", + "id": 5, + "description": "sort method", + "datatype": "enum", + "valuetype": "FIXED_IN_METER", + "value": "1", "access": "R" }, { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, W", + "id": 6, + "description": "sort object", + "datatype": "object_definition", + "valuetype": "FIXED_IN_METER", + "value": "NONE", "access": "R" - } - ] - }, - { - "tag": "AVERAGE_ACTIVE_POWER_IMPORT_L2", - "description": "Average active power (+P) L2", - "class-id": 3, - "version": 0, - "obis": "1.0.41.24.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ + }, { - "id": 2, - "description": "value", - "datatype": "long-unsigned", + "id": 7, + "description": "entries in use", + "datatype": "double-long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", + "id": 8, + "description": "profile entries", + "datatype": "double-long-unsigned", "valuetype": "FIXED_IN_PROFILE", - "value": "0, W", + "value": "13", "access": "R" } ] }, { - "tag": "AVERAGE_ACTIVE_POWER_IMPORT_L3", - "description": "Average active power (+P) L3", - "class-id": 3, + "tag": "AMR_PROFILE_STATUS_HOURLY_G", + "description": "AMR Profile Status Code M-Bus", + "class-id": 1, "version": 0, - "obis": "1.0.61.24.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, + "obis": "0.x.96.10.3.255", + "group": "GAS", + "meterTypes": ["SP","PP"], + "properties": {}, "attributes": [ { "id": 2, "description": "value", - "datatype": "long-unsigned", + "datatype": "unsigned", "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, W", "access": "R" } ] }, { - "tag": "AVERAGE_ACTIVE_POWER_EXPORT_L1", - "description": "Average active power (-P) L1", - "class-id": 3, + "tag": "AMR_PROFILE_STATUS", + "description": "AMR Profile Status Code E meter", + "class-id": 1, "version": 0, - "obis": "1.0.22.24.0.255", - "group": "ELECTRICITY", + "obis": "0.0.96.10.2.255", + "group": "ABSTRACT", "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, + "properties": {}, "attributes": [ { "id": 2, "description": "value", - "datatype": "long-unsigned", + "datatype": "unsigned", "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, W", "access": "R" } ] }, { - "tag": "AVERAGE_ACTIVE_POWER_EXPORT_L2", - "description": "Average active power (-P) L2", - "class-id": 3, + "tag": "MBUS_MASTER_VALUE", + "description": "M-Bus volume hourly", + "note": null, + "class-id": 4, "version": 0, - "obis": "1.0.42.24.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, + "obis": "0.x.24.2.1.255", + "group": "GAS", + "meterTypes": ["SP","PP"], + "properties": {}, "attributes": [ { "id": 2, "description": "value", - "datatype": "long-unsigned", + "datatype": "double-long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { "id": 3, "description": "scaler_unit", "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, W", + "valuetype": "BASED_ON_MODEL", + "valuebasedonmodel": { + "type": "GAS_METER_TYPE", + "values": [ + { + "types": ["G4-G6"], + "value": "-3, M3" + }, + { + "types": ["G10-G25"], + "value": "-2, M3" + } + ] + }, "access": "R" - } - ] - }, - { - "tag": "AVERAGE_ACTIVE_POWER_EXPORT_L3", - "description": "Average active power (-P) L3", - "class-id": 3, - "version": 0, - "obis": "1.0.62.24.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ + }, { - "id": 2, - "description": "value", - "datatype": "long-unsigned", + "id": 4, + "description": "status", + "datatype": "unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, W", + "id": 5, + "description": "capture_time", + "datatype": "octet-string", + "valuetype": "DYNAMIC", "access": "R" } ] }, { - "tag": "AVERAGE_REACTIVE_POWER_IMPORT_L1", - "description": "Average reactive power (+Q) L1", - "class-id": 3, + "tag": "ACTIVITY_CALENDAR", + "description": "Activity calendar", + "note": null, + "class-id": 20, "version": 0, - "obis": "1.0.23.24.0.255", - "group": "ELECTRICITY", + "obis": "0.0.13.0.0.255", + "group": "ABSTRACT", "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, "attributes": [ { "id": 2, - "description": "value", - "datatype": "long-unsigned", + "description": "calendar_name_active", + "datatype": "octet-string", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, VAR", - "access": "R" - } - ] - }, - { - "tag": "AVERAGE_REACTIVE_POWER_IMPORT_L2", - "description": "Average reactive power (+Q) L2", - "class-id": 3, - "version": 0, - "obis": "1.0.43.24.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", + "description": "season_profile_active", + "datatype": "array", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, VAR", - "access": "R" - } - ] - }, - { - "tag": "AVERAGE_REACTIVE_POWER_IMPORT_L3", - "description": "Average reactive power (+Q) L3", - "class-id": 3, - "version": 0, - "obis": "1.0.63.24.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", + "id": 4, + "description": "week_profile_table_active", + "datatype": "array", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, VAR", - "access": "R" - } - ] - }, - { - "tag": "AVERAGE_REACTIVE_POWER_EXPORT_L1", - "description": "Average reactive power (-Q) L1", - "class-id": 3, - "version": 0, - "obis": "1.0.24.24.0.255", - "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", + "id": 5, + "description": "day_profile_table_active", + "datatype": "array", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, VAR", - "access": "R" - } - ] - }, - { - "tag": "AVERAGE_REACTIVE_POWER_EXPORT_L2", - "description": "Average reactive power (-Q) L2", - "class-id": 3, - "version": 0, - "obis": "1.0.44.24.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ + "id": 6, + "description": "calendar_name_passive", + "datatype": "octet-string", + "valuetype": "SET_BY_CLIENT", + "access": "RW" + }, { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" + "id": 7, + "description": "season_profile_passive", + "datatype": "array", + "valuetype": "SET_BY_CLIENT", + "access": "RW" }, { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, VAR", - "access": "R" - } - ] - }, - { - "tag": "AVERAGE_REACTIVE_POWER_EXPORT_L3", - "description": "Average reactive power (-Q) L3", - "class-id": 3, - "version": 0, - "obis": "1.0.64.24.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ + "id": 8, + "description": "week_profile_table_passive", + "datatype": "array", + "valuetype": "SET_BY_CLIENT", + "access": "RW" + }, { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" + "id": 9, + "description": "day_profile_table_passive", + "datatype": "array", + "valuetype": "SET_BY_CLIENT", + "access": "RW" }, { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, VAR", - "access": "R" + "id": 10, + "description": "activate_passive_calendar_time", + "datatype": "octet-string", + "valuetype": "SET_BY_CLIENT", + "access": "RW" } ] } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-dsmr22.json.license b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-dsmr22.json.license similarity index 100% rename from osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-dsmr22.json.license rename to osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-dsmr22.json.license diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-dsmr422.json b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-dsmr422.json index fd184d459a5..4ab29f41de3 100644 --- a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-dsmr422.json +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-dsmr422.json @@ -7,11 +7,15 @@ { "tag": "CLOCK", "description": "Clock", + "note": null, "class-id": 8, "version": 0, "obis": "0.0.1.0.0.255", "group": "ABSTRACT", - "meterTypes": ["SP","PP"], + "meterTypes": [ + "SP", + "PP" + ], "attributes": [ { "id": 2, @@ -39,18 +43,141 @@ } ] }, + { + "tag": "ACTIVE_ENERGY_IMPORT_RATE_1", + "description": "Active energy import (+A) rate 1", + "note": null, + "class-id": 3, + "version": 0, + "obis": "1.0.1.8.1.255", + "group": "ELECTRICITY", + "meterTypes": [ + "SP", + "PP" + ], + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "double-long-unsigned", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 3, + "description": "scaler_unit", + "datatype": "scal_unit_type", + "valuetype": "FIXED_IN_PROFILE", + "value": "0, WH", + "access": "R" + } + ] + }, + { + "tag": "ACTIVE_ENERGY_IMPORT_RATE_2", + "description": "Active energy import (+A) rate 2", + "note": null, + "class-id": 3, + "version": 0, + "obis": "1.0.1.8.2.255", + "group": "ELECTRICITY", + "meterTypes": [ + "SP", + "PP" + ], + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "double-long-unsigned", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 3, + "description": "scaler_unit", + "datatype": "scal_unit_type", + "valuetype": "FIXED_IN_PROFILE", + "value": "0, WH", + "access": "R" + } + ] + }, + { + "tag": "ACTIVE_ENERGY_EXPORT_RATE_1", + "description": "Active energy export (-A) rate 1", + "note": null, + "class-id": 3, + "version": 0, + "obis": "1.0.2.8.1.255", + "group": "ELECTRICITY", + "meterTypes": [ + "SP", + "PP" + ], + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "double-long-unsigned", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 3, + "description": "scaler_unit", + "datatype": "scal_unit_type", + "valuetype": "FIXED_IN_PROFILE", + "value": "0, WH", + "access": "R" + } + ] + }, + { + "tag": "ACTIVE_ENERGY_EXPORT_RATE_2", + "description": "Active energy export (-A) rate 2", + "note": null, + "class-id": 3, + "version": 0, + "obis": "1.0.2.8.2.255", + "group": "ELECTRICITY", + "meterTypes": [ + "SP", + "PP" + ], + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "double-long-unsigned", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 3, + "description": "scaler_unit", + "datatype": "scal_unit_type", + "valuetype": "FIXED_IN_PROFILE", + "value": "0, WH", + "access": "R" + } + ] + }, { "tag": "DEFINABLE_LOAD_PROFILE", "description": "Definable load profile", + "note": "Attribute 4 (capture period in sec) is overridden in factory with value 900 (default in spec: 86400)", "class-id": 7, "version": 1, "obis": "0.1.94.31.6.255", "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], + "meterTypes": [ + "SP", + "PP" + ], "properties": { "SELECTABLE_OBJECTS": [ "CLOCK", - "GPRS_DIAGNOSTIC", "NUMBER_OF_VOLTAGE_SWELLS_FOR_L1", "NUMBER_OF_VOLTAGE_SAGS_FOR_L1", "NUMBER_OF_POWER_FAILURES", @@ -83,7 +210,6 @@ "description": "buffer", "datatype": "array", "valuetype": "DYNAMIC", - "value": "EMPTY", "access": "R" }, { @@ -91,15 +217,15 @@ "description": "capture objects", "datatype": "array", "valuetype": "SET_BY_CLIENT", - "value": "EMPTY", "access": "RW" }, { "id": 4, "description": "capture period in sec", + "note": "Attribute 4 (capture period in sec) is overridden in factory with value 900 (default in spec: 86400)", "datatype": "double-long-unsigned", "valuetype": "SET_BY_CLIENT", - "value": "86400", + "value": "900", "access": "RW" }, { @@ -123,7 +249,6 @@ "description": "entries in use", "datatype": "double-long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -137,87 +262,162 @@ ] }, { - "tag": "GPRS_DIAGNOSTIC", - "description": "GPRS Diagnostic", - "class-id": 47, + "tag": "NUMBER_OF_VOLTAGE_SWELLS_FOR_L1", + "description": "Number of voltage swells in phase L1", + "note": null, + "class-id": 1, "version": 0, - "obis": "0.0.25.6.0.255", + "obis": "1.0.32.36.0.255", "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], + "meterTypes": [ + "SP", + "PP" + ], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "PERIODIC" + "PQ_REQUEST": [ + "ACTUAL_SP", + "ACTUAL_PP", + "PERIODIC_SP" + ] }, "attributes": [ { "id": 2, - "description": "operator", - "datatype": "visible-string", - "valuetype": "DYNAMIC", - "value": "EMPTY", - "access": "R" - }, - { - "id": 3, - "description": "status", - "datatype": "enum", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 4, - "description": "cs attachment", - "datatype": "enum", + "description": "value", + "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" - }, + } + ] + }, + { + "tag": "NUMBER_OF_VOLTAGE_SWELLS_FOR_L2", + "description": "Number of voltage swells in phase L2", + "note": null, + "class-id": 1, + "version": 0, + "obis": "1.0.52.36.0.255", + "group": "ELECTRICITY", + "meterTypes": [ + "PP" + ], + "properties": { + "PQ_PROFILE": "PUBLIC", + "PQ_REQUEST": [ + "ACTUAL_PP" + ] + }, + "attributes": [ { - "id": 5, - "description": "ps status", - "datatype": "enum", + "id": 2, + "description": "value", + "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, + "access": "R" + } + ] + }, + { + "tag": "NUMBER_OF_VOLTAGE_SWELLS_FOR_L3", + "description": "Number of voltage swells in phase L3", + "note": null, + "class-id": 1, + "version": 0, + "obis": "1.0.72.36.0.255", + "group": "ELECTRICITY", + "meterTypes": [ + "PP" + ], + "properties": { + "PQ_PROFILE": "PUBLIC", + "PQ_REQUEST": [ + "ACTUAL_PP" + ] + }, + "attributes": [ { - "id": 6, - "description": "cell info", - "datatype": "cell_info_type", + "id": 2, + "description": "value", + "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "EMPTY", "access": "R" - }, + } + ] + }, + { + "tag": "NUMBER_OF_VOLTAGE_SAGS_FOR_L1", + "description": "Number of voltage sags in phase L1", + "note": null, + "class-id": 1, + "version": 0, + "obis": "1.0.32.32.0.255", + "group": "ELECTRICITY", + "meterTypes": [ + "SP", + "PP" + ], + "properties": { + "PQ_PROFILE": "PUBLIC", + "PQ_REQUEST": [ + "ACTUAL_SP", + "ACTUAL_PP", + "PERIODIC_SP" + ] + }, + "attributes": [ { - "id": 7, - "description": "adjacent cells", - "datatype": "array", + "id": 2, + "description": "value", + "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "EMPTY", "access": "R" - }, + } + ] + }, + { + "tag": "NUMBER_OF_VOLTAGE_SAGS_FOR_L2", + "description": "Number of voltage sags in phase L2", + "note": null, + "class-id": 1, + "version": 0, + "obis": "1.0.52.32.0.255", + "group": "ELECTRICITY", + "meterTypes": [ + "PP" + ], + "properties": { + "PQ_PROFILE": "PUBLIC", + "PQ_REQUEST": [ + "ACTUAL_PP" + ] + }, + "attributes": [ { - "id": 8, - "description": "capture time", - "datatype": "date-time", + "id": 2, + "description": "value", + "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "EMPTY", "access": "R" } ] }, { - "tag": "NUMBER_OF_VOLTAGE_SWELLS_FOR_L1", - "description": "Number of voltage swells in phase L1", + "tag": "NUMBER_OF_VOLTAGE_SAGS_FOR_L3", + "description": "Number of voltage sags in phase L3", + "note": null, "class-id": 1, "version": 0, - "obis": "1.0.32.36.0.255", + "obis": "1.0.72.32.0.255", "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], + "meterTypes": [ + "PP" + ], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": [ + "ACTUAL_PP" + ] }, "attributes": [ { @@ -225,22 +425,28 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" } ] }, { - "tag": "NUMBER_OF_VOLTAGE_SAGS_FOR_L1", - "description": "Number of voltage sags in phase L1", + "tag": "NUMBER_OF_LONG_POWER_FAILURES", + "description": "Number of long power failures in any phases", + "note": null, "class-id": 1, "version": 0, - "obis": "1.0.32.32.0.255", + "obis": "0.0.96.7.9.255", "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], + "meterTypes": [ + "SP", + "PP" + ], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": [ + "ACTUAL_SP", + "ACTUAL_PP" + ] }, "attributes": [ { @@ -248,7 +454,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" } ] @@ -256,14 +461,22 @@ { "tag": "NUMBER_OF_POWER_FAILURES", "description": "Number of power failures in any phases", + "note": null, "class-id": 1, "version": 0, "obis": "0.0.96.7.21.255", "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], + "meterTypes": [ + "SP", + "PP" + ], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": [ + "ACTUAL_SP", + "ACTUAL_PP", + "PERIODIC_SP" + ] }, "attributes": [ { @@ -271,7 +484,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" } ] @@ -279,14 +491,23 @@ { "tag": "INSTANTANEOUS_VOLTAGE_L1", "description": "Instantaneous voltage L1", + "note": "Attribute 3 (scaler_unit) is default in spec: '0, V', this is overridden in factory with value -1, V for some meter-types (so use valuetype dynamic)", "class-id": 3, "version": 0, "obis": "1.0.32.7.0.255", "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], + "meterTypes": [ + "SP", + "PP" + ], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": [ + "ACTUAL_SP", + "ACTUAL_PP", + "PERIODIC_SP", + "PERIODIC_PP" + ] }, "attributes": [ { @@ -294,15 +515,15 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { "id": 3, "description": "scaler_unit", + "note": "Attribute 3 (scaler_unit) is default in spec: '0, V', this is overridden in factory with value -1, V for some meter-types (so use valuetype dynamic)", "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "-1, V", + "valuetype": "DYNAMIC", + "value": "0, V", "access": "RW" } ] @@ -310,14 +531,20 @@ { "tag": "INSTANTANEOUS_VOLTAGE_L2", "description": "Instantaneous voltage L2", + "note": "Attribute 3 (scaler_unit) is default in spec: '0, V', this is overridden in factory with value -1, V for some meter-types (so use valuetype dynamic)", "class-id": 3, "version": 0, "obis": "1.0.52.7.0.255", "group": "ELECTRICITY", - "meterTypes": ["PP"], + "meterTypes": [ + "PP" + ], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": [ + "ACTUAL_PP", + "PERIODIC_PP" + ] }, "attributes": [ { @@ -325,15 +552,15 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { "id": 3, "description": "scaler_unit", + "note": "Attribute 3 (scaler_unit) is default in spec: '0, V', this is overridden in factory with value -1, V for some meter-types (so use valuetype dynamic)", "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "-1, V", + "valuetype": "DYNAMIC", + "value": "0, V", "access": "RW" } ] @@ -341,14 +568,20 @@ { "tag": "INSTANTANEOUS_VOLTAGE_L3", "description": "Instantaneous voltage L3", + "note": "Attribute 3 (scaler_unit) is default in spec: '0, V', this is overridden in factory with value -1, V for some meter-types (so use valuetype dynamic)", "class-id": 3, "version": 0, "obis": "1.0.72.7.0.255", "group": "ELECTRICITY", - "meterTypes": ["PP"], + "meterTypes": [ + "PP" + ], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": [ + "ACTUAL_PP", + "PERIODIC_PP" + ] }, "attributes": [ { @@ -356,15 +589,15 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { "id": 3, "description": "scaler_unit", + "note": "Attribute 3 (scaler_unit) is default in spec: '0, V', this is overridden in factory with value -1, V for some meter-types (so use valuetype dynamic)", "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "-1, V", + "valuetype": "DYNAMIC", + "value": "0, V", "access": "RW" } ] @@ -372,14 +605,23 @@ { "tag": "AVERAGE_VOLTAGE_L1", "description": "Average voltage L1", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.32.24.0.255", "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], + "meterTypes": [ + "SP", + "PP" + ], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": [ + "ACTUAL_SP", + "ACTUAL_PP", + "PERIODIC_SP", + "PERIODIC_PP" + ] }, "attributes": [ { @@ -387,7 +629,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -395,7 +636,7 @@ "description": "scaler_unit", "datatype": "scal_unit_type", "valuetype": "FIXED_IN_PROFILE", - "value": "-1, V", + "value": "0, V", "access": "R" } ] @@ -403,14 +644,20 @@ { "tag": "AVERAGE_VOLTAGE_L2", "description": "Average voltage L2", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.52.24.0.255", "group": "ELECTRICITY", - "meterTypes": ["PP"], + "meterTypes": [ + "PP" + ], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": [ + "ACTUAL_PP", + "PERIODIC_PP" + ] }, "attributes": [ { @@ -418,7 +665,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -426,7 +672,7 @@ "description": "scaler_unit", "datatype": "scal_unit_type", "valuetype": "FIXED_IN_PROFILE", - "value": "-1, V", + "value": "0, V", "access": "R" } ] @@ -434,14 +680,20 @@ { "tag": "AVERAGE_VOLTAGE_L3", "description": "Average voltage L3", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.72.24.0.255", "group": "ELECTRICITY", - "meterTypes": ["PP"], + "meterTypes": [ + "PP" + ], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": [ + "ACTUAL_PP", + "PERIODIC_PP" + ] }, "attributes": [ { @@ -449,7 +701,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -457,7 +708,7 @@ "description": "scaler_unit", "datatype": "scal_unit_type", "valuetype": "FIXED_IN_PROFILE", - "value": "-1, V", + "value": "0, V", "access": "R" } ] @@ -465,14 +716,22 @@ { "tag": "INSTANTANEOUS_CURRENT_L1", "description": "Instantaneous current L1", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.31.7.0.255", "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], + "meterTypes": [ + "SP", + "PP" + ], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": [ + "ACTUAL_SP", + "ACTUAL_PP", + "PERIODIC_SP" + ] }, "attributes": [ { @@ -480,7 +739,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -488,22 +746,27 @@ "description": "scaler_unit", "datatype": "scal_unit_type", "valuetype": "FIXED_IN_PROFILE", - "value": "-2, A", + "value": "0, A", "access": "RW" } ] }, { - "tag": "AVERAGE_CURRENT_L1", - "description": "Average current L1", + "tag": "INSTANTANEOUS_CURRENT_L2", + "description": "Instantaneous current L2", + "note": null, "class-id": 3, "version": 0, - "obis": "1.0.31.24.0.255", + "obis": "1.0.51.7.0.255", "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], + "meterTypes": [ + "PP" + ], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": [ + "ACTUAL_PP" + ] }, "attributes": [ { @@ -511,7 +774,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -519,22 +781,27 @@ "description": "scaler_unit", "datatype": "scal_unit_type", "valuetype": "FIXED_IN_PROFILE", - "value": "-2, A", - "access": "R" + "value": "0, A", + "access": "RW" } ] }, { - "tag": "INSTANTANEOUS_ACTIVE_CURRENT_TOTAL_OVER_ALL_PHASES", - "description": "Instantaneous current total", + "tag": "INSTANTANEOUS_CURRENT_L3", + "description": "Instantaneous current L3", + "note": null, "class-id": 3, "version": 0, - "obis": "1.0.90.7.0.255", + "obis": "1.0.71.7.0.255", "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], + "meterTypes": [ + "PP" + ], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": [ + "ACTUAL_PP" + ] }, "attributes": [ { @@ -542,7 +809,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -550,22 +816,30 @@ "description": "scaler_unit", "datatype": "scal_unit_type", "valuetype": "FIXED_IN_PROFILE", - "value": "-2, A", - "access": "R" + "value": "0, A", + "access": "RW" } ] }, { - "tag": "AVERAGE_ACTIVE_POWER_IMPORT_L1", - "description": "Average active power (+P) L1", + "tag": "AVERAGE_CURRENT_L1", + "description": "Average current L1", + "note": null, "class-id": 3, "version": 0, - "obis": "1.0.21.24.0.255", + "obis": "1.0.31.24.0.255", "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], + "meterTypes": [ + "SP", + "PP" + ], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": [ + "ACTUAL_SP", + "ACTUAL_PP", + "PERIODIC_SP" + ] }, "attributes": [ { @@ -573,7 +847,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -581,22 +854,27 @@ "description": "scaler_unit", "datatype": "scal_unit_type", "valuetype": "FIXED_IN_PROFILE", - "value": "0, W", + "value": "0, A", "access": "R" } ] }, { - "tag": "AVERAGE_ACTIVE_POWER_IMPORT_L2", - "description": "Average active power (+P) L2", + "tag": "AVERAGE_CURRENT_L2", + "description": "Average current L2", + "note": null, "class-id": 3, "version": 0, - "obis": "1.0.41.24.0.255", + "obis": "1.0.51.24.0.255", "group": "ELECTRICITY", - "meterTypes": ["PP"], + "meterTypes": [ + "PP" + ], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": [ + "ACTUAL_PP" + ] }, "attributes": [ { @@ -604,7 +882,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -612,22 +889,102 @@ "description": "scaler_unit", "datatype": "scal_unit_type", "valuetype": "FIXED_IN_PROFILE", - "value": "0, W", + "value": "0, A", "access": "R" } ] }, { - "tag": "AVERAGE_ACTIVE_POWER_IMPORT_L3", - "description": "Average active power (+P) L3", + "tag": "AVERAGE_CURRENT_L3", + "description": "Average current L3", + "note": null, "class-id": 3, "version": 0, - "obis": "1.0.61.24.0.255", + "obis": "1.0.71.24.0.255", "group": "ELECTRICITY", - "meterTypes": ["PP"], + "meterTypes": [ + "PP" + ], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": [ + "ACTUAL_PP" + ] + }, + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "long-unsigned", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 3, + "description": "scaler_unit", + "datatype": "scal_unit_type", + "valuetype": "FIXED_IN_PROFILE", + "value": "0, A", + "access": "R" + } + ] + }, + { + "tag": "INSTANTANEOUS_ACTIVE_CURRENT_TOTAL_OVER_ALL_PHASES", + "description": "Instantaneous current total", + "note": null, + "class-id": 3, + "version": 0, + "obis": "1.0.90.7.0.255", + "group": "ELECTRICITY", + "meterTypes": [ + "SP", + "PP" + ], + "properties": { + "PQ_PROFILE": "PRIVATE", + "PQ_REQUEST": [ + "ACTUAL_SP", + "ACTUAL_PP", + "PERIODIC_PP" + ] + }, + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "long-unsigned", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 3, + "description": "scaler_unit", + "datatype": "scal_unit_type", + "valuetype": "FIXED_IN_PROFILE", + "value": "0, A", + "access": "R" + } + ] + }, + { + "tag": "INSTANTANEOUS_ACTIVE_POWER_IMPORT", + "description": "Instantaneous active power (+P)", + "note": null, + "class-id": 3, + "version": 0, + "obis": "1.0.1.7.0.255", + "group": "ELECTRICITY", + "meterTypes": [ + "SP", + "PP" + ], + "properties": { + "PQ_PROFILE": "PRIVATE", + "PQ_REQUEST": [ + "ACTUAL_SP", + "ACTUAL_PP" + ] }, "attributes": [ { @@ -635,7 +992,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -649,16 +1005,23 @@ ] }, { - "tag": "AVERAGE_ACTIVE_POWER_EXPORT_L1", - "description": "Average active power (-P) L1", + "tag": "INSTANTANEOUS_ACTIVE_POWER_EXPORT", + "description": "Instantaneous active power (-P)", + "note": null, "class-id": 3, "version": 0, - "obis": "1.0.22.24.0.255", + "obis": "1.0.2.7.0.255", "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], + "meterTypes": [ + "SP", + "PP" + ], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": [ + "ACTUAL_SP", + "ACTUAL_PP" + ] }, "attributes": [ { @@ -666,7 +1029,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -680,16 +1042,23 @@ ] }, { - "tag": "AVERAGE_ACTIVE_POWER_EXPORT_L2", - "description": "Average active power (-P) L2", + "tag": "INSTANTANEOUS_ACTIVE_POWER_IMPORT_L1", + "description": "Instantaneous active power L1 (+P)", + "note": null, "class-id": 3, "version": 0, - "obis": "1.0.42.24.0.255", + "obis": "1.0.21.7.0.255", "group": "ELECTRICITY", - "meterTypes": ["PP"], + "meterTypes": [ + "SP", + "PP" + ], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": [ + "ACTUAL_SP", + "ACTUAL_PP" + ] }, "attributes": [ { @@ -697,7 +1066,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -711,16 +1079,21 @@ ] }, { - "tag": "AVERAGE_ACTIVE_POWER_EXPORT_L3", - "description": "Average active power (-P) L3", + "tag": "INSTANTANEOUS_ACTIVE_POWER_IMPORT_L2", + "description": "Instantaneous active power L2 (+P)", + "note": null, "class-id": 3, "version": 0, - "obis": "1.0.62.24.0.255", + "obis": "1.0.41.7.0.255", "group": "ELECTRICITY", - "meterTypes": ["PP"], + "meterTypes": [ + "PP" + ], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": [ + "ACTUAL_PP" + ] }, "attributes": [ { @@ -728,7 +1101,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -742,16 +1114,21 @@ ] }, { - "tag": "AVERAGE_REACTIVE_POWER_IMPORT_L1", - "description": "Average reactive power (+Q) L1", + "tag": "INSTANTANEOUS_ACTIVE_POWER_IMPORT_L3", + "description": "Instantaneous active power L3 (+P)", + "note": null, "class-id": 3, "version": 0, - "obis": "1.0.23.24.0.255", + "obis": "1.0.61.7.0.255", "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], + "meterTypes": [ + "PP" + ], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": [ + "ACTUAL_PP" + ] }, "attributes": [ { @@ -759,7 +1136,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -767,22 +1143,29 @@ "description": "scaler_unit", "datatype": "scal_unit_type", "valuetype": "FIXED_IN_PROFILE", - "value": "0, var", + "value": "0, W", "access": "R" } ] }, { - "tag": "AVERAGE_REACTIVE_POWER_IMPORT_L2", - "description": "Average reactive power (+Q) L2", + "tag": "INSTANTANEOUS_ACTIVE_POWER_EXPORT_L1", + "description": "Instantaneous active power L1 (-P)", + "note": null, "class-id": 3, "version": 0, - "obis": "1.0.43.24.0.255", + "obis": "1.0.22.7.0.255", "group": "ELECTRICITY", - "meterTypes": ["PP"], + "meterTypes": [ + "SP", + "PP" + ], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": [ + "ACTUAL_SP", + "ACTUAL_PP" + ] }, "attributes": [ { @@ -790,7 +1173,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -798,22 +1180,27 @@ "description": "scaler_unit", "datatype": "scal_unit_type", "valuetype": "FIXED_IN_PROFILE", - "value": "0, var", + "value": "0, W", "access": "R" } ] }, { - "tag": "AVERAGE_REACTIVE_POWER_IMPORT_L3", - "description": "Average reactive power (+Q) L3", + "tag": "INSTANTANEOUS_ACTIVE_POWER_EXPORT_L2", + "description": "Instantaneous active power L2 (-P)", + "note": null, "class-id": 3, "version": 0, - "obis": "1.0.63.24.0.255", + "obis": "1.0.42.7.0.255", "group": "ELECTRICITY", - "meterTypes": ["PP"], + "meterTypes": [ + "PP" + ], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": [ + "ACTUAL_PP" + ] }, "attributes": [ { @@ -821,7 +1208,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -829,22 +1215,27 @@ "description": "scaler_unit", "datatype": "scal_unit_type", "valuetype": "FIXED_IN_PROFILE", - "value": "0, var", + "value": "0, W", "access": "R" } ] }, { - "tag": "AVERAGE_REACTIVE_POWER_EXPORT_L1", - "description": "Average reactive power (-Q) L1", + "tag": "INSTANTANEOUS_ACTIVE_POWER_EXPORT_L3", + "description": "Instantaneous active power L3 (-P)", + "note": null, "class-id": 3, "version": 0, - "obis": "1.0.24.24.0.255", + "obis": "1.0.62.7.0.255", "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], + "meterTypes": [ + "PP" + ], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": [ + "ACTUAL_PP" + ] }, "attributes": [ { @@ -852,7 +1243,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -860,22 +1250,31 @@ "description": "scaler_unit", "datatype": "scal_unit_type", "valuetype": "FIXED_IN_PROFILE", - "value": "0, var", + "value": "0, W", "access": "R" } ] }, { - "tag": "AVERAGE_REACTIVE_POWER_EXPORT_L2", - "description": "Average reactive power (-Q) L2", + "tag": "AVERAGE_ACTIVE_POWER_IMPORT_L1", + "description": "Average active power (+P) L1", + "note": null, "class-id": 3, "version": 0, - "obis": "1.0.44.24.0.255", + "obis": "1.0.21.24.0.255", "group": "ELECTRICITY", - "meterTypes": ["PP"], + "meterTypes": [ + "SP", + "PP" + ], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": [ + "ACTUAL_SP", + "ACTUAL_PP", + "PERIODIC_SP", + "PERIODIC_PP" + ] }, "attributes": [ { @@ -883,7 +1282,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -891,22 +1289,175 @@ "description": "scaler_unit", "datatype": "scal_unit_type", "valuetype": "FIXED_IN_PROFILE", - "value": "0, var", + "value": "0, W", "access": "R" } ] }, { - "tag": "AVERAGE_REACTIVE_POWER_EXPORT_L3", - "description": "Average reactive power (-Q) L3", + "tag": "AVERAGE_ACTIVE_POWER_IMPORT_L2", + "description": "Average active power (+P) L2", + "note": null, "class-id": 3, "version": 0, - "obis": "1.0.64.24.0.255", + "obis": "1.0.41.24.0.255", "group": "ELECTRICITY", - "meterTypes": ["PP"], + "meterTypes": [ + "PP" + ], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": [ + "ACTUAL_PP", + "PERIODIC_PP" + ] + }, + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "long-unsigned", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 3, + "description": "scaler_unit", + "datatype": "scal_unit_type", + "valuetype": "FIXED_IN_PROFILE", + "value": "0, W", + "access": "R" + } + ] + }, + { + "tag": "AVERAGE_ACTIVE_POWER_IMPORT_L3", + "description": "Average active power (+P) L3", + "note": null, + "class-id": 3, + "version": 0, + "obis": "1.0.61.24.0.255", + "group": "ELECTRICITY", + "meterTypes": [ + "PP" + ], + "properties": { + "PQ_PROFILE": "PRIVATE", + "PQ_REQUEST": [ + "ACTUAL_PP", + "PERIODIC_PP" + ] + }, + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "long-unsigned", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 3, + "description": "scaler_unit", + "datatype": "scal_unit_type", + "valuetype": "FIXED_IN_PROFILE", + "value": "0, W", + "access": "R" + } + ] + }, + { + "tag": "AVERAGE_ACTIVE_POWER_EXPORT_L1", + "description": "Average active power (-P) L1", + "note": null, + "class-id": 3, + "version": 0, + "obis": "1.0.22.24.0.255", + "group": "ELECTRICITY", + "meterTypes": [ + "SP", + "PP" + ], + "properties": { + "PQ_PROFILE": "PRIVATE", + "PQ_REQUEST": [ + "ACTUAL_SP", + "ACTUAL_PP", + "PERIODIC_SP", + "PERIODIC_PP" + ] + }, + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "long-unsigned", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 3, + "description": "scaler_unit", + "datatype": "scal_unit_type", + "valuetype": "FIXED_IN_PROFILE", + "value": "0, W", + "access": "R" + } + ] + }, + { + "tag": "AVERAGE_ACTIVE_POWER_EXPORT_L2", + "description": "Average active power (-P) L2", + "note": null, + "class-id": 3, + "version": 0, + "obis": "1.0.42.24.0.255", + "group": "ELECTRICITY", + "meterTypes": [ + "PP" + ], + "properties": { + "PQ_PROFILE": "PRIVATE", + "PQ_REQUEST": [ + "ACTUAL_PP", + "PERIODIC_PP" + ] + }, + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "long-unsigned", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 3, + "description": "scaler_unit", + "datatype": "scal_unit_type", + "valuetype": "FIXED_IN_PROFILE", + "value": "0, W", + "access": "R" + } + ] + }, + { + "tag": "AVERAGE_ACTIVE_POWER_EXPORT_L3", + "description": "Average active power (-P) L3", + "note": null, + "class-id": 3, + "version": 0, + "obis": "1.0.62.24.0.255", + "group": "ELECTRICITY", + "meterTypes": [ + "PP" + ], + "properties": { + "PQ_PROFILE": "PRIVATE", + "PQ_REQUEST": [ + "ACTUAL_PP", + "PERIODIC_PP" + ] }, "attributes": [ { @@ -914,7 +1465,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -922,8 +1472,683 @@ "description": "scaler_unit", "datatype": "scal_unit_type", "valuetype": "FIXED_IN_PROFILE", - "value": "0, var", + "value": "0, W", + "access": "R" + } + ] + }, + { + "tag": "AVERAGE_REACTIVE_POWER_IMPORT_L1", + "description": "Average reactive power (+Q) L1", + "note": null, + "class-id": 3, + "version": 0, + "obis": "1.0.23.24.0.255", + "group": "ELECTRICITY", + "meterTypes": [ + "SP", + "PP" + ], + "properties": { + "PQ_PROFILE": "PRIVATE", + "PQ_REQUEST": [ + "ACTUAL_SP", + "ACTUAL_PP", + "PERIODIC_SP", + "PERIODIC_PP" + ] + }, + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "long-unsigned", + "valuetype": "DYNAMIC", "access": "R" + }, + { + "id": 3, + "description": "scaler_unit", + "datatype": "scal_unit_type", + "valuetype": "FIXED_IN_PROFILE", + "value": "0, VAR", + "access": "R" + } + ] + }, + { + "tag": "AVERAGE_REACTIVE_POWER_IMPORT_L2", + "description": "Average reactive power (+Q) L2", + "note": null, + "class-id": 3, + "version": 0, + "obis": "1.0.43.24.0.255", + "group": "ELECTRICITY", + "meterTypes": [ + "PP" + ], + "properties": { + "PQ_PROFILE": "PRIVATE", + "PQ_REQUEST": [ + "ACTUAL_PP", + "PERIODIC_PP" + ] + }, + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "long-unsigned", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 3, + "description": "scaler_unit", + "datatype": "scal_unit_type", + "valuetype": "FIXED_IN_PROFILE", + "value": "0, VAR", + "access": "R" + } + ] + }, + { + "tag": "AVERAGE_REACTIVE_POWER_IMPORT_L3", + "description": "Average reactive power (+Q) L3", + "note": null, + "class-id": 3, + "version": 0, + "obis": "1.0.63.24.0.255", + "group": "ELECTRICITY", + "meterTypes": [ + "PP" + ], + "properties": { + "PQ_PROFILE": "PRIVATE", + "PQ_REQUEST": [ + "ACTUAL_PP", + "PERIODIC_PP" + ] + }, + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "long-unsigned", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 3, + "description": "scaler_unit", + "datatype": "scal_unit_type", + "valuetype": "FIXED_IN_PROFILE", + "value": "0, VAR", + "access": "R" + } + ] + }, + { + "tag": "AVERAGE_REACTIVE_POWER_EXPORT_L1", + "description": "Average reactive power (-Q) L1", + "note": null, + "class-id": 3, + "version": 0, + "obis": "1.0.24.24.0.255", + "group": "ELECTRICITY", + "meterTypes": [ + "SP", + "PP" + ], + "properties": { + "PQ_PROFILE": "PRIVATE", + "PQ_REQUEST": [ + "ACTUAL_SP", + "ACTUAL_PP", + "PERIODIC_SP", + "PERIODIC_PP" + ] + }, + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "long-unsigned", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 3, + "description": "scaler_unit", + "datatype": "scal_unit_type", + "valuetype": "FIXED_IN_PROFILE", + "value": "0, VAR", + "access": "R" + } + ] + }, + { + "tag": "AVERAGE_REACTIVE_POWER_EXPORT_L2", + "description": "Average reactive power (-Q) L2", + "note": null, + "class-id": 3, + "version": 0, + "obis": "1.0.44.24.0.255", + "group": "ELECTRICITY", + "meterTypes": [ + "PP" + ], + "properties": { + "PQ_PROFILE": "PRIVATE", + "PQ_REQUEST": [ + "ACTUAL_PP", + "PERIODIC_PP" + ] + }, + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "long-unsigned", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 3, + "description": "scaler_unit", + "datatype": "scal_unit_type", + "valuetype": "FIXED_IN_PROFILE", + "value": "0, VAR", + "access": "R" + } + ] + }, + { + "tag": "AVERAGE_REACTIVE_POWER_EXPORT_L3", + "description": "Average reactive power (-Q) L3", + "note": null, + "class-id": 3, + "version": 0, + "obis": "1.0.64.24.0.255", + "group": "ELECTRICITY", + "meterTypes": [ + "PP" + ], + "properties": { + "PQ_PROFILE": "PRIVATE", + "PQ_REQUEST": [ + "ACTUAL_PP", + "PERIODIC_PP" + ] + }, + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "long-unsigned", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 3, + "description": "scaler_unit", + "datatype": "scal_unit_type", + "valuetype": "FIXED_IN_PROFILE", + "value": "0, VAR", + "access": "R" + } + ] + }, + { + "tag": "ALARM_REGISTER_1", + "description": "Alarm register 1", + "note": null, + "class-id": 1, + "version": 0, + "obis": "0.0.97.98.0.255", + "group": "ELECTRICITY", + "meterTypes": [ + "SP", + "PP" + ], + "properties": {}, + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "double-long-unsigned", + "valuetype": "DYNAMIC", + "access": "RW" + } + ] + }, + { + "tag": "ALARM_FILTER_1", + "description": "Alarm filter 1", + "note": null, + "class-id": 1, + "version": 0, + "obis": "0.0.97.98.10.255", + "group": "ELECTRICITY", + "meterTypes": [ + "SP", + "PP" + ], + "properties": {}, + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "double-long-unsigned", + "valuetype": "DYNAMIC", + "access": "RW" + } + ] + }, + { + "tag": "INTERVAL_VALUES_G", + "description": "Hourly interval readings of M-Bus device", + "class-id": 7, + "version": 1, + "obis": "0.x.24.3.0.255", + "group": "GAS", + "meterTypes": ["SP","PP"], + "properties": {}, + "attributes": [ + { + "id": 2, + "description": "buffer", + "datatype": "array", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 3, + "description": "capture objects", + "datatype": "array", + "valuetype": "FIXED_IN_PROFILE", + "value": "CLOCK,2|AMR_PROFILE_STATUS_HOURLY_G,2|MBUS_MASTER_VALUE,2|MBUS_MASTER_VALUE,5", + "access": "R" + }, + { + "id": 4, + "description": "capture period in sec", + "datatype": "double-long-unsigned", + "valuetype": "FIXED_IN_PROFILE", + "value": "3600", + "access": "R" + }, + { + "id": 5, + "description": "sort method", + "datatype": "enum", + "valuetype": "FIXED_IN_METER", + "value": "1", + "access": "R" + }, + { + "id": 6, + "description": "sort object", + "datatype": "object_definition", + "valuetype": "FIXED_IN_METER", + "value": "NONE", + "access": "R" + }, + { + "id": 7, + "description": "entries in use", + "datatype": "double-long-unsigned", + "valuetype": "DYNAMIC", + "value": "0", + "access": "R" + }, + { + "id": 8, + "description": "profile entries", + "datatype": "double-long-unsigned", + "valuetype": "FIXED_IN_PROFILE", + "value": "240", + "access": "R" + } + ] + }, + { + "tag": "DAILY_VALUES_COMBINED", + "description": "Daily combined billing", + "class-id": 7, + "version": 1, + "obis": "1.0.99.2.0.255", + "group": "ELECTRICITY", + "meterTypes": ["SP","PP"], + "properties": {}, + "attributes": [ + { + "id": 2, + "description": "buffer", + "datatype": "array", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 3, + "description": "capture objects", + "datatype": "array", + "valuetype": "FIXED_IN_PROFILE", + "value": "CLOCK,2|AMR_PROFILE_STATUS,2|ACTIVE_ENERGY_IMPORT_RATE_1,2|ACTIVE_ENERGY_IMPORT_RATE_2,2|ACTIVE_ENERGY_EXPORT_RATE_1,2|ACTIVE_ENERGY_EXPORT_RATE_1,2|MBUS_MASTER_VALUE,2|MBUS_MASTER_VALUE,5", + "access": "R" + }, + { + "id": 4, + "description": "capture period in sec", + "datatype": "double-long-unsigned", + "valuetype": "FIXED_IN_PROFILE", + "value": "86400", + "access": "R" + }, + { + "id": 5, + "description": "sort method", + "datatype": "enum", + "valuetype": "FIXED_IN_METER", + "value": "1", + "access": "R" + }, + { + "id": 6, + "description": "sort object", + "datatype": "object_definition", + "valuetype": "FIXED_IN_METER", + "value": "NONE", + "access": "R" + }, + { + "id": 7, + "description": "entries in use", + "datatype": "double-long-unsigned", + "valuetype": "DYNAMIC", + "value": "0", + "access": "R" + }, + { + "id": 8, + "description": "profile entries", + "datatype": "double-long-unsigned", + "valuetype": "FIXED_IN_PROFILE", + "value": "40", + "access": "R" + } + ] + }, + { + "tag": "MONTHLY_VALUES_COMBINED", + "description": "Monthly billing values", + "class-id": 7, + "version": 1, + "obis": "0.0.98.1.0.255", + "group": "ABSTRACT", + "meterTypes": ["SP","PP"], + "properties": {}, + "attributes": [ + { + "id": 2, + "description": "buffer", + "datatype": "array", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 3, + "description": "capture objects", + "datatype": "array", + "valuetype": "FIXED_IN_PROFILE", + "value": "CLOCK,2|ACTIVE_ENERGY_IMPORT_RATE_1,2|ACTIVE_ENERGY_IMPORT_RATE_2,2|ACTIVE_ENERGY_EXPORT_RATE_1,2|ACTIVE_ENERGY_EXPORT_RATE_1,2|MBUS_MASTER_VALUE,2|MBUS_MASTER_VALUE,5", + "access": "R" + }, + { + "id": 4, + "description": "capture period in sec", + "datatype": "double-long-unsigned", + "valuetype": "FIXED_IN_PROFILE", + "value": "0", + "access": "R" + }, + { + "id": 5, + "description": "sort method", + "datatype": "enum", + "valuetype": "FIXED_IN_METER", + "value": "1", + "access": "R" + }, + { + "id": 6, + "description": "sort object", + "datatype": "object_definition", + "valuetype": "FIXED_IN_METER", + "value": "NONE", + "access": "R" + }, + { + "id": 7, + "description": "entries in use", + "datatype": "double-long-unsigned", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 8, + "description": "profile entries", + "datatype": "double-long-unsigned", + "valuetype": "FIXED_IN_PROFILE", + "value": "13", + "access": "R" + } + ] + }, + { + "tag": "AMR_PROFILE_STATUS_HOURLY_G", + "description": "AMR Profile Status Code M-Bus", + "class-id": 1, + "version": 0, + "obis": "0.x.96.10.3.255", + "group": "GAS", + "meterTypes": ["SP","PP"], + "properties": {}, + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "unsigned", + "valuetype": "DYNAMIC", + "access": "R" + } + ] + }, + { + "tag": "AMR_PROFILE_STATUS", + "description": "AMR Profile Status Code E meter", + "class-id": 1, + "version": 0, + "obis": "0.0.96.10.2.255", + "group": "ABSTRACT", + "meterTypes": ["SP","PP"], + "properties": {}, + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "unsigned", + "valuetype": "DYNAMIC", + "access": "R" + } + ] + }, + { + "tag": "MBUS_MASTER_VALUE", + "description": "M-Bus volume hourly", + "note": null, + "class-id": 4, + "version": 0, + "obis": "0.x.24.2.1.255", + "group": "GAS", + "meterTypes": ["SP","PP"], + "properties": {}, + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "double-long-unsigned", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 3, + "description": "scaler_unit", + "datatype": "scal_unit_type", + "valuetype": "BASED_ON_MODEL", + "valuebasedonmodel": { + "type": "GAS_METER_TYPE", + "values": [ + { + "types": ["G4-G6"], + "value": "-3, M3" + }, + { + "types": ["G10-G25"], + "value": "-2, M3" + } + ] + }, + "access": "R" + }, + { + "id": 4, + "description": "status", + "datatype": "unsigned", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 5, + "description": "capture_time", + "datatype": "octet-string", + "valuetype": "DYNAMIC", + "access": "R" + } + ] + }, + { + "tag": "ACTIVITY_CALENDAR", + "description": "Activity calendar", + "note": null, + "class-id": 20, + "version": 0, + "obis": "0.0.13.0.0.255", + "group": "ABSTRACT", + "meterTypes": ["SP","PP"], + "attributes": [ + { + "id": 2, + "description": "calendar_name_active", + "datatype": "octet-string", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 3, + "description": "season_profile_active", + "datatype": "array", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 4, + "description": "week_profile_table_active", + "datatype": "array", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 5, + "description": "day_profile_table_active", + "datatype": "array", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 6, + "description": "calendar_name_passive", + "datatype": "octet-string", + "valuetype": "SET_BY_CLIENT", + "access": "RW" + }, + { + "id": 7, + "description": "season_profile_passive", + "datatype": "array", + "valuetype": "SET_BY_CLIENT", + "access": "RW" + }, + { + "id": 8, + "description": "week_profile_table_passive", + "datatype": "array", + "valuetype": "SET_BY_CLIENT", + "access": "RW" + }, + { + "id": 9, + "description": "day_profile_table_passive", + "datatype": "array", + "valuetype": "SET_BY_CLIENT", + "access": "RW" + }, + { + "id": 10, + "description": "activate_passive_calendar_time", + "datatype": "octet-string", + "valuetype": "SET_BY_CLIENT", + "access": "RW" + } + ] + }, + { + "tag": "CONFIGURATION_OBJECT", + "description": "Configuration object", + "note": null, + "class-id": 1, + "version": 0, + "obis": "0.1.94.31.3.255", + "group": "ELECTRICITY", + "meterTypes": ["SP","PP"], + "properties": {}, + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "structure", + "valuetype": "SET_BY_CLIENT", + "access": "RW" + } + ] + }, + { + "tag": "RANDOMISATION_SETTINGS", + "description": "PHY Randomisation Object", + "note": "This object configuration is supported by DSMR4 devices but not presented in de DSMR4 specification. This object configuration is added according to the SMR 5.0.0 specification", + "class-id": 1, + "version": 0, + "obis": "0.1.94.31.12.255", + "group": "ELECTRICITY", + "meterTypes": ["SP","PP"], + "properties": {}, + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "structure", + "valuetype": "SET_BY_CLIENT", + "access": "RW" } ] } diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr43.json b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr43.json index f13fe7e88a7..2dcccd16780 100644 --- a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr43.json +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr43.json @@ -7,114 +7,124 @@ "version": "4.2.2" }, "properties": [], - "objects": [{ - "tag": "DEFINABLE_LOAD_PROFILE", - "description": "Definable load profile", - "class-id": 7, - "version": 1, - "obis": "0.1.94.31.6.255", - "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "SELECTABLE_OBJECTS": [ - "CLOCK", - "CDMA_DIAGNOSTIC", - "NUMBER_OF_VOLTAGE_SWELLS_FOR_L1", - "NUMBER_OF_VOLTAGE_SAGS_FOR_L1", - "NUMBER_OF_POWER_FAILURES", - "INSTANTANEOUS_VOLTAGE_L1", - "INSTANTANEOUS_VOLTAGE_L2", - "INSTANTANEOUS_VOLTAGE_L3", - "AVERAGE_VOLTAGE_L1", - "AVERAGE_VOLTAGE_L2", - "AVERAGE_VOLTAGE_L3", - "INSTANTANEOUS_CURRENT_L1", - "AVERAGE_CURRENT_L1", - "INSTANTANEOUS_ACTIVE_CURRENT_TOTAL_OVER_ALL_PHASES", - "AVERAGE_ACTIVE_POWER_IMPORT_L1", - "AVERAGE_ACTIVE_POWER_IMPORT_L2", - "AVERAGE_ACTIVE_POWER_IMPORT_L3", - "AVERAGE_ACTIVE_POWER_EXPORT_L1", - "AVERAGE_ACTIVE_POWER_EXPORT_L2", - "AVERAGE_ACTIVE_POWER_EXPORT_L3", - "AVERAGE_REACTIVE_POWER_IMPORT_L1", - "AVERAGE_REACTIVE_POWER_IMPORT_L2", - "AVERAGE_REACTIVE_POWER_IMPORT_L3", - "AVERAGE_REACTIVE_POWER_EXPORT_L1", - "AVERAGE_REACTIVE_POWER_EXPORT_L2", - "AVERAGE_REACTIVE_POWER_EXPORT_L3" + "objects": [ + { + "tag": "DEFINABLE_LOAD_PROFILE", + "description": "Definable load profile", + "note": "Attribute 4 (capture period in sec) is overridden in factory with value 900 (default in spec: 86400)", + "class-id": 7, + "version": 1, + "obis": "0.1.94.31.6.255", + "group": "ELECTRICITY", + "meterTypes": [ + "SP", + "PP" + ], + "properties": { + "SELECTABLE_OBJECTS": [ + "CLOCK", + "CDMA_DIAGNOSTIC", + "NUMBER_OF_VOLTAGE_SWELLS_FOR_L1", + "NUMBER_OF_VOLTAGE_SAGS_FOR_L1", + "NUMBER_OF_POWER_FAILURES", + "INSTANTANEOUS_VOLTAGE_L1", + "INSTANTANEOUS_VOLTAGE_L2", + "INSTANTANEOUS_VOLTAGE_L3", + "AVERAGE_VOLTAGE_L1", + "AVERAGE_VOLTAGE_L2", + "AVERAGE_VOLTAGE_L3", + "INSTANTANEOUS_CURRENT_L1", + "AVERAGE_CURRENT_L1", + "INSTANTANEOUS_ACTIVE_CURRENT_TOTAL_OVER_ALL_PHASES", + "AVERAGE_ACTIVE_POWER_IMPORT_L1", + "AVERAGE_ACTIVE_POWER_IMPORT_L2", + "AVERAGE_ACTIVE_POWER_IMPORT_L3", + "AVERAGE_ACTIVE_POWER_EXPORT_L1", + "AVERAGE_ACTIVE_POWER_EXPORT_L2", + "AVERAGE_ACTIVE_POWER_EXPORT_L3", + "AVERAGE_REACTIVE_POWER_IMPORT_L1", + "AVERAGE_REACTIVE_POWER_IMPORT_L2", + "AVERAGE_REACTIVE_POWER_IMPORT_L3", + "AVERAGE_REACTIVE_POWER_EXPORT_L1", + "AVERAGE_REACTIVE_POWER_EXPORT_L2", + "AVERAGE_REACTIVE_POWER_EXPORT_L3" + ] + }, + "attributes": [ + { + "id": 2, + "description": "buffer", + "datatype": "array", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 3, + "description": "capture objects", + "datatype": "array", + "valuetype": "SET_BY_CLIENT", + "access": "RW" + }, + { + "id": 4, + "description": "capture period in sec", + "note": "Attribute 4 (capture period in sec) is overridden in factory with value 900 (default in spec: 86400)", + "datatype": "double-long-unsigned", + "valuetype": "SET_BY_CLIENT", + "value": "900", + "access": "RW" + }, + { + "id": 5, + "description": "sort method", + "datatype": "enum", + "valuetype": "FIXED_IN_METER", + "value": "1", + "access": "R" + }, + { + "id": 6, + "description": "sort object", + "datatype": "object_definition", + "valuetype": "FIXED_IN_METER", + "value": "NONE", + "access": "R" + }, + { + "id": 7, + "description": "entries in use", + "datatype": "double-long-unsigned", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 8, + "description": "profile entries", + "datatype": "double-long-unsigned", + "valuetype": "SET_BY_CLIENT", + "value": "960", + "access": "RW" + } ] }, - "attributes": [ - { - "id": 2, - "description": "buffer", - "datatype": "array", - "valuetype": "DYNAMIC", - "value": "EMPTY", - "access": "R" - }, - { - "id": 3, - "description": "capture objects", - "datatype": "array", - "valuetype": "SET_BY_CLIENT", - "value": "EMPTY", - "access": "RW" - }, - { - "id": 4, - "description": "capture period in sec", - "datatype": "double-long-unsigned", - "valuetype": "SET_BY_CLIENT", - "value": "86400", - "access": "RW" - }, - { - "id": 5, - "description": "sort method", - "datatype": "enum", - "valuetype": "FIXED_IN_METER", - "value": "1", - "access": "R" - }, - { - "id": 6, - "description": "sort object", - "datatype": "object_definition", - "valuetype": "FIXED_IN_METER", - "value": "NONE", - "access": "R" - }, - { - "id": 7, - "description": "entries in use", - "datatype": "double-long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 8, - "description": "profile entries", - "datatype": "double-long-unsigned", - "valuetype": "SET_BY_CLIENT", - "value": "960", - "access": "RW" - } - ] - }, { "tag": "CDMA_DIAGNOSTIC", "description": "CDMA Diagnostic", + "note": null, "class-id": 47, "version": 0, "obis": "0.1.25.6.0.255", "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], + "meterTypes": [ + "SP", + "PP" + ], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "PERIODIC" + "PQ_REQUEST": [ + "PERIODIC_SP", + "PERIODIC_PP" + ] }, "attributes": [ { @@ -122,7 +132,6 @@ "description": "operator", "datatype": "visible-string", "valuetype": "DYNAMIC", - "value": "EMPTY", "access": "R" }, { @@ -130,7 +139,6 @@ "description": "status", "datatype": "enum", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -138,7 +146,6 @@ "description": "cs attachment", "datatype": "enum", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -154,7 +161,6 @@ "description": "cell info", "datatype": "cell_info_type", "valuetype": "DYNAMIC", - "value": "EMPTY", "access": "R" }, { @@ -162,7 +168,6 @@ "description": "adjacent cells", "datatype": "array", "valuetype": "DYNAMIC", - "value": "EMPTY", "access": "R" }, { @@ -170,7 +175,6 @@ "description": "capture time", "datatype": "date-time", "valuetype": "DYNAMIC", - "value": "EMPTY", "access": "R" } ] diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr50.json b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr50.json deleted file mode 100644 index 9fe7708e0ad..00000000000 --- a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr50.json +++ /dev/null @@ -1,1805 +0,0 @@ -{ - "profile": "SMR", - "version": "5.0", - "description": "Profile for Smart Meter Requirements 5.0", - "properties": [], - "objects": [ - { - "tag": "CLOCK", - "description": "Clock", - "class-id": 8, - "version": 0, - "obis": "0.0.1.0.0.255", - "group": "ABSTRACT", - "meterTypes": ["SP","PP"], - "attributes": [ - { - "id": 2, - "description": "time", - "datatype": "octet-string", - "valuetype": "DYNAMIC", - "value": "CURRENT_LOCAL_DATE_AND_TIME", - "access": "RW" - }, - { - "id": 3, - "description": "time_zone", - "datatype": "long", - "valuetype": "FIXED_IN_PROFILE", - "value": "-60", - "access": "RW" - }, - { - "id": 4, - "description": "status", - "datatype": "clock_status", - "valuetype": "DYNAMIC", - "value": "OK", - "access": "R" - } - ] - }, - { - "tag": "DEFINABLE_LOAD_PROFILE", - "description": "Definable load profile", - "class-id": 7, - "version": 1, - "obis": "0.1.94.31.6.255", - "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "SELECTABLE_OBJECTS": [ - "CLOCK", - "NUMBER_OF_VOLTAGE_SAGS_FOR_L1", - "NUMBER_OF_VOLTAGE_SAGS_FOR_L2", - "NUMBER_OF_VOLTAGE_SAGS_FOR_L3", - "NUMBER_OF_VOLTAGE_SWELLS_FOR_L1", - "NUMBER_OF_VOLTAGE_SWELLS_FOR_L2", - "NUMBER_OF_VOLTAGE_SWELLS_FOR_L3", - "NUMBER_OF_POWER_FAILURES", - "CDMA_DIAGNOSTIC", - "GPRS_DIAGNOSTIC", - "MBUS_CLIENT_SETUP", - "MBUS_DIAGNOSTIC" - ] - }, - "attributes": [ - { - "id": 2, - "description": "buffer", - "datatype": "array", - "valuetype": "DYNAMIC", - "value": "EMPTY", - "access": "R" - }, - { - "id": 3, - "description": "capture objects", - "datatype": "array", - "valuetype": "SET_BY_CLIENT", - "value": "EMPTY", - "access": "RW" - }, - { - "id": 4, - "description": "capture period in sec", - "datatype": "double-long-unsigned", - "valuetype": "SET_BY_CLIENT", - "value": "86400", - "access": "RW" - }, - { - "id": 5, - "description": "sort method", - "datatype": "enum", - "valuetype": "FIXED_IN_METER", - "value": "1", - "access": "R" - }, - { - "id": 6, - "description": "sort object", - "datatype": "object_definition", - "valuetype": "FIXED_IN_METER", - "value": "NONE", - "access": "R" - }, - { - "id": 7, - "description": "entries in use", - "datatype": "double-long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 8, - "description": "profile entries", - "datatype": "double-long-unsigned", - "valuetype": "SET_BY_CLIENT", - "value": "960", - "access": "RW" - } - ] - }, - { - "tag": "POWER_QUALITY_PROFILE_1", - "description": "Power Quality profile 1, 15 min power quality values", - "class-id": 7, - "version": 1, - "obis": "0.1.99.1.1.255", - "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "SELECTABLE_OBJECTS": [ - "CLOCK", - "AVERAGE_ACTIVE_POWER_IMPORT_L1", - "AVERAGE_ACTIVE_POWER_IMPORT_L2", - "AVERAGE_ACTIVE_POWER_IMPORT_L3", - "AVERAGE_ACTIVE_POWER_EXPORT_L1", - "AVERAGE_ACTIVE_POWER_EXPORT_L2", - "AVERAGE_ACTIVE_POWER_EXPORT_L3", - "AVERAGE_REACTIVE_POWER_IMPORT_L1", - "AVERAGE_REACTIVE_POWER_IMPORT_L2", - "AVERAGE_REACTIVE_POWER_IMPORT_L3", - "AVERAGE_REACTIVE_POWER_EXPORT_L1", - "AVERAGE_REACTIVE_POWER_EXPORT_L2", - "AVERAGE_REACTIVE_POWER_EXPORT_L3" - ] - }, - "attributes": [ - { - "id": 2, - "description": "buffer", - "datatype": "array", - "valuetype": "DYNAMIC", - "value": "EMPTY", - "access": "R" - }, - { - "id": 3, - "description": "capture objects", - "datatype": "array", - "valuetype": "SET_BY_CLIENT", - "value": "EMPTY", - "access": "RW" - }, - { - "id": 4, - "description": "capture period in sec", - "datatype": "double-long-unsigned", - "valuetype": "FIXED_IN_PROFILE", - "value": "900", - "access": "R" - }, - { - "id": 5, - "description": "sort method", - "datatype": "enum", - "valuetype": "FIXED_IN_PROFILE", - "value": "1", - "access": "R" - }, - { - "id": 6, - "description": "sort object", - "datatype": "object_definition", - "valuetype": "FIXED_IN_METER", - "value": "NONE", - "access": "R" - }, - { - "id": 7, - "description": "entries in use", - "datatype": "double-long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 8, - "description": "profile entries", - "datatype": "double-long-unsigned", - "valuetype": "FIXED_IN_PROFILE", - "value": "960", - "access": "R" - } - ] - }, - { - "tag": "POWER_QUALITY_PROFILE_2", - "description": "Power Quality profile 2, 10 min power quality values", - "class-id": 7, - "version": 1, - "obis": "0.1.99.1.2.255", - "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "SELECTABLE_OBJECTS": [ - "CLOCK", - "AVERAGE_VOLTAGE_L1", - "AVERAGE_VOLTAGE_L2", - "AVERAGE_VOLTAGE_L3", - "AVERAGE_CURRENT_L1", - "AVERAGE_CURRENT_L2", - "AVERAGE_CURRENT_L3", - "INSTANTANEOUS_CURRENT_L1" - ] - }, - "attributes": [ - { - "id": 2, - "description": "buffer", - "datatype": "array", - "valuetype": "DYNAMIC", - "value": "EMPTY", - "access": "R" - }, - { - "id": 3, - "description": "capture objects", - "datatype": "array", - "valuetype": "SET_BY_CLIENT", - "value": "EMPTY", - "access": "RW" - }, - { - "id": 4, - "description": "capture period in sec", - "datatype": "double-long-unsigned", - "valuetype": "FIXED_IN_PROFILE", - "value": "600", - "access": "R" - }, - { - "id": 5, - "description": "sort method", - "datatype": "enum", - "valuetype": "FIXED_IN_PROFILE", - "value": "1", - "access": "R" - }, - { - "id": 6, - "description": "sort object", - "datatype": "object_definition", - "valuetype": "FIXED_IN_METER", - "value": "NONE", - "access": "R" - }, - { - "id": 7, - "description": "entries in use", - "datatype": "double-long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 8, - "description": "profile entries", - "datatype": "double-long-unsigned", - "valuetype": "FIXED_IN_PROFILE", - "value": "1440", - "access": "R" - } - ] - }, - { - "tag": "INSTANTANEOUS_ACTIVE_POWER_IMPORT", - "description": "Instantaneous active power (+P)", - "class-id": 3, - "version": 0, - "obis": "1.0.1.7.0.255", - "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, W", - "access": "R" - } - ] - }, - { - "tag": "INSTANTANEOUS_ACTIVE_POWER_EXPORT", - "description": "Instantaneous active power (-P)", - "class-id": 3, - "version": 0, - "obis": "1.0.2.7.0.255", - "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, W", - "access": "R" - } - ] - }, - { - "tag": "INSTANTANEOUS_ACTIVE_POWER_IMPORT_L1", - "description": "Instantaneous active power L1 (+P)", - "class-id": 3, - "version": 0, - "obis": "1.0.21.7.0.255", - "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, W", - "access": "R" - } - ] - }, - { - "tag": "INSTANTANEOUS_ACTIVE_POWER_IMPORT_L2", - "description": "Instantaneous active power L2 (+P)", - "class-id": 3, - "version": 0, - "obis": "1.0.41.7.0.255", - "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, W", - "access": "R" - } - ] - }, - { - "tag": "INSTANTANEOUS_ACTIVE_POWER_IMPORT_L3", - "description": "Instantaneous active power L3 (+P)", - "class-id": 3, - "version": 0, - "obis": "1.0.61.7.0.255", - "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, W", - "access": "R" - } - ] - }, - { - "tag": "INSTANTANEOUS_ACTIVE_POWER_EXPORT_L1", - "description": "Instantaneous active power L1 (-P)", - "class-id": 3, - "version": 0, - "obis": "1.0.22.7.0.255", - "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, W", - "access": "R" - } - ] - }, - { - "tag": "INSTANTANEOUS_ACTIVE_POWER_EXPORT_L2", - "description": "Instantaneous active power L2 (-P)", - "class-id": 3, - "version": 0, - "obis": "1.0.42.7.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, W", - "access": "R" - } - ] - }, - { - "tag": "INSTANTANEOUS_ACTIVE_POWER_EXPORT_L3", - "description": "Instantaneous active power L3 (-P)", - "class-id": 3, - "version": 0, - "obis": "1.0.62.7.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, W", - "access": "R" - } - ] - }, - { - "tag": "INSTANTANEOUS_CURRENT_L1", - "description": "Instantaneous current L1", - "class-id": 3, - "version": 0, - "obis": "1.0.31.7.0.255", - "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "-2, A", - "access": "R" - } - ] - }, - { - "tag": "INSTANTANEOUS_CURRENT_L2", - "description": "Instantaneous current L2", - "class-id": 3, - "version": 0, - "obis": "1.0.51.7.0.255", - "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "-2, A", - "access": "R" - } - ] - }, - { - "tag": "INSTANTANEOUS_CURRENT_L3", - "description": "Instantaneous current L3", - "class-id": 3, - "version": 0, - "obis": "1.0.71.7.0.255", - "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "-2, A", - "access": "R" - } - ] - }, - { - "tag": "INSTANTANEOUS_VOLTAGE_L1", - "description": "Instantaneous voltage L1", - "class-id": 3, - "version": 0, - "obis": "1.0.32.7.0.255", - "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "-1, V", - "access": "R" - } - ] - }, - { - "tag": "INSTANTANEOUS_VOLTAGE_L2", - "description": "Instantaneous voltage L2", - "class-id": 3, - "version": 0, - "obis": "1.0.52.7.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "-1, V", - "access": "R" - } - ] - }, - { - "tag": "INSTANTANEOUS_VOLTAGE_L3", - "description": "Instantaneous voltage L3", - "class-id": 3, - "version": 0, - "obis": "1.0.72.7.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "-1, V", - "access": "R" - } - ] - }, - { - "tag": "AVERAGE_ACTIVE_POWER_EXPORT_L1", - "description": "Average active power (-P) L1", - "class-id": 3, - "version": 0, - "obis": "1.0.22.4.0.255", - "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, W", - "access": "R" - } - ] - }, - { - "tag": "AVERAGE_ACTIVE_POWER_EXPORT_L2", - "description": "Average active power (-P) L2", - "class-id": 3, - "version": 0, - "obis": "1.0.42.4.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, W", - "access": "R" - } - ] - }, - { - "tag": "AVERAGE_ACTIVE_POWER_EXPORT_L3", - "description": "Average active power (-P) L3", - "class-id": 3, - "version": 0, - "obis": "1.0.62.4.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, W", - "access": "R" - } - ] - }, - { - "tag": "AVERAGE_ACTIVE_POWER_IMPORT_L1", - "description": "Average active power (+P) L1", - "class-id": 3, - "version": 0, - "obis": "1.0.21.4.0.255", - "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, W", - "access": "R" - } - ] - }, - { - "tag": "AVERAGE_ACTIVE_POWER_IMPORT_L2", - "description": "Average active power (+P) L2", - "class-id": 3, - "version": 0, - "obis": "1.0.41.4.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, W", - "access": "R" - } - ] - }, - { - "tag": "AVERAGE_ACTIVE_POWER_IMPORT_L3", - "description": "Average active power (+P) L3", - "class-id": 3, - "version": 0, - "obis": "1.0.61.4.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, W", - "access": "R" - } - ] - }, - { - "tag": "AVERAGE_REACTIVE_POWER_IMPORT_L1", - "description": "Average reactive power (+Q) L1", - "class-id": 3, - "version": 0, - "obis": "1.0.23.4.0.255", - "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, var", - "access": "R" - } - ] - }, - { - "tag": "AVERAGE_REACTIVE_POWER_IMPORT_L2", - "description": "Average reactive power (+Q) L2", - "class-id": 3, - "version": 0, - "obis": "1.0.43.4.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, var", - "access": "R" - } - ] - }, - { - "tag": "AVERAGE_REACTIVE_POWER_IMPORT_L3", - "description": "Average reactive power (+Q) L3", - "class-id": 3, - "version": 0, - "obis": "1.0.63.4.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, var", - "access": "R" - } - ] - }, - { - "tag": "AVERAGE_REACTIVE_POWER_EXPORT_L1", - "description": "Average reactive power (-Q) L1", - "class-id": 3, - "version": 0, - "obis": "1.0.24.4.0.255", - "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, var", - "access": "R" - } - ] - }, - { - "tag": "AVERAGE_REACTIVE_POWER_EXPORT_L2", - "description": "Average reactive power (-Q) L2", - "class-id": 3, - "version": 0, - "obis": "1.0.44.4.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, var", - "access": "R" - } - ] - }, - { - "tag": "AVERAGE_REACTIVE_POWER_EXPORT_L3", - "description": "Average reactive power (-Q) L3", - "class-id": 3, - "version": 0, - "obis": "1.0.64.4.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, var", - "access": "R" - } - ] - }, - { - "tag": "AVERAGE_CURRENT_L1", - "description": "Average current L1", - "class-id": 3, - "version": 0, - "obis": "1.0.31.24.0.255", - "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "-2, A", - "access": "R" - } - ] - }, - { - "tag": "AVERAGE_CURRENT_L2", - "description": "Average current L2", - "class-id": 3, - "version": 0, - "obis": "1.0.51.24.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "-2, A", - "access": "R" - } - ] - }, - { - "tag": "AVERAGE_CURRENT_L3", - "description": "Average current L3", - "class-id": 3, - "version": 0, - "obis": "1.0.71.24.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "-2, A", - "access": "R" - } - ] - }, - { - "tag": "AVERAGE_VOLTAGE_L1", - "description": "Average voltage L1", - "class-id": 3, - "version": 0, - "obis": "1.0.32.24.0.255", - "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "-1, V", - "access": "R" - } - ] - }, - { - "tag": "AVERAGE_VOLTAGE_L2", - "description": "Average voltage L2", - "class-id": 3, - "version": 0, - "obis": "1.0.52.24.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "-1, V", - "access": "R" - } - ] - }, - { - "tag": "AVERAGE_VOLTAGE_L3", - "description": "Average voltage L3", - "class-id": 3, - "version": 0, - "obis": "1.0.72.24.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "-1, V", - "access": "R" - } - ] - }, - { - "tag": "NUMBER_OF_POWER_FAILURES", - "description": "Number of power failures in any phases", - "class-id": 1, - "version": 0, - "obis": "0.0.96.7.21.255", - "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - } - ] - }, - { - "tag": "NUMBER_OF_LONG_POWER_FAILURES", - "description": "Number of long power failures in any phases", - "class-id": 1, - "version": 0, - "obis": "0.0.96.7.9.255", - "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - } - ] - }, - { - "tag": "NUMBER_OF_VOLTAGE_SAGS_FOR_L1", - "description": "Number of voltage sags in phase L1", - "class-id": 1, - "version": 0, - "obis": "1.0.32.32.0.255", - "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - } - ] - }, - { - "tag": "NUMBER_OF_VOLTAGE_SAGS_FOR_L2", - "description": "Number of voltage sags in phase L2", - "class-id": 1, - "version": 0, - "obis": "1.0.52.32.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - } - ] - }, - { - "tag": "NUMBER_OF_VOLTAGE_SAGS_FOR_L3", - "description": "Number of voltage sags in phase L3", - "class-id": 1, - "version": 0, - "obis": "1.0.72.32.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - } - ] - }, - { - "tag": "NUMBER_OF_VOLTAGE_SWELLS_FOR_L1", - "description": "Number of voltage swells in phase L1", - "class-id": 1, - "version": 0, - "obis": "1.0.32.36.0.255", - "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - } - ] - }, - { - "tag": "NUMBER_OF_VOLTAGE_SWELLS_FOR_L2", - "description": "Number of voltage swells in phase L2", - "class-id": 1, - "version": 0, - "obis": "1.0.52.36.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - } - ] - }, - { - "tag": "NUMBER_OF_VOLTAGE_SWELLS_FOR_L3", - "description": "Number of voltage swells in phase L3", - "class-id": 1, - "version": 0, - "obis": "1.0.72.36.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" - }, - "attributes": [ - { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - } - ] - }, - { - "tag": "CDMA_DIAGNOSTIC", - "description": "CDMA Diagnostic", - "class-id": 47, - "version": 0, - "obis": "0.1.25.6.0.255", - "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "PERIODIC" - }, - "attributes": [ - { - "id": 2, - "description": "operator", - "datatype": "visible-string", - "valuetype": "DYNAMIC", - "value": "EMPTY", - "access": "R" - }, - { - "id": 3, - "description": "status", - "datatype": "enum", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 4, - "description": "cs attachment", - "datatype": "enum", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 5, - "description": "ps status", - "datatype": "enum", - "valuetype": "DYNAMIC", - "value": "255", - "access": "R" - }, - { - "id": 6, - "description": "cell info", - "datatype": "cell_info_type", - "valuetype": "DYNAMIC", - "value": "EMPTY", - "access": "R" - }, - { - "id": 7, - "description": "adjacent cells", - "datatype": "array", - "valuetype": "DYNAMIC", - "value": "EMPTY", - "access": "R" - }, - { - "id": 8, - "description": "capture time", - "datatype": "date-time", - "valuetype": "DYNAMIC", - "value": "EMPTY", - "access": "R" - } - ] - }, - { - "tag": "GPRS_DIAGNOSTIC", - "description": "GPRS Diagnostic", - "class-id": 47, - "version": 0, - "obis": "0.0.25.6.0.255", - "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "PERIODIC" - }, - "attributes": [ - { - "id": 2, - "description": "operator", - "datatype": "visible-string", - "valuetype": "DYNAMIC", - "value": "EMPTY", - "access": "R" - }, - { - "id": 3, - "description": "status", - "datatype": "enum", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 4, - "description": "cs attachment", - "datatype": "enum", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 5, - "description": "ps status", - "datatype": "enum", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 6, - "description": "cell info", - "datatype": "cell_info_type", - "valuetype": "DYNAMIC", - "value": "EMPTY", - "access": "R" - }, - { - "id": 7, - "description": "adjacent cells", - "datatype": "array", - "valuetype": "DYNAMIC", - "value": "EMPTY", - "access": "R" - }, - { - "id": 8, - "description": "capture time", - "datatype": "date-time", - "valuetype": "DYNAMIC", - "value": "EMPTY", - "access": "R" - } - ] - }, - { - "tag": "MBUS_CLIENT_SETUP", - "description": "M-Bus client setup", - "class-id": 72, - "version": 1, - "obis": "0.x.24.1.0.255", - "group": "GAS", - "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "PERIODIC" - }, - "attributes": [ - { - "id": 2, - "description": "mbus port reference", - "datatype": "octet-string", - "valuetype": "FIXED_IN_PROFILE", - "value": "0.0.24.6.0.255", - "access": "R" - }, - { - "id": 3, - "description": "capture definition", - "datatype": "array", - "valuetype": "DYNAMIC", - "value": "EMPTY", - "access": "R" - }, - { - "id": 4, - "description": "capture period", - "datatype": "double-long-unsigned", - "valuetype": "FIXED_IN_PROFILE", - "value": "0", - "access": "RW" - }, - { - "id": 5, - "description": "primary address", - "datatype": "unsigned", - "valuetype": "FIXED_IN_PROFILE", - "value": "0", - "access": "RW" - }, - { - "id": 6, - "description": "identification number", - "datatype": "double-long-unsigned", - "valuetype": "FIXED_IN_METER", - "value": "IDENTIFICATION_NUMBER", - "access": "RW" - }, - { - "id": 7, - "description": "manufacturer id", - "datatype": "long-unsigned", - "valuetype": "FIXED_IN_METER", - "value": "MANUFACTURER_ID", - "access": "RW" - }, - { - "id": 8, - "description": "version", - "datatype": "unsigned", - "valuetype": "FIXED_IN_PROFILE", - "value": "50", - "access": "RW" - }, - { - "id": 9, - "description": "device type", - "datatype": "unsigned", - "valuetype": "FIXED_IN_METER", - "value": "3", - "access": "RW" - }, - { - "id": 10, - "description": "access number", - "datatype": "unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 11, - "description": "status", - "datatype": "unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 12, - "description": "alarm", - "datatype": "unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 13, - "description": "configuration", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0x0063", - "access": "R" - }, - { - "id": 14, - "description": "encryption key status", - "datatype": "enum", - "valuetype": "DYNAMIC", - "value": "1", - "access": "R" - } - ] - }, - { - "tag": "MBUS_DIAGNOSTIC", - "description": "M-Bus diagnostic", - "class-id": 77, - "version": 0, - "obis": "0.x.24.9.0.255", - "group": "GAS", - "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "PERIODIC" - }, - "attributes": [ - { - "id": 2, - "description": "received signal strength", - "datatype": "unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 3, - "description": "channel id", - "datatype": "unsigned", - "valuetype": "FIXED_IN_PROFILE", - "value": "0", - "access": "R" - }, - { - "id": 4, - "description": "link status", - "datatype": "enum", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 5, - "description": "broadcast frames counter", - "datatype": "array", - "valuetype": "FIXED_IN_PROFILE", - "value": "0", - "access": "R" - }, - { - "id": 6, - "description": "transmissions counter", - "datatype": "double-long-unsigned", - "valuetype": "FIXED_IN_PROFILE", - "value": "0", - "access": "R" - }, - { - "id": 7, - "description": "fcs ok frames counter", - "datatype": "double-long-unsigned", - "valuetype": "FIXED_IN_PROFILE", - "value": "0", - "access": "R" - }, - { - "id": 8, - "description": "fcs nok frames counter", - "datatype": "double-long-unsigned", - "valuetype": "FIXED_IN_PROFILE", - "value": "0", - "access": "R" - }, - { - "id": 9, - "description": "capture time", - "datatype": "structure", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - } - ] - } - ] -} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr50.json b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr500.json similarity index 71% rename from osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr50.json rename to osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr500.json index 26d4a55884a..7a8a6b3fc0b 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr50.json +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr500.json @@ -7,6 +7,7 @@ { "tag": "CLOCK", "description": "Clock", + "note": null, "class-id": 8, "version": 0, "obis": "0.0.1.0.0.255", @@ -42,6 +43,7 @@ { "tag": "DEFINABLE_LOAD_PROFILE", "description": "Definable load profile", + "note": "Attribute 4 (capture period in sec) is overridden in factory with value 900 (default in spec: 86400)", "class-id": 7, "version": 1, "obis": "0.1.94.31.6.255", @@ -57,6 +59,7 @@ "NUMBER_OF_VOLTAGE_SWELLS_FOR_L2", "NUMBER_OF_VOLTAGE_SWELLS_FOR_L3", "NUMBER_OF_POWER_FAILURES", + "INSTANTANEOUS_ACTIVE_CURRENT_TOTAL_OVER_ALL_PHASES", "CDMA_DIAGNOSTIC", "GPRS_DIAGNOSTIC", "MBUS_CLIENT_SETUP", @@ -69,7 +72,6 @@ "description": "buffer", "datatype": "array", "valuetype": "DYNAMIC", - "value": "EMPTY", "access": "R" }, { @@ -77,12 +79,12 @@ "description": "capture objects", "datatype": "array", "valuetype": "SET_BY_CLIENT", - "value": "EMPTY", "access": "RW" }, { "id": 4, "description": "capture period in sec", + "note": "Attribute 4 (capture period in sec) is overridden in factory with value 900 (default in spec: 86400)", "datatype": "double-long-unsigned", "valuetype": "SET_BY_CLIENT", "value": "900", @@ -109,7 +111,6 @@ "description": "entries in use", "datatype": "double-long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -125,6 +126,7 @@ { "tag": "POWER_QUALITY_PROFILE_1", "description": "Power Quality profile 1, 15 min power quality values", + "note": null, "class-id": 7, "version": 1, "obis": "1.0.99.1.1.255", @@ -153,7 +155,6 @@ "description": "buffer", "datatype": "array", "valuetype": "DYNAMIC", - "value": "EMPTY", "access": "R" }, { @@ -161,7 +162,6 @@ "description": "capture objects", "datatype": "array", "valuetype": "SET_BY_CLIENT", - "value": "EMPTY", "access": "RW" }, { @@ -193,7 +193,6 @@ "description": "entries in use", "datatype": "double-long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -224,7 +223,15 @@ "AVERAGE_CURRENT_L2", "AVERAGE_CURRENT_L3", "INSTANTANEOUS_CURRENT_L1", - "INSTANTANEOUS_VOLTAGE_L1" + "INSTANTANEOUS_VOLTAGE_L1", + "INSTANTANEOUS_ACTIVE_POWER_IMPORT", + "INSTANTANEOUS_ACTIVE_POWER_EXPORT", + "INSTANTANEOUS_ACTIVE_POWER_IMPORT_L1", + "INSTANTANEOUS_ACTIVE_POWER_IMPORT_L2", + "INSTANTANEOUS_ACTIVE_POWER_IMPORT_L3", + "INSTANTANEOUS_ACTIVE_POWER_EXPORT_L1", + "INSTANTANEOUS_ACTIVE_POWER_EXPORT_L2", + "INSTANTANEOUS_ACTIVE_POWER_EXPORT_L3" ] }, "attributes": [ @@ -233,7 +240,6 @@ "description": "buffer", "datatype": "array", "valuetype": "DYNAMIC", - "value": "EMPTY", "access": "R" }, { @@ -241,7 +247,6 @@ "description": "capture objects", "datatype": "array", "valuetype": "SET_BY_CLIENT", - "value": "EMPTY", "access": "RW" }, { @@ -273,7 +278,6 @@ "description": "entries in use", "datatype": "double-long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -289,6 +293,7 @@ { "tag": "INSTANTANEOUS_ACTIVE_POWER_IMPORT", "description": "Instantaneous active power (+P)", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.1.7.0.255", @@ -296,7 +301,7 @@ "meterTypes": ["SP","PP"], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_SP","ACTUAL_PP"] }, "attributes": [ { @@ -304,7 +309,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -320,6 +324,7 @@ { "tag": "INSTANTANEOUS_ACTIVE_POWER_EXPORT", "description": "Instantaneous active power (-P)", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.2.7.0.255", @@ -327,7 +332,7 @@ "meterTypes": ["SP","PP"], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_SP","ACTUAL_PP"] }, "attributes": [ { @@ -335,7 +340,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -351,6 +355,7 @@ { "tag": "INSTANTANEOUS_ACTIVE_POWER_IMPORT_L1", "description": "Instantaneous active power L1 (+P)", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.21.7.0.255", @@ -358,7 +363,7 @@ "meterTypes": ["SP","PP"], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_SP","ACTUAL_PP"] }, "attributes": [ { @@ -366,7 +371,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -382,6 +386,7 @@ { "tag": "INSTANTANEOUS_ACTIVE_POWER_IMPORT_L2", "description": "Instantaneous active power L2 (+P)", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.41.7.0.255", @@ -389,7 +394,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_PP"] }, "attributes": [ { @@ -397,7 +402,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -413,6 +417,7 @@ { "tag": "INSTANTANEOUS_ACTIVE_POWER_IMPORT_L3", "description": "Instantaneous active power L3 (+P)", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.61.7.0.255", @@ -420,7 +425,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_PP"] }, "attributes": [ { @@ -428,7 +433,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -444,6 +448,7 @@ { "tag": "INSTANTANEOUS_ACTIVE_POWER_EXPORT_L1", "description": "Instantaneous active power L1 (-P)", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.22.7.0.255", @@ -451,7 +456,7 @@ "meterTypes": ["SP","PP"], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_SP","ACTUAL_PP"] }, "attributes": [ { @@ -459,7 +464,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -475,6 +479,7 @@ { "tag": "INSTANTANEOUS_ACTIVE_POWER_EXPORT_L2", "description": "Instantaneous active power L2 (-P)", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.42.7.0.255", @@ -482,7 +487,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_PP"] }, "attributes": [ { @@ -490,7 +495,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -506,6 +510,7 @@ { "tag": "INSTANTANEOUS_ACTIVE_POWER_EXPORT_L3", "description": "Instantaneous active power L3 (-P)", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.62.7.0.255", @@ -513,7 +518,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_PP"] }, "attributes": [ { @@ -521,7 +526,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -537,6 +541,7 @@ { "tag": "INSTANTANEOUS_ACTIVE_CURRENT_TOTAL_OVER_ALL_PHASES", "description": "Instantaneous current total", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.90.7.0.255", @@ -544,7 +549,7 @@ "meterTypes": ["SP","PP"], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_SP","ACTUAL_PP"] }, "attributes": [ { @@ -552,7 +557,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -568,6 +572,7 @@ { "tag": "INSTANTANEOUS_CURRENT_L1", "description": "Instantaneous current L1", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.31.7.0.255", @@ -575,7 +580,7 @@ "meterTypes": ["SP","PP"], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_SP","ACTUAL_PP","PERIODIC_SP"] }, "attributes": [ { @@ -583,7 +588,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -599,6 +603,7 @@ { "tag": "INSTANTANEOUS_CURRENT_L2", "description": "Instantaneous current L2", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.51.7.0.255", @@ -606,7 +611,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_PP"] }, "attributes": [ { @@ -614,7 +619,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -630,6 +634,7 @@ { "tag": "INSTANTANEOUS_CURRENT_L3", "description": "Instantaneous current L3", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.71.7.0.255", @@ -637,7 +642,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_PP"] }, "attributes": [ { @@ -645,7 +650,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -661,6 +665,7 @@ { "tag": "INSTANTANEOUS_VOLTAGE_L1", "description": "Instantaneous voltage L1", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.32.7.0.255", @@ -668,7 +673,7 @@ "meterTypes": ["SP","PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_SP","ACTUAL_PP","PERIODIC_SP"] }, "attributes": [ { @@ -676,7 +681,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -692,6 +696,7 @@ { "tag": "INSTANTANEOUS_VOLTAGE_L2", "description": "Instantaneous voltage L2", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.52.7.0.255", @@ -699,7 +704,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_PP"] }, "attributes": [ { @@ -707,7 +712,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -723,6 +727,7 @@ { "tag": "INSTANTANEOUS_VOLTAGE_L3", "description": "Instantaneous voltage L3", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.72.7.0.255", @@ -730,7 +735,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_PP"] }, "attributes": [ { @@ -738,7 +743,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -754,6 +758,7 @@ { "tag": "AVERAGE_ACTIVE_POWER_EXPORT_L1", "description": "Average active power (-P) L1", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.22.4.0.255", @@ -761,7 +766,7 @@ "meterTypes": ["SP","PP"], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_SP","ACTUAL_PP","PERIODIC_SP","PERIODIC_PP"] }, "attributes": [ { @@ -769,7 +774,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -785,6 +789,7 @@ { "tag": "AVERAGE_ACTIVE_POWER_EXPORT_L2", "description": "Average active power (-P) L2", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.42.4.0.255", @@ -792,7 +797,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_PP","PERIODIC_PP"] }, "attributes": [ { @@ -800,7 +805,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -816,6 +820,7 @@ { "tag": "AVERAGE_ACTIVE_POWER_EXPORT_L3", "description": "Average active power (-P) L3", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.62.4.0.255", @@ -823,7 +828,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_PP","PERIODIC_PP"] }, "attributes": [ { @@ -831,7 +836,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -847,6 +851,7 @@ { "tag": "AVERAGE_ACTIVE_POWER_IMPORT_L1", "description": "Average active power (+P) L1", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.21.4.0.255", @@ -854,7 +859,7 @@ "meterTypes": ["SP","PP"], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_SP","ACTUAL_PP","PERIODIC_SP","PERIODIC_PP"] }, "attributes": [ { @@ -862,7 +867,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -878,6 +882,7 @@ { "tag": "AVERAGE_ACTIVE_POWER_IMPORT_L2", "description": "Average active power (+P) L2", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.41.4.0.255", @@ -885,7 +890,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_PP","PERIODIC_PP"] }, "attributes": [ { @@ -893,7 +898,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -909,6 +913,7 @@ { "tag": "AVERAGE_ACTIVE_POWER_IMPORT_L3", "description": "Average active power (+P) L3", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.61.4.0.255", @@ -916,7 +921,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_PP","PERIODIC_PP"] }, "attributes": [ { @@ -924,7 +929,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -940,6 +944,7 @@ { "tag": "AVERAGE_REACTIVE_POWER_IMPORT_L1", "description": "Average reactive power (+Q) L1", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.23.4.0.255", @@ -947,7 +952,7 @@ "meterTypes": ["SP","PP"], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_SP","ACTUAL_PP","PERIODIC_SP","PERIODIC_PP"] }, "attributes": [ { @@ -955,7 +960,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -971,6 +975,7 @@ { "tag": "AVERAGE_REACTIVE_POWER_IMPORT_L2", "description": "Average reactive power (+Q) L2", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.43.4.0.255", @@ -978,7 +983,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_PP","PERIODIC_PP"] }, "attributes": [ { @@ -986,7 +991,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -1002,6 +1006,7 @@ { "tag": "AVERAGE_REACTIVE_POWER_IMPORT_L3", "description": "Average reactive power (+Q) L3", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.63.4.0.255", @@ -1009,7 +1014,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_PP","PERIODIC_PP"] }, "attributes": [ { @@ -1017,7 +1022,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -1033,6 +1037,7 @@ { "tag": "AVERAGE_REACTIVE_POWER_EXPORT_L1", "description": "Average reactive power (-Q) L1", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.24.4.0.255", @@ -1040,7 +1045,7 @@ "meterTypes": ["SP","PP"], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_SP","ACTUAL_PP","PERIODIC_SP","PERIODIC_PP"] }, "attributes": [ { @@ -1048,7 +1053,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -1064,6 +1068,7 @@ { "tag": "AVERAGE_REACTIVE_POWER_EXPORT_L2", "description": "Average reactive power (-Q) L2", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.44.4.0.255", @@ -1071,7 +1076,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_PP","PERIODIC_PP"] }, "attributes": [ { @@ -1079,7 +1084,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -1095,6 +1099,7 @@ { "tag": "AVERAGE_REACTIVE_POWER_EXPORT_L3", "description": "Average reactive power (-Q) L3", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.64.4.0.255", @@ -1102,7 +1107,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_PP","PERIODIC_PP"] }, "attributes": [ { @@ -1110,7 +1115,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -1126,6 +1130,7 @@ { "tag": "AVERAGE_CURRENT_L1", "description": "Average current L1", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.31.24.0.255", @@ -1133,7 +1138,7 @@ "meterTypes": ["SP","PP"], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_SP","ACTUAL_PP","PERIODIC_SP","PERIODIC_PP"] }, "attributes": [ { @@ -1141,7 +1146,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -1157,6 +1161,7 @@ { "tag": "AVERAGE_CURRENT_L2", "description": "Average current L2", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.51.24.0.255", @@ -1164,7 +1169,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_PP","PERIODIC_PP"] }, "attributes": [ { @@ -1172,7 +1177,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -1188,6 +1192,7 @@ { "tag": "AVERAGE_CURRENT_L3", "description": "Average current L3", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.71.24.0.255", @@ -1195,7 +1200,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_PP","PERIODIC_PP"] }, "attributes": [ { @@ -1203,7 +1208,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -1219,6 +1223,7 @@ { "tag": "AVERAGE_VOLTAGE_L1", "description": "Average voltage L1", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.32.24.0.255", @@ -1226,7 +1231,7 @@ "meterTypes": ["SP","PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_SP","ACTUAL_PP","PERIODIC_SP","PERIODIC_PP"] }, "attributes": [ { @@ -1234,7 +1239,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -1250,6 +1254,7 @@ { "tag": "AVERAGE_VOLTAGE_L2", "description": "Average voltage L2", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.52.24.0.255", @@ -1257,7 +1262,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_PP","PERIODIC_PP"] }, "attributes": [ { @@ -1265,7 +1270,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -1281,6 +1285,7 @@ { "tag": "AVERAGE_VOLTAGE_L3", "description": "Average voltage L3", + "note": null, "class-id": 3, "version": 0, "obis": "1.0.72.24.0.255", @@ -1288,7 +1293,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_PP","PERIODIC_PP"] }, "attributes": [ { @@ -1296,7 +1301,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -1312,6 +1316,7 @@ { "tag": "NUMBER_OF_POWER_FAILURES", "description": "Number of power failures in any phases", + "note": null, "class-id": 1, "version": 0, "obis": "0.0.96.7.21.255", @@ -1319,7 +1324,7 @@ "meterTypes": ["SP","PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_SP","ACTUAL_PP","PERIODIC_SP","PERIODIC_PP"] }, "attributes": [ { @@ -1327,7 +1332,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" } ] @@ -1335,6 +1339,7 @@ { "tag": "NUMBER_OF_LONG_POWER_FAILURES", "description": "Number of long power failures in any phases", + "note": null, "class-id": 1, "version": 0, "obis": "0.0.96.7.9.255", @@ -1342,7 +1347,7 @@ "meterTypes": ["SP","PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_SP","ACTUAL_PP"] }, "attributes": [ { @@ -1350,7 +1355,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" } ] @@ -1358,6 +1362,7 @@ { "tag": "NUMBER_OF_VOLTAGE_SAGS_FOR_L1", "description": "Number of voltage sags in phase L1", + "note": null, "class-id": 1, "version": 0, "obis": "1.0.32.32.0.255", @@ -1365,7 +1370,7 @@ "meterTypes": ["SP","PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_SP","ACTUAL_PP","PERIODIC_SP","PERIODIC_PP"] }, "attributes": [ { @@ -1373,7 +1378,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" } ] @@ -1381,6 +1385,7 @@ { "tag": "NUMBER_OF_VOLTAGE_SAGS_FOR_L2", "description": "Number of voltage sags in phase L2", + "note": null, "class-id": 1, "version": 0, "obis": "1.0.52.32.0.255", @@ -1388,7 +1393,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_PP","PERIODIC_PP"] }, "attributes": [ { @@ -1396,7 +1401,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" } ] @@ -1404,6 +1408,7 @@ { "tag": "NUMBER_OF_VOLTAGE_SAGS_FOR_L3", "description": "Number of voltage sags in phase L3", + "note": null, "class-id": 1, "version": 0, "obis": "1.0.72.32.0.255", @@ -1411,7 +1416,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_PP","PERIODIC_PP"] }, "attributes": [ { @@ -1419,7 +1424,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" } ] @@ -1427,6 +1431,7 @@ { "tag": "NUMBER_OF_VOLTAGE_SWELLS_FOR_L1", "description": "Number of voltage swells in phase L1", + "note": null, "class-id": 1, "version": 0, "obis": "1.0.32.36.0.255", @@ -1434,7 +1439,7 @@ "meterTypes": ["SP","PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_SP","ACTUAL_PP","PERIODIC_SP","PERIODIC_PP"] }, "attributes": [ { @@ -1442,7 +1447,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" } ] @@ -1450,6 +1454,7 @@ { "tag": "NUMBER_OF_VOLTAGE_SWELLS_FOR_L2", "description": "Number of voltage swells in phase L2", + "note": null, "class-id": 1, "version": 0, "obis": "1.0.52.36.0.255", @@ -1457,7 +1462,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_PP","PERIODIC_PP"] }, "attributes": [ { @@ -1465,7 +1470,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" } ] @@ -1473,6 +1477,7 @@ { "tag": "NUMBER_OF_VOLTAGE_SWELLS_FOR_L3", "description": "Number of voltage swells in phase L3", + "note": null, "class-id": 1, "version": 0, "obis": "1.0.72.36.0.255", @@ -1480,7 +1485,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "BOTH" + "PQ_REQUEST": ["ACTUAL_PP","PERIODIC_PP"] }, "attributes": [ { @@ -1488,7 +1493,6 @@ "description": "value", "datatype": "long-unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" } ] @@ -1496,6 +1500,7 @@ { "tag": "CDMA_DIAGNOSTIC", "description": "CDMA Diagnostic", + "note": null, "class-id": 47, "version": 0, "obis": "0.1.25.6.0.255", @@ -1503,7 +1508,7 @@ "meterTypes": ["SP","PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "PERIODIC" + "PQ_REQUEST": ["PERIODIC_SP","PERIODIC_PP"] }, "attributes": [ { @@ -1511,7 +1516,6 @@ "description": "operator", "datatype": "visible-string", "valuetype": "DYNAMIC", - "value": "EMPTY", "access": "R" }, { @@ -1519,7 +1523,6 @@ "description": "status", "datatype": "enum", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -1527,7 +1530,6 @@ "description": "cs attachment", "datatype": "enum", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -1543,7 +1545,6 @@ "description": "cell info", "datatype": "cell_info_type", "valuetype": "DYNAMIC", - "value": "EMPTY", "access": "R" }, { @@ -1551,7 +1552,6 @@ "description": "adjacent cells", "datatype": "array", "valuetype": "DYNAMIC", - "value": "EMPTY", "access": "R" }, { @@ -1559,7 +1559,6 @@ "description": "capture time", "datatype": "date-time", "valuetype": "DYNAMIC", - "value": "EMPTY", "access": "R" } ] @@ -1567,6 +1566,7 @@ { "tag": "GPRS_DIAGNOSTIC", "description": "GPRS Diagnostic", + "note": null, "class-id": 47, "version": 0, "obis": "0.0.25.6.0.255", @@ -1574,7 +1574,7 @@ "meterTypes": ["SP","PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "PERIODIC" + "PQ_REQUEST": ["PERIODIC_SP","PERIODIC_PP"] }, "attributes": [ { @@ -1582,7 +1582,6 @@ "description": "operator", "datatype": "visible-string", "valuetype": "DYNAMIC", - "value": "EMPTY", "access": "R" }, { @@ -1590,7 +1589,6 @@ "description": "status", "datatype": "enum", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -1598,7 +1596,6 @@ "description": "cs attachment", "datatype": "enum", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -1606,7 +1603,6 @@ "description": "ps status", "datatype": "enum", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -1614,7 +1610,6 @@ "description": "cell info", "datatype": "cell_info_type", "valuetype": "DYNAMIC", - "value": "EMPTY", "access": "R" }, { @@ -1622,7 +1617,6 @@ "description": "adjacent cells", "datatype": "array", "valuetype": "DYNAMIC", - "value": "EMPTY", "access": "R" }, { @@ -1630,7 +1624,6 @@ "description": "capture time", "datatype": "date-time", "valuetype": "DYNAMIC", - "value": "EMPTY", "access": "R" } ] @@ -1638,6 +1631,7 @@ { "tag": "MBUS_CLIENT_SETUP", "description": "M-Bus client setup", + "note": null, "class-id": 72, "version": 1, "obis": "0.x.24.1.0.255", @@ -1645,7 +1639,7 @@ "meterTypes": ["SP","PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "PERIODIC" + "PQ_REQUEST": ["PERIODIC_SP","PERIODIC_PP"] }, "attributes": [ { @@ -1661,7 +1655,6 @@ "description": "capture definition", "datatype": "array", "valuetype": "DYNAMIC", - "value": "EMPTY", "access": "R" }, { @@ -1717,7 +1710,6 @@ "description": "access number", "datatype": "unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -1725,7 +1717,6 @@ "description": "status", "datatype": "unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -1733,7 +1724,6 @@ "description": "alarm", "datatype": "unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -1757,6 +1747,7 @@ { "tag": "MBUS_DIAGNOSTIC", "description": "M-Bus diagnostic", + "note": null, "class-id": 77, "version": 0, "obis": "0.x.24.9.0.255", @@ -1764,7 +1755,7 @@ "meterTypes": ["SP","PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "PERIODIC" + "PQ_REQUEST": ["PERIODIC_SP","PERIODIC_PP"] }, "attributes": [ { @@ -1772,7 +1763,6 @@ "description": "received signal strength", "datatype": "unsigned", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -1788,7 +1778,6 @@ "description": "link status", "datatype": "enum", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { @@ -1828,8 +1817,518 @@ "description": "capture time", "datatype": "structure", "valuetype": "DYNAMIC", + "access": "R" + } + ] + }, + { + "tag": "ALARM_REGISTER_1", + "description": "Alarm register 1", + "note": null, + "class-id": 1, + "version": 0, + "obis": "0.0.97.98.0.255", + "group": "ELECTRICITY", + "meterTypes": ["SP","PP"], + "properties": {}, + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "double-long-unsigned", + "valuetype": "DYNAMIC", + "access": "RW" + } + ] + }, + { + "tag": "ALARM_FILTER_1", + "description": "Alarm filter 1", + "note": null, + "class-id": 1, + "version": 0, + "obis": "0.0.97.98.10.255", + "group": "ELECTRICITY", + "meterTypes": [ + "SP", + "PP" + ], + "properties": {}, + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "double-long-unsigned", + "valuetype": "DYNAMIC", + "access": "RW" + } + ] + }, + { + "tag": "INTERVAL_VALUES_G", + "description": "Hourly interval readings of M-Bus device", + "class-id": 7, + "version": 1, + "obis": "0.x.24.3.0.255", + "group": "GAS", + "meterTypes": ["SP","PP"], + "properties": {}, + "attributes": [ + { + "id": 2, + "description": "buffer", + "datatype": "array", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 3, + "description": "capture objects", + "datatype": "array", + "valuetype": "FIXED_IN_PROFILE", + "value": "CLOCK,2|AMR_PROFILE_STATUS_HOURLY_G,2|MBUS_MASTER_VALUE,2|MBUS_MASTER_VALUE,5", + "access": "R" + }, + { + "id": 4, + "description": "capture period in sec", + "datatype": "double-long-unsigned", + "valuetype": "FIXED_IN_PROFILE", + "value": "3600", + "access": "R" + }, + { + "id": 5, + "description": "sort method", + "datatype": "enum", + "valuetype": "FIXED_IN_METER", + "value": "1", + "access": "R" + }, + { + "id": 6, + "description": "sort object", + "datatype": "object_definition", + "valuetype": "FIXED_IN_METER", + "value": "NONE", + "access": "R" + }, + { + "id": 7, + "description": "entries in use", + "datatype": "double-long-unsigned", + "valuetype": "DYNAMIC", + "value": "0", + "access": "R" + }, + { + "id": 8, + "description": "profile entries", + "datatype": "double-long-unsigned", + "valuetype": "FIXED_IN_PROFILE", + "value": "240", + "access": "R" + } + ] + }, + { + "tag": "DAILY_VALUES_G", + "description": "Daily billing values of M-Bus device", + "class-id": 7, + "version": 1, + "obis": "0.x.24.3.1.255", + "group": "GAS", + "meterTypes": ["SP","PP"], + "properties": {}, + "attributes": [ + { + "id": 2, + "description": "buffer", + "datatype": "array", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 3, + "description": "capture objects", + "datatype": "array", + "valuetype": "FIXED_IN_PROFILE", + "value": "CLOCK,2|AMR_PROFILE_STATUS_DAILY_G,2|MBUS_MASTER_VALUE,2|MBUS_MASTER_VALUE,5", + "access": "R" + }, + { + "id": 4, + "description": "capture period in sec", + "datatype": "double-long-unsigned", + "valuetype": "FIXED_IN_PROFILE", + "value": "86400", + "access": "R" + }, + { + "id": 5, + "description": "sort method", + "datatype": "enum", + "valuetype": "FIXED_IN_METER", + "value": "1", + "access": "R" + }, + { + "id": 6, + "description": "sort object", + "datatype": "object_definition", + "valuetype": "FIXED_IN_METER", + "value": "NONE", + "access": "R" + }, + { + "id": 7, + "description": "entries in use", + "datatype": "double-long-unsigned", + "valuetype": "DYNAMIC", + "value": "0", + "access": "R" + }, + { + "id": 8, + "description": "profile entries", + "datatype": "double-long-unsigned", + "valuetype": "FIXED_IN_PROFILE", + "value": "40", + "access": "R" + } + ] + }, + { + "tag": "MONTHLY_VALUES_G", + "description": "Monthly billing values of M-Bus device", + "class-id": 7, + "version": 1, + "obis": "0.x.24.3.2.255", + "group": "GAS", + "meterTypes": ["SP","PP"], + "properties": {}, + "attributes": [ + { + "id": 2, + "description": "buffer", + "datatype": "array", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 3, + "description": "capture objects", + "datatype": "array", + "valuetype": "FIXED_IN_PROFILE", + "value": "CLOCK,2|AMR_PROFILE_STATUS_MONTHLY_G,2|MBUS_MASTER_VALUE,2|MBUS_MASTER_VALUE,5", + "access": "R" + }, + { + "id": 4, + "description": "capture period in sec", + "datatype": "double-long-unsigned", + "valuetype": "FIXED_IN_PROFILE", "value": "0", "access": "R" + }, + { + "id": 5, + "description": "sort method", + "datatype": "enum", + "valuetype": "FIXED_IN_METER", + "value": "1", + "access": "R" + }, + { + "id": 6, + "description": "sort object", + "datatype": "object_definition", + "valuetype": "FIXED_IN_METER", + "value": "NONE", + "access": "R" + }, + { + "id": 7, + "description": "entries in use", + "datatype": "double-long-unsigned", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 8, + "description": "profile entries", + "datatype": "double-long-unsigned", + "valuetype": "FIXED_IN_PROFILE", + "value": "13", + "access": "R" + } + ] + }, + { + "tag": "AMR_PROFILE_STATUS_HOURLY_G", + "description": "AMR Profile status code M-Bus, hourly load profile values", + "class-id": 1, + "version": 0, + "obis": "0.x.96.10.3.255", + "group": "GAS", + "meterTypes": ["SP","PP"], + "properties": {}, + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "unsigned", + "valuetype": "DYNAMIC", + "access": "R" + } + ] + }, + { + "tag": "AMR_PROFILE_STATUS_DAILY_G", + "description": "AMR Profile status code M-Bus, daily load profile values", + "class-id": 1, + "version": 0, + "obis": "0.x.96.10.5.255", + "group": "GAS", + "meterTypes": ["SP","PP"], + "properties": {}, + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "unsigned", + "valuetype": "DYNAMIC", + "access": "R" + } + ] + }, + { + "tag": "AMR_PROFILE_STATUS_MONTHLY_G", + "description": "AMR Profile status code M-Bus, monthly load profile values", + "class-id": 1, + "version": 0, + "obis": "0.x.96.10.7.255", + "group": "GAS", + "meterTypes": ["SP","PP"], + "properties": {}, + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "unsigned", + "valuetype": "DYNAMIC", + "access": "R" + } + ] + }, + { + "tag": "MBUS_MASTER_VALUE", + "description": "M-Bus volume hourly", + "note": null, + "class-id": 4, + "version": 0, + "obis": "0.x.24.2.2.255", + "group": "GAS", + "meterTypes": ["SP","PP"], + "properties": {}, + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "double-long-unsigned", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 3, + "description": "scaler_unit", + "datatype": "scal_unit_type", + "valuetype": "BASED_ON_MODEL", + "valuebasedonmodel": { + "type": "GAS_METER_TYPE", + "values": [ + { + "types": ["G4-G6"], + "value": "-3, M3" + }, + { + "types": ["G10-G25"], + "value": "-2, M3" + } + ] + }, + "access": "R" + }, + { + "id": 4, + "description": "status", + "datatype": "unsigned", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 5, + "description": "capture_time", + "datatype": "octet-string", + "valuetype": "DYNAMIC", + "access": "R" + } + ] + }, + { + "tag": "READ_MBUS_STATUS", + "description": "Read MBus Status", + "note": null, + "class-id": 4, + "version": 0, + "obis": "0.x.24.2.6.255", + "group": "MBUS", + "meterTypes": ["SP","PP"], + "properties": {}, + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "double-long-unsigned", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 3, + "description": "scalar_unit", + "datatype": "scal_unit_type", + "valuetype": "DYNAMIC", + "value": "0, undefined", + "access": "R" + }, + { + "id": 4, + "description": "status", + "datatype": "unsigned", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 5, + "description": "capture_time", + "datatype": "octet-string", + "valuetype": "DYNAMIC", + "access": "R" + } + ] + }, + { + "tag": "ACTIVITY_CALENDAR", + "description": "Activity calendar", + "note": null, + "class-id": 20, + "version": 0, + "obis": "0.0.13.0.0.255", + "group": "ABSTRACT", + "meterTypes": ["SP","PP"], + "attributes": [ + { + "id": 2, + "description": "calendar_name_active", + "datatype": "octet-string", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 3, + "description": "season_profile_active", + "datatype": "array", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 4, + "description": "week_profile_table_active", + "datatype": "array", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 5, + "description": "day_profile_table_active", + "datatype": "array", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 6, + "description": "calendar_name_passive", + "datatype": "octet-string", + "valuetype": "SET_BY_CLIENT", + "access": "RW" + }, + { + "id": 7, + "description": "season_profile_passive", + "datatype": "array", + "valuetype": "SET_BY_CLIENT", + "access": "RW" + }, + { + "id": 8, + "description": "week_profile_table_passive", + "datatype": "array", + "valuetype": "SET_BY_CLIENT", + "access": "RW" + }, + { + "id": 9, + "description": "day_profile_table_passive", + "datatype": "array", + "valuetype": "SET_BY_CLIENT", + "access": "RW" + }, + { + "id": 10, + "description": "activate_passive_calendar_time", + "datatype": "octet-string", + "valuetype": "SET_BY_CLIENT", + "access": "RW" + } + ] + }, + { + "tag": "CONFIGURATION_OBJECT", + "description": "Configuration object", + "note": null, + "class-id": 1, + "version": 0, + "obis": "0.1.94.31.3.255", + "group": "ELECTRICITY", + "meterTypes": ["SP","PP"], + "properties": {}, + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "bit-string", + "valuetype": "SET_BY_CLIENT", + "access": "RW" + } + ] + }, + { + "tag": "RANDOMISATION_SETTINGS", + "description": "PHY Randomisation Object", + "note": null, + "class-id": 1, + "version": 0, + "obis": "0.1.94.31.12.255", + "group": "ELECTRICITY", + "meterTypes": ["SP","PP"], + "properties": {}, + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "structure", + "valuetype": "SET_BY_CLIENT", + "access": "RW" } ] } diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr50.json.license b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr500.json.license similarity index 100% rename from osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr50.json.license rename to osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr500.json.license diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr51.json b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr51.json index 5aba8ed8946..1981afef7dc 100644 --- a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr51.json +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr51.json @@ -4,8 +4,64 @@ "description": "Profile for Smart Meter Requirements 5.1", "inherit": { "profile": "SMR", - "version": "5.0" + "version": "5.0.0" }, "properties": [], - "objects": [] + "objects": [ + { + "tag": "CLEAR_MBUS_STATUS", + "description": "Clear MBus Status", + "note": null, + "class-id": 1, + "version": 0, + "obis": "0.x.94.31.10.255", + "group": "ELECTRICITY", + "meterTypes": ["SP","PP"], + "properties": {}, + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "double-long-unsigned", + "valuetype": "DYNAMIC", + "access": "RW" + } + ] + }, + { + "tag": "PHASE_OUTAGE_TEST", + "description": "Phase outage test scheduler", + "note": null, + "class-id": 22, + "version": 0, + "obis": "0.0.15.1.4.255", + "group": "ELECTRICITY", + "meterTypes": ["PP"], + "properties": {}, + "attributes": [ + { + "id": 2, + "description": "executed_script", + "datatype": "script", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 3, + "description": "type", + "datatype": "enum", + "valuetype": "DYNAMIC", + "value": "1", + "access": "R" + }, + { + "id": 4, + "description": "execution time", + "datatype": "array", + "valuetype": "SET_BY_CLIENT", + "access": "RW" + } + ] + } + ] } diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr52.json b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr52.json index c8c0a126354..0bcdbf98f7c 100644 --- a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr52.json +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr52.json @@ -7,5 +7,210 @@ "version": "5.1" }, "properties": [], - "objects": [] + "objects": [ + { + "tag": "DEFINABLE_LOAD_PROFILE", + "description": "Definable load profile", + "note": "Attribute 4 (capture period in sec) is overridden in factory with value 900 (default in spec: 86400)", + "class-id": 7, + "version": 1, + "obis": "0.1.94.31.6.255", + "group": "ELECTRICITY", + "meterTypes": [ + "SP", + "PP" + ], + "properties": { + "SELECTABLE_OBJECTS": [ + "CLOCK", + "NUMBER_OF_VOLTAGE_SAGS_FOR_L1", + "NUMBER_OF_VOLTAGE_SAGS_FOR_L2", + "NUMBER_OF_VOLTAGE_SAGS_FOR_L3", + "NUMBER_OF_VOLTAGE_SWELLS_FOR_L1", + "NUMBER_OF_VOLTAGE_SWELLS_FOR_L2", + "NUMBER_OF_VOLTAGE_SWELLS_FOR_L3", + "NUMBER_OF_POWER_FAILURES", + "INSTANTANEOUS_ACTIVE_CURRENT_TOTAL_OVER_ALL_PHASES", + "CDMA_DIAGNOSTIC", + "GPRS_DIAGNOSTIC", + "LTE_DIAGNOSTIC", + "MBUS_CLIENT_SETUP", + "MBUS_DIAGNOSTIC" + ] + }, + "attributes": [ + { + "id": 2, + "description": "buffer", + "datatype": "array", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 3, + "description": "capture objects", + "datatype": "array", + "valuetype": "SET_BY_CLIENT", + "access": "RW" + }, + { + "id": 4, + "description": "capture period in sec", + "note": "Attribute 4 (capture period in sec) is overridden in factory with value 900 (default in spec: 86400)", + "datatype": "double-long-unsigned", + "valuetype": "SET_BY_CLIENT", + "value": "900", + "access": "RW" + }, + { + "id": 5, + "description": "sort method", + "datatype": "enum", + "valuetype": "FIXED_IN_METER", + "value": "1", + "access": "R" + }, + { + "id": 6, + "description": "sort object", + "datatype": "object_definition", + "valuetype": "FIXED_IN_METER", + "value": "NONE", + "access": "R" + }, + { + "id": 7, + "description": "entries in use", + "datatype": "double-long-unsigned", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 8, + "description": "profile entries", + "datatype": "double-long-unsigned", + "valuetype": "SET_BY_CLIENT", + "value": "960", + "access": "RW" + } + ] + }, + { + "tag": "LTE_DIAGNOSTIC", + "description": "LTE Diagnostic", + "note": null, + "class-id": 47, + "version": 0, + "obis": "0.2.25.6.0.255", + "group": "ELECTRICITY", + "meterTypes": [ + "SP", + "PP" + ], + "properties": { + "PQ_PROFILE": "PUBLIC", + "PQ_REQUEST": [ + "PERIODIC_SP", + "PERIODIC_PP" + ] + }, + "attributes": [ + { + "id": 2, + "description": "operator", + "datatype": "visible-string", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 3, + "description": "status", + "datatype": "enum", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 4, + "description": "cs attachment", + "datatype": "enum", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 5, + "description": "ps status", + "datatype": "enum", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 6, + "description": "cell info", + "datatype": "cell_info_type", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 7, + "description": "adjacent cells", + "datatype": "array", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 8, + "description": "capture time", + "datatype": "date-time", + "valuetype": "DYNAMIC", + "access": "R" + } + ] + }, + { + "tag": "ALARM_REGISTER_2", + "description": "Alarm register 2", + "note": "Specified in addendum for SMR5.2", + "class-id": 1, + "version": 0, + "obis": "0.0.97.98.1.255", + "group": "ELECTRICITY", + "meterTypes": [ + "SP", + "PP" + ], + "properties": {}, + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "double-long-unsigned", + "valuetype": "DYNAMIC", + "access": "RW" + } + ] + }, + { + "tag": "ALARM_FILTER_2", + "description": "Alarm filter 2", + "note": "Specified in addendum for SMR5.2", + "class-id": 1, + "version": 0, + "obis": "0.0.97.98.11.255", + "group": "ELECTRICITY", + "meterTypes": [ + "SP", + "PP" + ], + "properties": {}, + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "double-long-unsigned", + "valuetype": "DYNAMIC", + "access": "RW" + } + ] + } + ] } diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr55.json b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr55.json index bbf15b2b880..3996597d3bb 100644 --- a/osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr55.json +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr55.json @@ -7,5 +7,138 @@ "version": "5.2" }, "properties": [], - "objects": [] + "objects": [{ + "tag": "PUSH_SETUP_UDP", + "description": "Push Setup UDP", + "note": null, + "class-id": 40, + "version": 0, + "obis": "0.3.25.9.0.255", + "group": "ABSTRACT", + "meterTypes": ["SP","PP"], + "attributes": [ + { + "id": 2, + "description": "push_object_list", + "datatype": "array", + "valuetype": "DYNAMIC", + "access": "RW" + }, + { + "id": 3, + "description": "send_destination_and_method", + "datatype": "structure", + "valuetype": "DYNAMIC", + "access": "RW" + }, + { + "id": 4, + "description": "communication_window", + "datatype": "array", + "valuetype": "DYNAMIC", + "access": "RW" + }, + { + "id": 5, + "description": "randomisation_start_interval", + "datatype": "long-unsigned", + "valuetype": "DYNAMIC", + "value": "5", + "access": "RW" + }, + { + "id": 6, + "description": "number of retries", + "datatype": "unsigned", + "valuetype": "DYNAMIC", + "access": "RW" + }, + { + "id": 7, + "description": "repetition_delay", + "datatype": "long-unsigned", + "valuetype": "DYNAMIC", + "access": "RW" + } + ] + }, + { + "tag": "ALARM_REGISTER_3", + "description": "Alarm register 3", + "note": "Specified in addendum for SMR5.5", + "class-id": 1, + "version": 0, + "obis": "0.0.97.98.2.255", + "group": "ELECTRICITY", + "meterTypes": ["SP","PP"], + "properties": {}, + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "double-long-unsigned", + "valuetype": "DYNAMIC", + "access": "RW" + } + ] + }, + { + "tag": "ALARM_FILTER_3", + "description": "Alarm filter 3", + "note": "Specified in addendum for SMR5.5", + "class-id": 1, + "version": 0, + "obis": "0.0.97.98.12.255", + "group": "ELECTRICITY", + "meterTypes": [ + "SP", + "PP" + ], + "properties": {}, + "attributes": [ + { + "id": 2, + "description": "value", + "datatype": "double-long-unsigned", + "valuetype": "DYNAMIC", + "access": "RW" + } + ] + }, + { + "tag": "LAST_GASP_TEST", + "description": "Last gasp test scheduler", + "note": "Specified in addendum for SMR5.5", + "class-id": 22, + "version": 0, + "obis": "0.0.15.2.4.255", + "group": "ELECTRICITY", + "meterTypes": ["PP"], + "properties": {}, + "attributes": [ + { + "id": 2, + "description": "executed_script", + "datatype": "script", + "valuetype": "DYNAMIC", + "access": "R" + }, + { + "id": 3, + "description": "type", + "datatype": "enum", + "valuetype": "DYNAMIC", + "value": "1", + "access": "R" + }, + { + "id": 4, + "description": "execution time", + "datatype": "array", + "valuetype": "SET_BY_CLIENT", + "access": "RW" + } + ] + } + ] } diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/test/java/org/opensmartgridplatform/dlms/objectcondig/DlmsProfileTest.java b/osgp/protocol-adapter-dlms/osgp-dlms/src/test/java/org/opensmartgridplatform/dlms/objectcondig/DlmsProfileTest.java deleted file mode 100644 index 78c7c9555ea..00000000000 --- a/osgp/protocol-adapter-dlms/osgp-dlms/src/test/java/org/opensmartgridplatform/dlms/objectcondig/DlmsProfileTest.java +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-FileCopyrightText: Copyright Contributors to the GXF project -// -// SPDX-License-Identifier: Apache-2.0 - -package org.opensmartgridplatform.dlms.objectcondig; - -import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import com.fasterxml.jackson.databind.ObjectMapper; -import java.io.IOException; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.opensmartgridplatform.dlms.objectconfig.DlmsProfile; -import org.springframework.core.io.ClassPathResource; - -@Slf4j -class DlmsProfileTest { - - private ObjectMapper objectMapper; - - @BeforeEach - void init() { - this.objectMapper = new ObjectMapper(); - } - - @Test - void loadJsonFile() throws IOException { - - final DlmsProfile dlmsProfile = - this.objectMapper.readValue( - new ClassPathResource("/dlmsprofiles/dlmsprofile-smr50.json").getFile(), - DlmsProfile.class); - - assertNotNull(dlmsProfile); - assertThat(dlmsProfile.getObjects()).hasSize(48); - } -} diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/test/java/org/opensmartgridplatform/dlms/objectcondig/DlmsProfileValidatorTest.java b/osgp/protocol-adapter-dlms/osgp-dlms/src/test/java/org/opensmartgridplatform/dlms/objectcondig/DlmsProfileValidatorTest.java deleted file mode 100644 index f70b1060955..00000000000 --- a/osgp/protocol-adapter-dlms/osgp-dlms/src/test/java/org/opensmartgridplatform/dlms/objectcondig/DlmsProfileValidatorTest.java +++ /dev/null @@ -1,74 +0,0 @@ -// SPDX-FileCopyrightText: Copyright Contributors to the GXF project -// -// SPDX-License-Identifier: Apache-2.0 - -package org.opensmartgridplatform.dlms.objectcondig; - -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; - -import com.fasterxml.jackson.databind.ObjectMapper; -import java.io.IOException; -import java.util.Arrays; -import java.util.Collections; -import lombok.extern.slf4j.Slf4j; -import org.junit.jupiter.api.Test; -import org.opensmartgridplatform.dlms.exceptions.ObjectConfigException; -import org.opensmartgridplatform.dlms.objectconfig.DlmsProfile; -import org.opensmartgridplatform.dlms.objectconfig.DlmsProfileValidator; -import org.springframework.core.io.ClassPathResource; - -@Slf4j -class DlmsProfileValidatorTest { - - @Test - void testValidProfiles() throws IOException, ObjectConfigException { - - final ObjectMapper objectMapper = new ObjectMapper(); - final DlmsProfile dlmsProfile50 = - objectMapper.readValue( - new ClassPathResource("/dlmsprofiles/dlmsprofile-smr50.json").getFile(), - DlmsProfile.class); - final DlmsProfile dlmsProfile51 = - objectMapper.readValue( - new ClassPathResource("/dlmsprofiles/dlmsprofile-smr51.json").getFile(), - DlmsProfile.class); - - DlmsProfileValidator.validate(Arrays.asList(dlmsProfile50, dlmsProfile51)); - } - - @Test - void testProfileWithMissingUnit() throws IOException { - - final ObjectMapper objectMapper = new ObjectMapper(); - final DlmsProfile dlmsProfile = - objectMapper.readValue( - new ClassPathResource("/dlmsprofile-smr50-missingUnit.json").getFile(), - DlmsProfile.class); - - try { - DlmsProfileValidator.validate(Collections.singletonList(dlmsProfile)); - } catch (final ObjectConfigException e) { - assertThat(e.getMessage()) - .isEqualTo( - "DlmsProfile SMR 5.0.0 register validation error: Register(s) without scaler_unit: AVERAGE_ACTIVE_POWER_IMPORT_L2"); - } - } - - @Test - void testProfileWithPQProfileErrors() throws IOException { - - final ObjectMapper objectMapper = new ObjectMapper(); - final DlmsProfile dlmsProfile = - objectMapper.readValue( - new ClassPathResource("/dlmsprofile-smr50-PQProfileErrors.json").getFile(), - DlmsProfile.class); - - try { - DlmsProfileValidator.validate(Collections.singletonList(dlmsProfile)); - } catch (final ObjectConfigException e) { - assertThat(e.getMessage()) - .isEqualTo( - "DlmsProfile SMR 5.0.0 PQ validation error: AVERAGE_ACTIVE_POWER_IMPORT_L1 doesn't contain PQ Profile, PQ Profile POWER_QUALITY_PROFILE_2 has no selectable objects"); - } - } -} diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/test/java/org/opensmartgridplatform/dlms/objectconfig/CosemObjectTest.java b/osgp/protocol-adapter-dlms/osgp-dlms/src/test/java/org/opensmartgridplatform/dlms/objectconfig/CosemObjectTest.java new file mode 100644 index 00000000000..bf409e84b76 --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/test/java/org/opensmartgridplatform/dlms/objectconfig/CosemObjectTest.java @@ -0,0 +1,75 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.dlms.objectconfig; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; +import java.util.Map; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.ValueSource; +import org.opensmartgridplatform.dlms.exceptions.ObjectConfigException; + +@Slf4j +class CosemObjectTest { + + @Test + void getAttribute() { + final Attribute attribute1 = this.createAttribute(1, "Value 1"); + final Attribute attribute2 = this.createAttribute(2, "Value 2"); + + final CosemObject object = this.createCosemObject(List.of(attribute1, attribute2)); + + assertThat(object.getAttribute(1)).isEqualTo(attribute1); + assertThat(object.getAttribute(2)).isEqualTo(attribute2); + Assertions.assertThrows(IllegalArgumentException.class, () -> object.getAttribute(3)); + } + + @ParameterizedTest + @CsvSource({"1.1.1.1.1.1,1", "0.2.0.0.0.0,2", "1.4.99.98.10.255,4"}) + void getChannel(final String obis, final int expectedChannel) throws ObjectConfigException { + + final CosemObject object = this.createCosemObject(obis); + + assertThat(object.getChannel()).isEqualTo(expectedChannel); + } + + @ParameterizedTest + @ValueSource(strings = {"1.2.3.4.5", "1.2.3.4.5.6.7", "1.x.1.1.1.1.1"}) + void getChannelWithError(final String obis) { + + final CosemObject object = this.createCosemObject(obis); + + Assertions.assertThrows(ObjectConfigException.class, object::getChannel); + } + + @ParameterizedTest + @CsvSource({"1.1.1.1.1.1,false", "0.x.0.0.0.0,true", "0.X.0.0.0.0,false"}) + void hasWildcardChannel(final String obis, final boolean result) throws ObjectConfigException { + + final CosemObject object = this.createCosemObject(obis); + + assertThat(object.hasWildcardChannel()).isEqualTo(result); + } + + private Attribute createAttribute(final int id, final String value) { + return new Attribute( + id, "descr", null, DlmsDataType.DONT_CARE, ValueType.DYNAMIC, value, null, AccessType.RW); + } + + private CosemObject createCosemObject(final List attributes) { + return new CosemObject( + "TAG", "descr", 1, 0, "1.2.3", "group", null, List.of(), Map.of(), attributes); + } + + private CosemObject createCosemObject(final String obis) { + return new CosemObject( + "TAG", "descr", 1, 0, obis, "group", null, List.of(), Map.of(), List.of()); + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/test/java/org/opensmartgridplatform/dlms/objectconfig/DlmsProfileTest.java b/osgp/protocol-adapter-dlms/osgp-dlms/src/test/java/org/opensmartgridplatform/dlms/objectconfig/DlmsProfileTest.java new file mode 100644 index 00000000000..4cf218d4fd7 --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/test/java/org/opensmartgridplatform/dlms/objectconfig/DlmsProfileTest.java @@ -0,0 +1,44 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.dlms.objectconfig; + +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import lombok.extern.slf4j.Slf4j; +import org.assertj.core.api.AssertionsForInterfaceTypes; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.opensmartgridplatform.dlms.services.Protocol; +import org.springframework.core.io.ClassPathResource; + +@Slf4j +class DlmsProfileTest { + + private ObjectMapper objectMapper; + + @BeforeEach + void init() { + this.objectMapper = new ObjectMapper(); + } + + @ParameterizedTest + @CsvSource({ + "DSMR_2_2,dlmsprofile-dsmr22.json", + "DSMR_4_2_2,dlmsprofile-dsmr422.json", + "SMR_5_0_0,dlmsprofile-smr500.json", + }) + void loadJsonFile(final String enumName, final String fileName) throws IOException { + + final DlmsProfile dlmsProfile = + this.objectMapper.readValue( + new ClassPathResource("/dlmsprofiles/" + fileName).getFile(), DlmsProfile.class); + + Assertions.assertNotNull(dlmsProfile); + AssertionsForInterfaceTypes.assertThat(dlmsProfile.getObjects()) + .hasSize(Protocol.valueOf(enumName).getNrOfCosemObjects()); + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/test/java/org/opensmartgridplatform/dlms/objectconfig/DlmsProfileValidatorTest.java b/osgp/protocol-adapter-dlms/osgp-dlms/src/test/java/org/opensmartgridplatform/dlms/objectconfig/DlmsProfileValidatorTest.java new file mode 100644 index 00000000000..45d5cd014ff --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/test/java/org/opensmartgridplatform/dlms/objectconfig/DlmsProfileValidatorTest.java @@ -0,0 +1,97 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.dlms.objectconfig; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.opensmartgridplatform.dlms.exceptions.ObjectConfigException; +import org.opensmartgridplatform.dlms.services.ObjectConfigService; +import org.springframework.core.io.ClassPathResource; + +@Slf4j +class DlmsProfileValidatorTest { + + @Test + void testValidProfiles() throws IOException, ObjectConfigException { + + final ObjectMapper objectMapper = new ObjectMapper(); + final DlmsProfile dlmsProfile50 = + objectMapper.readValue( + new ClassPathResource("/dlmsprofiles/dlmsprofile-smr500.json").getFile(), + DlmsProfile.class); + final DlmsProfile dlmsProfile51 = + objectMapper.readValue( + new ClassPathResource("/dlmsprofiles/dlmsprofile-smr51.json").getFile(), + DlmsProfile.class); + + DlmsProfileValidator.validate(Arrays.asList(dlmsProfile50, dlmsProfile51)); + } + + static Stream errorCases() { + final List errorCases = + List.of( + Arguments.of( + "/dlmsprofile-smr50-missingUnit.json", + "DlmsProfile SMR 5.0.0 register validation error: Register(s) without scaler_unit: AVERAGE_ACTIVE_POWER_IMPORT_L2"), + Arguments.of( + "/dlmsprofile-smr50-PQProfileErrors.json", + "DlmsProfile SMR 5.0.0 PQ validation error: AVERAGE_ACTIVE_POWER_IMPORT_L1 doesn't contain PQ Profile, PQ Profile POWER_QUALITY_PROFILE_2 has no selectable objects"), + Arguments.of( + "/dlmsprofile-smr50-missingCaptureObject.json", + "DlmsProfile SMR 5.0.0 Capture objects validation error: Profile doesn't contain object for MBUS_MASTER_VALUE")); + + return errorCases.stream(); + } + + @ParameterizedTest + @MethodSource("errorCases") + void testProfileWithError(final String fileName, final String expectedError) throws IOException { + + final ObjectMapper objectMapper = new ObjectMapper(); + final DlmsProfile dlmsProfile = + objectMapper.readValue(new ClassPathResource(fileName).getFile(), DlmsProfile.class); + + try { + DlmsProfileValidator.validate(Collections.singletonList(dlmsProfile)); + } catch (final ObjectConfigException e) { + assertThat(e.getMessage()).isEqualTo(expectedError); + } + } + + @Test + void testAllValueTypesFixedInProfileHaveAValue() throws IOException, ObjectConfigException { + + final ObjectConfigService objectConfigService = new ObjectConfigService(); + final List dlmsProfiles = objectConfigService.dlmsProfiles; + + final List fixedWithoutValueList = + dlmsProfiles.stream() + .filter( + profile -> + profile.getObjects().stream() + .anyMatch( + object -> + object.getAttributes().stream() + .anyMatch( + attribute -> + attribute.getValuetype() == ValueType.FIXED_IN_PROFILE + && attribute.getValue() == null))) + .toList(); + + Assertions.assertThat(fixedWithoutValueList).isEmpty(); + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/test/java/org/opensmartgridplatform/dlms/objectconfig/configlookup/ConfigLookupGroupTest.java b/osgp/protocol-adapter-dlms/osgp-dlms/src/test/java/org/opensmartgridplatform/dlms/objectconfig/configlookup/ConfigLookupGroupTest.java new file mode 100644 index 00000000000..f13af218d4a --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/test/java/org/opensmartgridplatform/dlms/objectconfig/configlookup/ConfigLookupGroupTest.java @@ -0,0 +1,35 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.dlms.objectconfig.configlookup; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.Test; + +@Slf4j +class ConfigLookupGroupTest { + + @Test + void getType() { + final ConfigLookupType configLookupTypeG4G6 = new ConfigLookupType(); + configLookupTypeG4G6.type = "G4_G6"; + configLookupTypeG4G6.match = List.of("G4", "G6"); + final ConfigLookupType configLookupTypeG10G25 = new ConfigLookupType(); + configLookupTypeG10G25.type = "G10_G25"; + configLookupTypeG10G25.match = List.of("G10", "G16", "G25"); + + final ConfigLookupGroup group = new ConfigLookupGroup(); + group.defaulttype = "Unmatched"; + group.configlookuptypes = List.of(configLookupTypeG4G6, configLookupTypeG10G25); + + assertThat(group.getMatchingType("SmallMeterModelTypeG4")).isEqualTo(configLookupTypeG4G6.type); + assertThat(group.getMatchingType("BigMeterG25")).isEqualTo(configLookupTypeG10G25.type); + assertThat(group.getMatchingType("G25meterWithG4inName")) + .isEqualTo(configLookupTypeG10G25.type); + assertThat(group.getMatchingType("UnknownModel")).isEqualTo("Unmatched"); + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/test/java/org/opensmartgridplatform/dlms/objectconfig/configlookup/ConfigLookupTypeTest.java b/osgp/protocol-adapter-dlms/osgp-dlms/src/test/java/org/opensmartgridplatform/dlms/objectconfig/configlookup/ConfigLookupTypeTest.java new file mode 100644 index 00000000000..346e726b738 --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/test/java/org/opensmartgridplatform/dlms/objectconfig/configlookup/ConfigLookupTypeTest.java @@ -0,0 +1,25 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.dlms.objectconfig.configlookup; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.Test; + +@Slf4j +class ConfigLookupTypeTest { + + @Test + void match() { + final ConfigLookupType configLookupType = new ConfigLookupType(); + configLookupType.match = List.of("G4", "G6"); + + assertThat(configLookupType.matches("SmallMeterModelTypeG4")).isTrue(); + assertThat(configLookupType.matches("BiggerMeterG6Type")).isTrue(); + assertThat(configLookupType.matches("UnknownMeterType")).isFalse(); + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/test/java/org/opensmartgridplatform/dlms/services/ObjectConfigServiceTest.java b/osgp/protocol-adapter-dlms/osgp-dlms/src/test/java/org/opensmartgridplatform/dlms/services/ObjectConfigServiceTest.java index 4add4494492..a20248fb37c 100644 --- a/osgp/protocol-adapter-dlms/osgp-dlms/src/test/java/org/opensmartgridplatform/dlms/services/ObjectConfigServiceTest.java +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/test/java/org/opensmartgridplatform/dlms/services/ObjectConfigServiceTest.java @@ -4,39 +4,174 @@ package org.opensmartgridplatform.dlms.services; -import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.opensmartgridplatform.dlms.services.ObjectConfigService.getAttributeIdFromCaptureObjectDefinition; +import static org.opensmartgridplatform.dlms.services.ObjectConfigService.getCaptureObjectDefinitions; +import static org.opensmartgridplatform.dlms.services.ObjectConfigService.getCosemObjectTypeFromCaptureObjectDefinition; -import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; +import java.util.EnumMap; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; import org.opensmartgridplatform.dlms.exceptions.ObjectConfigException; +import org.opensmartgridplatform.dlms.objectconfig.AccessType; +import org.opensmartgridplatform.dlms.objectconfig.Attribute; +import org.opensmartgridplatform.dlms.objectconfig.CaptureObject; import org.opensmartgridplatform.dlms.objectconfig.CosemObject; +import org.opensmartgridplatform.dlms.objectconfig.DlmsDataType; import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; -import org.opensmartgridplatform.dlms.objectconfig.DlmsProfile; import org.opensmartgridplatform.dlms.objectconfig.ObjectProperty; -import org.springframework.core.io.ClassPathResource; +import org.opensmartgridplatform.dlms.objectconfig.PowerQualityRequest; +import org.opensmartgridplatform.dlms.objectconfig.TypeBasedValue; +import org.opensmartgridplatform.dlms.objectconfig.ValueBasedOnModel; +import org.opensmartgridplatform.dlms.objectconfig.ValueType; @Slf4j class ObjectConfigServiceTest { - final ObjectMapper objectMapper = new ObjectMapper(); - private ObjectConfigService objectConfigService; + private final int PROFILE_GENERIC_CLASS_ID = 7; + private final int PROFILE_GENERIC_CAPTURE_OBJECTS_ATTR_ID = 3; + private final int REGISTER_CLASS_ID = 3; + private final int REGISTER_SCALER_UNIT_ATTR_ID = 3; + @BeforeEach void setUp() throws IOException, ObjectConfigException { - final List dlmsProfileList = this.getDlmsProfileList(); - this.objectConfigService = new ObjectConfigService(dlmsProfileList); + this.objectConfigService = new ObjectConfigService(); + } + + @ParameterizedTest + @EnumSource(Protocol.class) + void testProtocolSpecifics(final Protocol protocol) throws ObjectConfigException { + + final Map cosemObjects = + this.objectConfigService.getCosemObjects(protocol.getName(), protocol.getVersion()); + assertThat(cosemObjects).hasSize(protocol.getNrOfCosemObjects()); + + final List cosemObjectsOnDemandPrivate = + this.getCosemObjectsWithProperties( + protocol, PowerQualityRequest.ACTUAL_SP, Profile.PRIVATE); + assertThat(cosemObjectsOnDemandPrivate) + .hasSize(protocol.getNrOfCosemObjects(PowerQualityRequest.ACTUAL_SP, Profile.PRIVATE)); + + final List cosemObjectsOnDemandPublic = + this.getCosemObjectsWithProperties(protocol, PowerQualityRequest.ACTUAL_SP, Profile.PUBLIC); + assertThat(cosemObjectsOnDemandPublic) + .hasSize(protocol.getNrOfCosemObjects(PowerQualityRequest.ACTUAL_SP, Profile.PUBLIC)); + + final List cosemObjectsOnPeriodicSpPrivate = + this.getCosemObjectsWithProperties( + protocol, PowerQualityRequest.PERIODIC_SP, Profile.PRIVATE); + assertThat(cosemObjectsOnPeriodicSpPrivate) + .hasSize(protocol.getNrOfCosemObjects(PowerQualityRequest.PERIODIC_SP, Profile.PRIVATE)); + + final List cosemObjectsOnPeriodicPpPrivate = + this.getCosemObjectsWithProperties( + protocol, PowerQualityRequest.PERIODIC_PP, Profile.PRIVATE); + assertThat(cosemObjectsOnPeriodicPpPrivate) + .hasSize(protocol.getNrOfCosemObjects(PowerQualityRequest.PERIODIC_PP, Profile.PRIVATE)); + + final List cosemObjectsPeriodicSpPublic = + this.getCosemObjectsWithProperties( + protocol, PowerQualityRequest.PERIODIC_SP, Profile.PUBLIC); + assertThat(cosemObjectsPeriodicSpPublic) + .hasSize(protocol.getNrOfCosemObjects(PowerQualityRequest.PERIODIC_SP, Profile.PUBLIC)); + + final List cosemObjectsPeriodicPpPublic = + this.getCosemObjectsWithProperties( + protocol, PowerQualityRequest.PERIODIC_PP, Profile.PUBLIC); + assertThat(cosemObjectsPeriodicPpPublic) + .hasSize(protocol.getNrOfCosemObjects(PowerQualityRequest.PERIODIC_PP, Profile.PUBLIC)); + } + + @ParameterizedTest + @EnumSource(Protocol.class) + void testProfilesObjectsContainPqObjects(final Protocol protocol) throws ObjectConfigException { + this.assertAllInConfig( + protocol, DlmsObjectType.DEFINABLE_LOAD_PROFILE, protocol.hasDefinableLoadProfile()); + this.assertAllInConfig( + protocol, DlmsObjectType.POWER_QUALITY_PROFILE_1, protocol.hasPqProfiles()); + this.assertAllInConfig( + protocol, DlmsObjectType.POWER_QUALITY_PROFILE_2, protocol.hasPqProfiles()); + } + + @ParameterizedTest + @EnumSource(Protocol.class) + void testAllPqObjectMapToProfile(final Protocol protocol) throws ObjectConfigException { + final List dlmsProfiles = new ArrayList<>(); + if (protocol.hasDefinableLoadProfile()) { + assertThat( + this.objectConfigService.getCosemObject( + protocol.getName(), protocol.getVersion(), DlmsObjectType.DEFINABLE_LOAD_PROFILE)) + .isNotNull(); + dlmsProfiles.add(DlmsObjectType.DEFINABLE_LOAD_PROFILE); + } + if (protocol.hasPqProfiles()) { + assertThat( + this.objectConfigService.getCosemObject( + protocol.getName(), + protocol.getVersion(), + DlmsObjectType.POWER_QUALITY_PROFILE_1)) + .isNotNull(); + assertThat( + this.objectConfigService.getCosemObject( + protocol.getName(), + protocol.getVersion(), + DlmsObjectType.POWER_QUALITY_PROFILE_2)) + .isNotNull(); + dlmsProfiles.addAll( + List.of(DlmsObjectType.POWER_QUALITY_PROFILE_1, DlmsObjectType.POWER_QUALITY_PROFILE_2)); + } + if (!dlmsProfiles.isEmpty()) { + this.assertAllPqPeriodicObjectsInProfiles(protocol, dlmsProfiles); + } + } + + private List getCosemObjectsWithProperties( + final Protocol protocol, final PowerQualityRequest powerQualityRequest, final Profile profile) + throws ObjectConfigException { + final EnumMap> pqProperties = new EnumMap<>(ObjectProperty.class); + pqProperties.put(ObjectProperty.PQ_PROFILE, Collections.singletonList(profile.name())); + pqProperties.put(ObjectProperty.PQ_REQUEST, List.of(powerQualityRequest.name())); + + return this.objectConfigService.getCosemObjectsWithProperties( + protocol.getName(), protocol.getVersion(), pqProperties); + } + + @Test + void testGetCosemObjectsDsmr22() throws ObjectConfigException { + final Map cosemObjects = + this.objectConfigService.getCosemObjects("DSMR", "2.2"); + + assertNotNull(cosemObjects); + assertThat(cosemObjects).hasSize(Protocol.DSMR_2_2.getNrOfCosemObjects()); + assertNotNull(cosemObjects.get(DlmsObjectType.ALARM_REGISTER_1)); + assertNotNull(cosemObjects.get(DlmsObjectType.NUMBER_OF_VOLTAGE_SWELLS_FOR_L1)); + } + + @Test + void testGetCosemObjectsDsmr422() throws ObjectConfigException { + final Map cosemObjects = + this.objectConfigService.getCosemObjects("DSMR", "4.2.2"); + + assertNotNull(cosemObjects); + assertThat(cosemObjects).hasSize(Protocol.DSMR_4_2_2.getNrOfCosemObjects()); + assertNotNull(cosemObjects.get(DlmsObjectType.ALARM_REGISTER_1)); + assertNotNull(cosemObjects.get(DlmsObjectType.NUMBER_OF_VOLTAGE_SWELLS_FOR_L1)); + assertNull(cosemObjects.get(DlmsObjectType.CDMA_DIAGNOSTIC)); } @Test @@ -48,29 +183,76 @@ void getCosemObjectIsNull() throws ObjectConfigException { this.objectConfigService.getCosemObjects(protocolName, protocolVersion43); assertNotNull(cosemObjects); - assertThat(cosemObjects).hasSize(28); + assertThat(cosemObjects).hasSize(Protocol.SMR_4_3.getNrOfCosemObjects()); + assertNotNull(cosemObjects.get(DlmsObjectType.ALARM_REGISTER_1)); + } + + @Test + void testGetCosemObjectsSmr43_shouldComplyWithAssertionChecks() throws ObjectConfigException { + final Map cosemObjects = + this.objectConfigService.getCosemObjects("SMR", "4.3"); + + assertNotNull(cosemObjects); + assertThat(cosemObjects).hasSize(Protocol.SMR_4_3.getNrOfCosemObjects()); + assertNotNull(cosemObjects.get(DlmsObjectType.ALARM_REGISTER_1)); + assertNotNull(cosemObjects.get(DlmsObjectType.NUMBER_OF_VOLTAGE_SWELLS_FOR_L1)); + assertNotNull(cosemObjects.get(DlmsObjectType.CDMA_DIAGNOSTIC)); assertNull(cosemObjects.get(DlmsObjectType.MBUS_DIAGNOSTIC)); } @Test - void testGetCosemObjects() throws ObjectConfigException { - final String protocolName = "SMR"; - final String protocolVersion51 = "5.1"; - final String protocolVersion52 = "5.2"; + void testGetCosemObjectsSmr500() throws ObjectConfigException { + final Map cosemObjects = + this.objectConfigService.getCosemObjects("SMR", "5.0.0"); + + assertNotNull(cosemObjects); + assertThat(cosemObjects).hasSize(Protocol.SMR_5_0_0.getNrOfCosemObjects()); + assertNotNull(cosemObjects.get(DlmsObjectType.ALARM_REGISTER_1)); + assertNotNull(cosemObjects.get(DlmsObjectType.NUMBER_OF_POWER_FAILURES)); + assertNull(cosemObjects.get(DlmsObjectType.LTE_DIAGNOSTIC)); + assertNull(cosemObjects.get(DlmsObjectType.PUSH_SETUP_UDP)); + } + + @Test + void testGetCosemObjectsSmr51() throws ObjectConfigException { + final Map cosemObjects = + this.objectConfigService.getCosemObjects("SMR", "5.1"); + + assertNotNull(cosemObjects); + assertThat(cosemObjects).hasSize(Protocol.SMR_5_1.getNrOfCosemObjects()); + assertNotNull(cosemObjects.get(DlmsObjectType.ALARM_REGISTER_1)); + assertNotNull(cosemObjects.get(DlmsObjectType.NUMBER_OF_POWER_FAILURES)); + assertNull(cosemObjects.get(DlmsObjectType.LTE_DIAGNOSTIC)); + assertNull(cosemObjects.get(DlmsObjectType.PUSH_SETUP_UDP)); + } - final Map cosemObjects51 = - this.objectConfigService.getCosemObjects(protocolName, protocolVersion51); + @Test + void testGetCosemObjectsSmr52() throws ObjectConfigException { + final Map cosemObjects = + this.objectConfigService.getCosemObjects("SMR", "5.2"); - assertNotNull(cosemObjects51); - assertThat(cosemObjects51).hasSize(48); - assertNotNull(cosemObjects51.get(DlmsObjectType.NUMBER_OF_POWER_FAILURES)); + assertNotNull(cosemObjects); + assertThat(cosemObjects).hasSize(Protocol.SMR_5_2.getNrOfCosemObjects()); + assertNotNull(cosemObjects.get(DlmsObjectType.ALARM_REGISTER_1)); + assertNotNull(cosemObjects.get(DlmsObjectType.ALARM_REGISTER_2)); + assertNotNull(cosemObjects.get(DlmsObjectType.NUMBER_OF_POWER_FAILURES)); + assertNotNull(cosemObjects.get(DlmsObjectType.LTE_DIAGNOSTIC)); + assertNull(cosemObjects.get(DlmsObjectType.PUSH_SETUP_UDP)); + } - final Map cosemObjects52 = - this.objectConfigService.getCosemObjects(protocolName, protocolVersion52); + @Test + void testGetCosemObjectsSmr55() throws ObjectConfigException { + final Map cosemObjects = + this.objectConfigService.getCosemObjects("SMR", "5.5"); - assertNotNull(cosemObjects52); - assertThat(cosemObjects52).hasSize(48); - assertNotNull(cosemObjects52.get(DlmsObjectType.NUMBER_OF_LONG_POWER_FAILURES)); + assertNotNull(cosemObjects); + assertThat(cosemObjects).hasSize(Protocol.SMR_5_5.getNrOfCosemObjects()); + assertNotNull(cosemObjects.get(DlmsObjectType.ALARM_REGISTER_1)); + assertNotNull(cosemObjects.get(DlmsObjectType.ALARM_REGISTER_2)); + assertNotNull(cosemObjects.get(DlmsObjectType.ALARM_REGISTER_3)); + assertNotNull(cosemObjects.get(DlmsObjectType.NUMBER_OF_POWER_FAILURES)); + assertNotNull(cosemObjects.get(DlmsObjectType.LTE_DIAGNOSTIC)); + assertNotNull(cosemObjects.get(DlmsObjectType.PUSH_SETUP_UDP)); } @Test @@ -105,42 +287,25 @@ void getCosemObjectShouldFindObject() throws ObjectConfigException { } @Test - void testGetCosemObjectsWithProperty() throws ObjectConfigException { - final String protocolName = "SMR"; - final String protocolVersion50 = "5.0"; - - final List cosemObjectsWithSelectableObjects = - this.objectConfigService.getCosemObjectsWithProperty( - protocolName, protocolVersion50, ObjectProperty.SELECTABLE_OBJECTS, null); - - assertNotNull(cosemObjectsWithSelectableObjects); - assertThat(cosemObjectsWithSelectableObjects).hasSize(3); - - final List cosemObjectsWithPqProfile = - this.objectConfigService.getCosemObjectsWithProperty( - protocolName, protocolVersion50, ObjectProperty.PQ_PROFILE, null); - - assertNotNull(cosemObjectsWithPqProfile); - assertThat(cosemObjectsWithPqProfile).hasSize(44); - - final List cosemObjectsWithPqProfileWithWrongValue = - this.objectConfigService.getCosemObjectsWithProperty( - protocolName, - protocolVersion50, - ObjectProperty.PQ_PROFILE, - Collections.singletonList("INVALID")); - - assertNotNull(cosemObjectsWithPqProfileWithWrongValue); - assertThat(cosemObjectsWithPqProfileWithWrongValue).isEmpty(); + void getOptionalCosemObject() throws ObjectConfigException { + assertThat( + this.objectConfigService.getOptionalCosemObject( + "DSMR", "4.2.2", DlmsObjectType.POWER_QUALITY_PROFILE_1)) + .isEmpty(); + + assertThat( + this.objectConfigService.getOptionalCosemObject( + "SMR", "5.0.0", DlmsObjectType.POWER_QUALITY_PROFILE_1)) + .isPresent(); } @Test void testGetCosemObjectsWithPropertiesWithMultipleAllowedValues() throws ObjectConfigException { final String protocolName = "SMR"; - final String protocolVersion50 = "5.0"; + final String protocolVersion50 = "5.0.0"; - final Map> requestMap = new HashMap<>(); - final List wantedValues = new ArrayList<>(); + final Map> requestMap = new HashMap<>(); + final List wantedValues = new ArrayList<>(); wantedValues.add("PRIVATE"); wantedValues.add("PUBLIC"); requestMap.put(ObjectProperty.PQ_PROFILE, wantedValues); @@ -149,27 +314,27 @@ void testGetCosemObjectsWithPropertiesWithMultipleAllowedValues() throws ObjectC protocolName, protocolVersion50, requestMap); assertNotNull(cosemObjectsWithSelectableObjects); - assertThat(cosemObjectsWithSelectableObjects).hasSize(44); + assertThat(cosemObjectsWithSelectableObjects).hasSize(45); } @Test void testGetCosemObjectsWithPropertiesWithMultipleProperties() throws ObjectConfigException { final String protocolName = "SMR"; - final String protocolVersion50 = "5.0"; + final String protocolVersion50 = "5.0.0"; - final Map> requestMap = new HashMap<>(); - final List wantedValuesPqProfile = new ArrayList<>(); + final Map> requestMap = new HashMap<>(); + final List wantedValuesPqProfile = new ArrayList<>(); wantedValuesPqProfile.add("PUBLIC"); requestMap.put(ObjectProperty.PQ_PROFILE, wantedValuesPqProfile); - final List wantedValuesPqRequest = new ArrayList<>(); - wantedValuesPqRequest.add("PERIODIC"); + final List wantedValuesPqRequest = new ArrayList<>(); + wantedValuesPqRequest.add("PERIODIC_SP"); requestMap.put(ObjectProperty.PQ_REQUEST, wantedValuesPqRequest); final List cosemObjectsWithSelectableObjects = this.objectConfigService.getCosemObjectsWithProperties( protocolName, protocolVersion50, requestMap); assertNotNull(cosemObjectsWithSelectableObjects); - assertThat(cosemObjectsWithSelectableObjects).hasSize(4); + assertThat(cosemObjectsWithSelectableObjects).hasSize(9); } @Test @@ -178,21 +343,193 @@ void getListOfDlmsProfiles() { assertNotNull(this.objectConfigService.getConfiguredDlmsProfiles()); } - private List getDlmsProfileList() throws IOException { - final List DlmsProfileList = new ArrayList<>(); + @Test + void testGetCaptureObjectDefinitions() { + final Attribute captureObjectsAttribute = + this.createAttribute( + this.PROFILE_GENERIC_CAPTURE_OBJECTS_ATTR_ID, "CLOCK,10|AMR_PROFILE_STATUS,11"); + final CosemObject profile = + this.createCosemObject(this.PROFILE_GENERIC_CLASS_ID, List.of(captureObjectsAttribute)); + + final List captureObjectDefinitions = getCaptureObjectDefinitions(profile); + + assertThat(captureObjectDefinitions).hasSize(2); + final String clockDef = captureObjectDefinitions.get(0); + assertThat(clockDef).isEqualTo("CLOCK,10"); + assertThat(getCosemObjectTypeFromCaptureObjectDefinition(clockDef)) + .isEqualTo(DlmsObjectType.CLOCK); + assertThat(getAttributeIdFromCaptureObjectDefinition(clockDef)).isEqualTo(10); + final String statusDef = captureObjectDefinitions.get(1); + assertThat(statusDef).isEqualTo("AMR_PROFILE_STATUS,11"); + assertThat(getCosemObjectTypeFromCaptureObjectDefinition(statusDef)) + .isEqualTo(DlmsObjectType.AMR_PROFILE_STATUS); + assertThat(getAttributeIdFromCaptureObjectDefinition(statusDef)).isEqualTo(11); + } + + @Test + void testGetCaptureObjectDefinitionsEmpty() { + final Attribute captureObjectsAttribute = + this.createAttribute(this.PROFILE_GENERIC_CAPTURE_OBJECTS_ATTR_ID, null); + final CosemObject profile = + this.createCosemObject(this.PROFILE_GENERIC_CLASS_ID, List.of(captureObjectsAttribute)); + + final List captureObjectDefinitions = getCaptureObjectDefinitions(profile); + + assertThat(captureObjectDefinitions).isEmpty(); + } + + @Test + void testGetCaptureObjectDefinitionsWrongClassId() { + final CosemObject profile = this.createCosemObject(5, List.of()); - DlmsProfileList.add(this.loadProfile("/dlmsprofiles/dlmsprofile-dsmr422.json")); - DlmsProfileList.add(this.loadProfile("/dlmsprofiles/dlmsprofile-smr43.json")); - DlmsProfileList.add(this.loadProfile("/dlmsprofiles/dlmsprofile-smr50.json")); - DlmsProfileList.add(this.loadProfile("/dlmsprofiles/dlmsprofile-smr51.json")); - DlmsProfileList.add(this.loadProfile("/dlmsprofiles/dlmsprofile-smr52.json")); - DlmsProfileList.add(this.loadProfile("/dlmsprofiles/dlmsprofile-smr55.json")); - return DlmsProfileList; + assertThrows(IllegalArgumentException.class, () -> getCaptureObjectDefinitions(profile)); } - private DlmsProfile loadProfile(final String profileJsonFile) throws IOException { + @Test + void testGetCaptureObjects() throws ObjectConfigException { + final Attribute captureObjectsAttribute = + this.createAttribute( + this.PROFILE_GENERIC_CAPTURE_OBJECTS_ATTR_ID, "CLOCK,10|AMR_PROFILE_STATUS,11"); + final CosemObject profile = + this.createCosemObject(this.PROFILE_GENERIC_CLASS_ID, List.of(captureObjectsAttribute)); + + final List captureObjectDefinitions = + this.objectConfigService.getCaptureObjects(profile, "DSMR", "4.2.2", "DeviceModel"); + + assertThat(captureObjectDefinitions).hasSize(2); + final CaptureObject clock = captureObjectDefinitions.get(0); + assertThat(clock.getCosemObject().getTag()).isEqualTo(DlmsObjectType.CLOCK.name()); + assertThat(clock.getAttributeId()).isEqualTo(10); + final CaptureObject status = captureObjectDefinitions.get(1); + assertThat(status.getCosemObject().getTag()) + .isEqualTo(DlmsObjectType.AMR_PROFILE_STATUS.name()); + assertThat(status.getAttributeId()).isEqualTo(11); + } + + @Test + void HandleValueBasedOnModel() throws ObjectConfigException { + final ValueBasedOnModel valueBasedOnModel = + new ValueBasedOnModel( + "GAS_METER_TYPE", + List.of( + new TypeBasedValue(List.of("G4-G6"), "-3, M3"), + new TypeBasedValue(List.of("G10-G25"), "-2, M3)"))); + final Attribute attribute = + this.createAttribute( + this.REGISTER_SCALER_UNIT_ATTR_ID, null, ValueType.BASED_ON_MODEL, valueBasedOnModel); + final CosemObject origObject = + this.createCosemObject(this.REGISTER_CLASS_ID, List.of(attribute)); + + // When the device model can be matched, then the value should be replaced with the value for + // this model. The valuetype should be set to FIXED_IN_METER. + final CosemObject handledObject1 = + this.objectConfigService.handleValueBasedOnModel(origObject, "DeviceModelG4"); + this.verifyHandledObject(handledObject1, origObject, "-3, M3", ValueType.FIXED_IN_METER); + + // When the device model cannot be matched, then the value should be set to null. The valuetype + // should be set to DYNAMIC to indicate that the value should be read from the meter. + final CosemObject handledObject2 = + this.objectConfigService.handleValueBasedOnModel(origObject, "UnknownDeviceModel"); + this.verifyHandledObject(handledObject2, origObject, null, ValueType.DYNAMIC); + } + + private void verifyHandledObject( + final CosemObject handledObject, + final CosemObject originalObject, + final String expectedValue, + final ValueType expectedValuetype) { + assertThat(handledObject) + .usingRecursiveComparison() + .ignoringFields("attributes") + .isEqualTo(originalObject); + final Attribute handledAttribute = + handledObject.getAttribute(this.REGISTER_SCALER_UNIT_ATTR_ID); + assertThat(handledAttribute) + .usingRecursiveComparison() + .ignoringFields("value", "valuetype") + .isEqualTo(originalObject.getAttribute(this.REGISTER_SCALER_UNIT_ATTR_ID)); + assertThat(handledAttribute.getValue()).isEqualTo(expectedValue); + assertThat(handledAttribute.getValuetype()).isEqualTo(expectedValuetype); + } + + private void assertAllInConfig( + final Protocol protocol, + final DlmsObjectType dlmsObjectType, + final boolean shouldHaveObjectType) + throws ObjectConfigException { + + final Optional optionalProfile = + this.objectConfigService.getOptionalCosemObject( + protocol.getName(), protocol.getVersion(), dlmsObjectType); + if (!shouldHaveObjectType) { + assertThat(optionalProfile).isEmpty(); + } else { + assertThat(optionalProfile).isPresent(); + + final List selectableObjects = + optionalProfile.orElseThrow().getListProperty(ObjectProperty.SELECTABLE_OBJECTS); + + final Map cosemObjects = + this.objectConfigService.getCosemObjects(protocol.getName(), protocol.getVersion()); + + // All selectable objects must be in config + selectableObjects.forEach( + selectableObject -> + assertThat(cosemObjects.get(DlmsObjectType.valueOf(selectableObject))).isNotNull()); + } + } + + private void assertAllPqPeriodicObjectsInProfiles( + final Protocol protocol, final List pqProfiles) throws ObjectConfigException { + final List allSelectableObjects = new ArrayList<>(); + for (final DlmsObjectType pqProfile : pqProfiles) { + final CosemObject cosemObjectProfile = + this.objectConfigService.getCosemObject( + protocol.getName(), protocol.getVersion(), pqProfile); + allSelectableObjects.addAll( + cosemObjectProfile.getListProperty(ObjectProperty.SELECTABLE_OBJECTS)); + } + + final Map pqObjects = + this.objectConfigService.getCosemObjects(protocol.getName(), protocol.getVersion()); + pqObjects.forEach( + (dlmsObjectType, pqObject) -> { + if (isPeriodicRequest(pqObject)) { + assertThat(allSelectableObjects).contains(pqObject.getTag()); + } + }); + } + + private static boolean isPeriodicRequest(final CosemObject object) { + return object.getProperty(ObjectProperty.PQ_REQUEST) != null + && (object.getProperty(ObjectProperty.PQ_REQUEST).equals(PowerQualityRequest.PERIODIC_SP) + || object + .getProperty(ObjectProperty.PQ_REQUEST) + .equals(PowerQualityRequest.PERIODIC_PP)); + } + + private Attribute createAttribute(final int id, final String value) { + return this.createAttribute(id, value, ValueType.DYNAMIC, null); + } + + private Attribute createAttribute( + final int id, + final String value, + final ValueType valueType, + final ValueBasedOnModel valueBasedOnModel) { + return new Attribute( + id, + "descr", + null, + DlmsDataType.DONT_CARE, + valueType, + value, + valueBasedOnModel, + AccessType.RW); + } - return this.objectMapper.readValue( - new ClassPathResource(profileJsonFile).getFile(), DlmsProfile.class); + private CosemObject createCosemObject(final int classId, final List attributes) { + return new CosemObject( + "TAG", "descr", classId, 0, "1.2.3", "group", null, List.of(), null, attributes); } } diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/test/java/org/opensmartgridplatform/dlms/services/Profile.java b/osgp/protocol-adapter-dlms/osgp-dlms/src/test/java/org/opensmartgridplatform/dlms/services/Profile.java new file mode 100644 index 00000000000..bf6ae9da773 --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/test/java/org/opensmartgridplatform/dlms/services/Profile.java @@ -0,0 +1,12 @@ +/* + * SPDX-FileCopyrightText: Copyright Contributors to the GXF project + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.opensmartgridplatform.dlms.services; + +public enum Profile { + PUBLIC, + PRIVATE +} diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/test/java/org/opensmartgridplatform/dlms/services/Protocol.java b/osgp/protocol-adapter-dlms/osgp-dlms/src/test/java/org/opensmartgridplatform/dlms/services/Protocol.java new file mode 100644 index 00000000000..e121294b998 --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/test/java/org/opensmartgridplatform/dlms/services/Protocol.java @@ -0,0 +1,97 @@ +/* + * SPDX-FileCopyrightText: Copyright Contributors to the GXF project + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.opensmartgridplatform.dlms.services; + +import lombok.Getter; +import org.opensmartgridplatform.dlms.objectconfig.PowerQualityRequest; + +@Getter +public enum Protocol { + DSMR_2_2("DSMR", "2.2", 32, 2, 4, 6, 14, 0, 0, 0, 0, false, false), + DSMR_4_2_2("DSMR", "4.2.2", 58, 11, 27, 6, 14, 6, 13, 5, 6, true, false), + SMR_4_3("SMR", "4.3", 59, 11, 27, 6, 14, 6, 13, 6, 7, true, false), + SMR_5_0_0("SMR", "5.0.0", 62, 11, 27, 6, 14, 6, 15, 9, 14, true, true), + SMR_5_1("SMR", "5.1", 64, 11, 27, 6, 14, 6, 15, 9, 14, true, true), + SMR_5_2("SMR", "5.2", 67, 11, 27, 6, 14, 6, 15, 10, 15, true, true), + SMR_5_5("SMR", "5.5", 71, 11, 27, 6, 14, 6, 15, 10, 15, true, true); + + private final String name; + private final String version; + private final int nrOfCosemObjects; + private final int nrOfCosemObjectsPqOnActualSpPrivate; + private final int nrOfCosemObjectsPqOnActualPpPrivate; + private final int nrOfCosemObjectsPqOnActualSpPublic; + private final int nrOfCosemObjectsPqOnActualPpPublic; + private final int nrOfCosemObjectsPqPeriodicSpPrivate; + private final int nrOfCosemObjectsPqPeriodicPpPrivate; + private final int nrOfCosemObjectsPqPeriodicSpPublic; + private final int nrOfCosemObjectsPqPeriodicPpPublic; + private final boolean hasDefinableLoadProfile; + private final boolean hasPqProfiles; + + Protocol( + final String name, + final String version, + final int nrOfCosemObjects, + final int nrOfCosemObjectsPqOnActualSpPrivate, + final int nrOfCosemObjectsPqOnActualPpPrivate, + final int nrOfCosemObjectsPqOnActualSpPublic, + final int nrOfCosemObjectsPqOnActualPpPublic, + final int nrOfCosemObjectsPqPeriodicSpPrivate, + final int nrOfCosemObjectsPqPeriodicPpPrivate, + final int nrOfCosemObjectsPqPeriodicSpPublic, + final int nrOfCosemObjectsPqPeriodicPpPublic, + final boolean hasDefinableLoadProfile, + final boolean hasPqProfiles) { + this.name = name; + this.version = version; + this.nrOfCosemObjects = nrOfCosemObjects; + this.nrOfCosemObjectsPqOnActualSpPublic = nrOfCosemObjectsPqOnActualSpPublic; + this.nrOfCosemObjectsPqOnActualPpPublic = nrOfCosemObjectsPqOnActualPpPublic; + this.nrOfCosemObjectsPqOnActualSpPrivate = nrOfCosemObjectsPqOnActualSpPrivate; + this.nrOfCosemObjectsPqOnActualPpPrivate = nrOfCosemObjectsPqOnActualPpPrivate; + this.nrOfCosemObjectsPqPeriodicSpPublic = nrOfCosemObjectsPqPeriodicSpPublic; + this.nrOfCosemObjectsPqPeriodicPpPublic = nrOfCosemObjectsPqPeriodicPpPublic; + this.nrOfCosemObjectsPqPeriodicSpPrivate = nrOfCosemObjectsPqPeriodicSpPrivate; + this.nrOfCosemObjectsPqPeriodicPpPrivate = nrOfCosemObjectsPqPeriodicPpPrivate; + this.hasDefinableLoadProfile = hasDefinableLoadProfile; + this.hasPqProfiles = hasPqProfiles; + } + + public int getNrOfCosemObjects(final PowerQualityRequest pqRequest, final Profile profile) { + if (PowerQualityRequest.ACTUAL_SP.equals(pqRequest) && Profile.PUBLIC.equals(profile)) { + return this.nrOfCosemObjectsPqOnActualSpPublic; + } else if (PowerQualityRequest.ACTUAL_PP.equals(pqRequest) && Profile.PUBLIC.equals(profile)) { + return this.nrOfCosemObjectsPqOnActualPpPublic; + } else if (PowerQualityRequest.ACTUAL_SP.equals(pqRequest) && Profile.PRIVATE.equals(profile)) { + return this.nrOfCosemObjectsPqOnActualSpPrivate; + } else if (PowerQualityRequest.ACTUAL_PP.equals(pqRequest) && Profile.PRIVATE.equals(profile)) { + return this.nrOfCosemObjectsPqOnActualPpPrivate; + } else if (PowerQualityRequest.PERIODIC_SP.equals(pqRequest) + && Profile.PUBLIC.equals(profile)) { + return this.nrOfCosemObjectsPqPeriodicSpPublic; + } else if (PowerQualityRequest.PERIODIC_PP.equals(pqRequest) + && Profile.PUBLIC.equals(profile)) { + return this.nrOfCosemObjectsPqPeriodicPpPublic; + } else if (PowerQualityRequest.PERIODIC_SP.equals(pqRequest) + && Profile.PRIVATE.equals(profile)) { + return this.nrOfCosemObjectsPqPeriodicSpPrivate; + } else if (PowerQualityRequest.PERIODIC_PP.equals(pqRequest) + && Profile.PRIVATE.equals(profile)) { + return this.nrOfCosemObjectsPqPeriodicPpPrivate; + } + throw new IllegalArgumentException("Unknown combination"); + } + + public boolean hasDefinableLoadProfile() { + return this.hasDefinableLoadProfile; + } + + public boolean hasPqProfiles() { + return this.hasPqProfiles; + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/test/resources/dlmsprofile-smr50-PQProfileErrors.json b/osgp/protocol-adapter-dlms/osgp-dlms/src/test/resources/dlmsprofile-smr50-PQProfileErrors.json index d92f94be2fd..72ff08de42d 100644 --- a/osgp/protocol-adapter-dlms/osgp-dlms/src/test/resources/dlmsprofile-smr50-PQProfileErrors.json +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/test/resources/dlmsprofile-smr50-PQProfileErrors.json @@ -61,7 +61,6 @@ "description": "buffer", "datatype": "array", "valuetype": "DYNAMIC", - "value": "EMPTY", "access": "R" }, { @@ -69,7 +68,6 @@ "description": "capture objects", "datatype": "array", "valuetype": "SET_BY_CLIENT", - "value": "EMPTY", "access": "RW" }, { @@ -136,7 +134,6 @@ "description": "buffer", "datatype": "array", "valuetype": "DYNAMIC", - "value": "EMPTY", "access": "R" }, { @@ -144,7 +141,6 @@ "description": "capture objects", "datatype": "array", "valuetype": "SET_BY_CLIENT", - "value": "EMPTY", "access": "RW" }, { @@ -203,7 +199,6 @@ "description": "buffer", "datatype": "array", "valuetype": "DYNAMIC", - "value": "EMPTY", "access": "R" }, { @@ -211,7 +206,6 @@ "description": "capture objects", "datatype": "array", "valuetype": "SET_BY_CLIENT", - "value": "EMPTY", "access": "RW" }, { @@ -292,7 +286,8 @@ "group": "ELECTRICITY", "meterTypes": ["PP"], "properties": { - "PQ_PROFILE": "PRIVATE" + "PQ_PROFILE": "PRIVATE", + "PQ_REQUEST": [] }, "attributes": [ { @@ -322,7 +317,8 @@ "group": "ELECTRICITY", "meterTypes": ["PP"], "properties": { - "PQ_PROFILE": "PRIVATE" + "PQ_PROFILE": "PRIVATE", + "PQ_REQUEST": [] }, "attributes": [ { @@ -352,7 +348,8 @@ "group": "ELECTRICITY", "meterTypes": ["SP","PP"], "properties": { - "PQ_PROFILE": "PUBLIC" + "PQ_PROFILE": "PUBLIC", + "PQ_REQUEST": [] }, "attributes": [ { @@ -382,7 +379,8 @@ "group": "ELECTRICITY", "meterTypes": ["PP"], "properties": { - "PQ_PROFILE": "PUBLIC" + "PQ_PROFILE": "PUBLIC", + "PQ_REQUEST": [] }, "attributes": [ { @@ -412,7 +410,8 @@ "group": "ELECTRICITY", "meterTypes": ["PP"], "properties": { - "PQ_PROFILE": "PUBLIC" + "PQ_PROFILE": "PUBLIC", + "PQ_REQUEST": [] }, "attributes": [ { @@ -442,7 +441,8 @@ "group": "ELECTRICITY", "meterTypes": ["SP","PP"], "properties": { - "PQ_PROFILE": "PUBLIC" + "PQ_PROFILE": "PUBLIC", + "PQ_REQUEST": [] }, "attributes": [ { @@ -464,7 +464,8 @@ "group": "ELECTRICITY", "meterTypes": ["PP"], "properties": { - "PQ_PROFILE": "PUBLIC" + "PQ_PROFILE": "PUBLIC", + "PQ_REQUEST": [] }, "attributes": [ { @@ -486,7 +487,8 @@ "group": "ELECTRICITY", "meterTypes": ["PP"], "properties": { - "PQ_PROFILE": "PUBLIC" + "PQ_PROFILE": "PUBLIC", + "PQ_REQUEST": [] }, "attributes": [ { diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-dsmr22.json b/osgp/protocol-adapter-dlms/osgp-dlms/src/test/resources/dlmsprofile-smr50-missingCaptureObject.json similarity index 55% rename from osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-dsmr22.json rename to osgp/protocol-adapter-dlms/osgp-dlms/src/test/resources/dlmsprofile-smr50-missingCaptureObject.json index 2f702aff699..0d3d2a48f81 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-dsmr22.json +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/test/resources/dlmsprofile-smr50-missingCaptureObject.json @@ -1,7 +1,7 @@ { - "profile": "DSMR", - "version": "2.2", - "description": "Profile for Smart Meter Requirements 2.2", + "profile": "SMR", + "version": "5.0.0", + "description": "Profile for Smart Meter Requirements 5.0.0", "properties": [], "objects": [ { @@ -40,200 +40,235 @@ ] }, { - "tag": "NUMBER_OF_VOLTAGE_SWELLS_FOR_L1", - "description": "Number of voltage swells in phase L1", - "class-id": 1, - "version": 0, - "obis": "1.0.32.36.0.255", + "tag": "DEFINABLE_LOAD_PROFILE", + "description": "Definable load profile", + "class-id": 7, + "version": 1, + "obis": "0.1.94.31.6.255", "group": "ELECTRICITY", "meterTypes": ["SP","PP"], "properties": { - "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "ONDEMAND" + "SELECTABLE_OBJECTS": [ + "CLOCK", + "NUMBER_OF_VOLTAGE_SAGS_FOR_L1", + "NUMBER_OF_VOLTAGE_SAGS_FOR_L2", + "NUMBER_OF_VOLTAGE_SAGS_FOR_L3" + ] }, "attributes": [ { "id": 2, - "description": "value", - "datatype": "long-unsigned", + "description": "buffer", + "datatype": "array", "valuetype": "DYNAMIC", - "value": "0", "access": "R" - } - ] - }, - { - "tag": "NUMBER_OF_VOLTAGE_SWELLS_FOR_L2", - "description": "Number of voltage swells in phase L2", - "class-id": 1, - "version": 0, - "obis": "1.0.52.36.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "ONDEMAND" - }, - "attributes": [ + }, { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", + "id": 3, + "description": "capture objects", + "datatype": "array", + "valuetype": "SET_BY_CLIENT", + "access": "RW" + }, + { + "id": 4, + "description": "capture period in sec", + "datatype": "double-long-unsigned", + "valuetype": "SET_BY_CLIENT", + "value": "86400", + "access": "RW" + }, + { + "id": 5, + "description": "sort method", + "datatype": "enum", + "valuetype": "FIXED_IN_METER", + "value": "1", "access": "R" - } - ] - }, - { - "tag": "NUMBER_OF_VOLTAGE_SWELLS_FOR_L3", - "description": "Number of voltage swells in phase L3", - "class-id": 1, - "version": 0, - "obis": "1.0.72.36.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "ONDEMAND" - }, - "attributes": [ + }, { - "id": 2, - "description": "value", - "datatype": "long-unsigned", + "id": 6, + "description": "sort object", + "datatype": "object_definition", + "valuetype": "FIXED_IN_METER", + "value": "NONE", + "access": "R" + }, + { + "id": 7, + "description": "entries in use", + "datatype": "double-long-unsigned", "valuetype": "DYNAMIC", "value": "0", "access": "R" + }, + { + "id": 8, + "description": "profile entries", + "datatype": "double-long-unsigned", + "valuetype": "SET_BY_CLIENT", + "value": "960", + "access": "RW" } ] }, { - "tag": "NUMBER_OF_VOLTAGE_SAGS_FOR_L1", - "description": "Number of voltage sags in phase L1", - "class-id": 1, - "version": 0, - "obis": "1.0.32.32.0.255", + "tag": "POWER_QUALITY_PROFILE_1", + "description": "Power Quality profile 1, 15 min power quality values", + "class-id": 7, + "version": 1, + "obis": "0.1.99.1.1.255", "group": "ELECTRICITY", "meterTypes": ["SP","PP"], "properties": { - "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "ONDEMAND" + "SELECTABLE_OBJECTS": [ + "CLOCK", + "AVERAGE_ACTIVE_POWER_IMPORT_L1", + "AVERAGE_ACTIVE_POWER_IMPORT_L2", + "AVERAGE_ACTIVE_POWER_IMPORT_L3" + ] }, "attributes": [ { "id": 2, - "description": "value", - "datatype": "long-unsigned", + "description": "buffer", + "datatype": "array", "valuetype": "DYNAMIC", - "value": "0", "access": "R" - } - ] - }, - { - "tag": "NUMBER_OF_VOLTAGE_SAGS_FOR_L2", - "description": "Number of voltage sags in phase L2", - "class-id": 1, - "version": 0, - "obis": "1.0.52.32.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "ONDEMAND" - }, - "attributes": [ + }, { - "id": 2, - "description": "value", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", + "id": 3, + "description": "capture objects", + "datatype": "array", + "valuetype": "SET_BY_CLIENT", + "access": "RW" + }, + { + "id": 4, + "description": "capture period in sec", + "datatype": "double-long-unsigned", + "valuetype": "FIXED_IN_PROFILE", + "value": "900", "access": "R" - } - ] - }, - { - "tag": "NUMBER_OF_VOLTAGE_SAGS_FOR_L3", - "description": "Number of voltage sags in phase L3", - "class-id": 1, - "version": 0, - "obis": "1.0.72.32.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "ONDEMAND" - }, - "attributes": [ + }, { - "id": 2, - "description": "value", - "datatype": "long-unsigned", + "id": 5, + "description": "sort method", + "datatype": "enum", + "valuetype": "FIXED_IN_PROFILE", + "value": "1", + "access": "R" + }, + { + "id": 6, + "description": "sort object", + "datatype": "object_definition", + "valuetype": "FIXED_IN_METER", + "value": "NONE", + "access": "R" + }, + { + "id": 7, + "description": "entries in use", + "datatype": "double-long-unsigned", "valuetype": "DYNAMIC", "value": "0", "access": "R" + }, + { + "id": 8, + "description": "profile entries", + "datatype": "double-long-unsigned", + "valuetype": "FIXED_IN_PROFILE", + "value": "960", + "access": "R" } ] }, { - "tag": "NUMBER_OF_LONG_POWER_FAILURES", - "description": "Number of long power failures in any phases", - "class-id": 1, - "version": 0, - "obis": "0.0.96.7.9.255", + "tag": "POWER_QUALITY_PROFILE_2", + "description": "Power Quality profile 2, 10 min power quality values", + "class-id": 7, + "version": 1, + "obis": "0.1.99.1.2.255", "group": "ELECTRICITY", "meterTypes": ["SP","PP"], "properties": { - "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "ONDEMAND" + "SELECTABLE_OBJECTS": [ + "CLOCK", + "AVERAGE_VOLTAGE_L1", + "AVERAGE_VOLTAGE_L2", + "AVERAGE_VOLTAGE_L3" + ] }, "attributes": [ { "id": 2, - "description": "value", - "datatype": "long-unsigned", + "description": "buffer", + "datatype": "array", "valuetype": "DYNAMIC", - "value": "0", "access": "R" - } - ] - }, - { - "tag": "NUMBER_OF_POWER_FAILURES", - "description": "Number of power failures in any phases", - "class-id": 1, - "version": 0, - "obis": "0.0.96.7.21.255", - "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "ONDEMAND" - }, - "attributes": [ + }, { - "id": 2, - "description": "value", - "datatype": "long-unsigned", + "id": 3, + "description": "capture objects", + "datatype": "array", + "valuetype": "SET_BY_CLIENT", + "access": "RW" + }, + { + "id": 4, + "description": "capture period in sec", + "datatype": "double-long-unsigned", + "valuetype": "FIXED_IN_PROFILE", + "value": "600", + "access": "R" + }, + { + "id": 5, + "description": "sort method", + "datatype": "enum", + "valuetype": "FIXED_IN_PROFILE", + "value": "1", + "access": "R" + }, + { + "id": 6, + "description": "sort object", + "datatype": "object_definition", + "valuetype": "FIXED_IN_METER", + "value": "NONE", + "access": "R" + }, + { + "id": 7, + "description": "entries in use", + "datatype": "double-long-unsigned", "valuetype": "DYNAMIC", "value": "0", "access": "R" + }, + { + "id": 8, + "description": "profile entries", + "datatype": "double-long-unsigned", + "valuetype": "FIXED_IN_PROFILE", + "value": "1440", + "access": "R" } ] }, { - "tag": "INSTANTANEOUS_VOLTAGE_L1", - "description": "Instantaneous voltage L1", + "tag": "AVERAGE_ACTIVE_POWER_IMPORT_L1", + "description": "Average active power (+P) L1", "class-id": 3, "version": 0, - "obis": "1.0.32.7.0.255", + "obis": "1.0.21.4.0.255", "group": "ELECTRICITY", "meterTypes": ["SP","PP"], "properties": { - "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "ONDEMAND" + "PQ_PROFILE": "PRIVATE", + "PQ_REQUEST": [] }, "attributes": [ { @@ -249,22 +284,22 @@ "description": "scaler_unit", "datatype": "scal_unit_type", "valuetype": "FIXED_IN_PROFILE", - "value": "0, V", - "access": "RW" + "value": "0, W", + "access": "R" } ] }, { - "tag": "INSTANTANEOUS_VOLTAGE_L2", - "description": "Instantaneous voltage L2", + "tag": "AVERAGE_ACTIVE_POWER_IMPORT_L2", + "description": "Average active power (+P) L2", "class-id": 3, "version": 0, - "obis": "1.0.52.7.0.255", + "obis": "1.0.41.4.0.255", "group": "ELECTRICITY", "meterTypes": ["PP"], "properties": { - "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "ONDEMAND" + "PQ_PROFILE": "PRIVATE", + "PQ_REQUEST": [] }, "attributes": [ { @@ -280,22 +315,22 @@ "description": "scaler_unit", "datatype": "scal_unit_type", "valuetype": "FIXED_IN_PROFILE", - "value": "0, V", - "access": "RW" + "value": "0, W", + "access": "R" } ] }, { - "tag": "INSTANTANEOUS_VOLTAGE_L3", - "description": "Instantaneous voltage L3", + "tag": "AVERAGE_ACTIVE_POWER_IMPORT_L3", + "description": "Average active power (+P) L3", "class-id": 3, "version": 0, - "obis": "1.0.72.7.0.255", + "obis": "1.0.61.4.0.255", "group": "ELECTRICITY", "meterTypes": ["PP"], "properties": { - "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "ONDEMAND" + "PQ_PROFILE": "PRIVATE", + "PQ_REQUEST": [] }, "attributes": [ { @@ -311,8 +346,8 @@ "description": "scaler_unit", "datatype": "scal_unit_type", "valuetype": "FIXED_IN_PROFILE", - "value": "0, V", - "access": "RW" + "value": "0, W", + "access": "R" } ] }, @@ -326,7 +361,7 @@ "meterTypes": ["SP","PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "ONDEMAND" + "PQ_REQUEST": [] }, "attributes": [ { @@ -342,7 +377,7 @@ "description": "scaler_unit", "datatype": "scal_unit_type", "valuetype": "FIXED_IN_PROFILE", - "value": "0, V", + "value": "-1, V", "access": "R" } ] @@ -357,7 +392,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "ONDEMAND" + "PQ_REQUEST": [] }, "attributes": [ { @@ -373,7 +408,7 @@ "description": "scaler_unit", "datatype": "scal_unit_type", "valuetype": "FIXED_IN_PROFILE", - "value": "0, V", + "value": "-1, V", "access": "R" } ] @@ -388,7 +423,7 @@ "meterTypes": ["PP"], "properties": { "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "ONDEMAND" + "PQ_REQUEST": [] }, "attributes": [ { @@ -404,22 +439,22 @@ "description": "scaler_unit", "datatype": "scal_unit_type", "valuetype": "FIXED_IN_PROFILE", - "value": "0, V", + "value": "-1, V", "access": "R" } ] }, { - "tag": "INSTANTANEOUS_CURRENT_L1", - "description": "Instantaneous current L1", - "class-id": 3, + "tag": "NUMBER_OF_VOLTAGE_SAGS_FOR_L1", + "description": "Number of voltage sags in phase L1", + "class-id": 1, "version": 0, - "obis": "1.0.31.7.0.255", + "obis": "1.0.32.32.0.255", "group": "ELECTRICITY", "meterTypes": ["SP","PP"], "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "ONDEMAND" + "PQ_PROFILE": "PUBLIC", + "PQ_REQUEST": [] }, "attributes": [ { @@ -429,28 +464,20 @@ "valuetype": "DYNAMIC", "value": "0", "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, A", - "access": "RW" } ] }, { - "tag": "INSTANTANEOUS_CURRENT_L2", - "description": "Instantaneous current L2", - "class-id": 3, + "tag": "NUMBER_OF_VOLTAGE_SAGS_FOR_L2", + "description": "Number of voltage sags in phase L2", + "class-id": 1, "version": 0, - "obis": "1.0.51.7.0.255", + "obis": "1.0.52.32.0.255", "group": "ELECTRICITY", "meterTypes": ["PP"], "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "ONDEMAND" + "PQ_PROFILE": "PUBLIC", + "PQ_REQUEST": [] }, "attributes": [ { @@ -460,28 +487,20 @@ "valuetype": "DYNAMIC", "value": "0", "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, A", - "access": "RW" } ] }, { - "tag": "INSTANTANEOUS_CURRENT_L3", - "description": "Instantaneous current L3", - "class-id": 3, + "tag": "NUMBER_OF_VOLTAGE_SAGS_FOR_L3", + "description": "Number of voltage sags in phase L3", + "class-id": 1, "version": 0, - "obis": "1.0.71.7.0.255", + "obis": "1.0.72.32.0.255", "group": "ELECTRICITY", "meterTypes": ["PP"], "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "ONDEMAND" + "PQ_PROFILE": "PUBLIC", + "PQ_REQUEST": [] }, "attributes": [ { @@ -491,75 +510,72 @@ "valuetype": "DYNAMIC", "value": "0", "access": "R" - }, - { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", - "valuetype": "FIXED_IN_PROFILE", - "value": "0, A", - "access": "RW" } ] }, { - "tag": "INSTANTANEOUS_ACTIVE_CURRENT_TOTAL_OVER_ALL_PHASES", - "description": "Instantaneous current total", - "class-id": 3, - "version": 0, - "obis": "1.0.90.7.0.255", - "group": "ELECTRICITY", - "meterTypes": ["PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "ONDEMAND" - }, + "tag": "MONTHLY_VALUES_G", + "description": "Monthly billing values of M-Bus device", + "class-id": 7, + "version": 1, + "obis": "0.x.24.3.2.255", + "group": "GAS", + "meterTypes": ["SP","PP"], + "properties": {}, "attributes": [ { "id": 2, - "description": "value", - "datatype": "long-unsigned", + "description": "buffer", + "datatype": "array", "valuetype": "DYNAMIC", - "value": "0", "access": "R" }, { "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", + "description": "capture objects", + "datatype": "array", "valuetype": "FIXED_IN_PROFILE", - "value": "0, A", + "value": "CLOCK,2|MBUS_MASTER_VALUE,2", "access": "R" - } - ] - }, - { - "tag": "INSTANTANEOUS_ACTIVE_POWER_IMPORT", - "description": "Instantaneous active power (+P)", - "class-id": 3, - "version": 0, - "obis": "1.0.15.7.0.255", - "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PRIVATE", - "PQ_REQUEST": "ONDEMAND" - }, - "attributes": [ + }, { - "id": 2, - "description": "value", - "datatype": "long-unsigned", + "id": 4, + "description": "capture period in sec", + "datatype": "double-long-unsigned", + "valuetype": "FIXED_IN_PROFILE", + "value": "0", + "access": "R" + }, + { + "id": 5, + "description": "sort method", + "datatype": "enum", + "valuetype": "FIXED_IN_METER", + "value": "1", + "access": "R" + }, + { + "id": 6, + "description": "sort object", + "datatype": "object_definition", + "valuetype": "FIXED_IN_METER", + "value": "NONE", + "access": "R" + }, + { + "id": 7, + "description": "entries in use", + "datatype": "double-long-unsigned", "valuetype": "DYNAMIC", "value": "0", "access": "R" }, { - "id": 3, - "description": "scaler_unit", - "datatype": "scal_unit_type", + "id": 8, + "description": "profile entries", + "datatype": "double-long-unsigned", "valuetype": "FIXED_IN_PROFILE", - "value": "0, W", + "value": "13", "access": "R" } ] diff --git a/osgp/protocol-adapter-dlms/osgp-dlms/src/test/resources/dlmsprofile-smr50-missingUnit.json b/osgp/protocol-adapter-dlms/osgp-dlms/src/test/resources/dlmsprofile-smr50-missingUnit.json index 84dacf6b2c1..0b7d6b00a46 100644 --- a/osgp/protocol-adapter-dlms/osgp-dlms/src/test/resources/dlmsprofile-smr50-missingUnit.json +++ b/osgp/protocol-adapter-dlms/osgp-dlms/src/test/resources/dlmsprofile-smr50-missingUnit.json @@ -61,7 +61,6 @@ "description": "buffer", "datatype": "array", "valuetype": "DYNAMIC", - "value": "EMPTY", "access": "R" }, { @@ -69,7 +68,6 @@ "description": "capture objects", "datatype": "array", "valuetype": "SET_BY_CLIENT", - "value": "EMPTY", "access": "RW" }, { @@ -136,7 +134,6 @@ "description": "buffer", "datatype": "array", "valuetype": "DYNAMIC", - "value": "EMPTY", "access": "R" }, { @@ -144,7 +141,6 @@ "description": "capture objects", "datatype": "array", "valuetype": "SET_BY_CLIENT", - "value": "EMPTY", "access": "RW" }, { @@ -211,7 +207,6 @@ "description": "buffer", "datatype": "array", "valuetype": "DYNAMIC", - "value": "EMPTY", "access": "R" }, { @@ -219,7 +214,6 @@ "description": "capture objects", "datatype": "array", "valuetype": "SET_BY_CLIENT", - "value": "EMPTY", "access": "RW" }, { @@ -273,7 +267,8 @@ "group": "ELECTRICITY", "meterTypes": ["SP","PP"], "properties": { - "PQ_PROFILE": "PRIVATE" + "PQ_PROFILE": "PRIVATE", + "PQ_REQUEST": [] }, "attributes": [ { @@ -303,7 +298,8 @@ "group": "ELECTRICITY", "meterTypes": ["PP"], "properties": { - "PQ_PROFILE": "PRIVATE" + "PQ_PROFILE": "PRIVATE", + "PQ_REQUEST": [] }, "attributes": [ { @@ -325,7 +321,8 @@ "group": "ELECTRICITY", "meterTypes": ["PP"], "properties": { - "PQ_PROFILE": "PRIVATE" + "PQ_PROFILE": "PRIVATE", + "PQ_REQUEST": [] }, "attributes": [ { @@ -355,7 +352,8 @@ "group": "ELECTRICITY", "meterTypes": ["SP","PP"], "properties": { - "PQ_PROFILE": "PUBLIC" + "PQ_PROFILE": "PUBLIC", + "PQ_REQUEST": [] }, "attributes": [ { @@ -385,7 +383,8 @@ "group": "ELECTRICITY", "meterTypes": ["PP"], "properties": { - "PQ_PROFILE": "PUBLIC" + "PQ_PROFILE": "PUBLIC", + "PQ_REQUEST": [] }, "attributes": [ { @@ -415,7 +414,8 @@ "group": "ELECTRICITY", "meterTypes": ["PP"], "properties": { - "PQ_PROFILE": "PUBLIC" + "PQ_PROFILE": "PUBLIC", + "PQ_REQUEST": [] }, "attributes": [ { @@ -445,7 +445,8 @@ "group": "ELECTRICITY", "meterTypes": ["SP","PP"], "properties": { - "PQ_PROFILE": "PUBLIC" + "PQ_PROFILE": "PUBLIC", + "PQ_REQUEST": [] }, "attributes": [ { @@ -467,7 +468,8 @@ "group": "ELECTRICITY", "meterTypes": ["PP"], "properties": { - "PQ_PROFILE": "PUBLIC" + "PQ_PROFILE": "PUBLIC", + "PQ_REQUEST": [] }, "attributes": [ { @@ -489,7 +491,8 @@ "group": "ELECTRICITY", "meterTypes": ["PP"], "properties": { - "PQ_PROFILE": "PUBLIC" + "PQ_PROFILE": "PUBLIC", + "PQ_REQUEST": [] }, "attributes": [ { diff --git a/osgp/protocol-adapter-dlms/osgp-jasper-interface/pom.xml b/osgp/protocol-adapter-dlms/osgp-jasper-interface/pom.xml index 362580d35d9..ca7958b1b44 100644 --- a/osgp/protocol-adapter-dlms/osgp-jasper-interface/pom.xml +++ b/osgp/protocol-adapter-dlms/osgp-jasper-interface/pom.xml @@ -20,7 +20,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-pa-dlms - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-pa-dlms/pom.xml @@ -172,6 +172,15 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform shared + + org.opensmartgridplatform + osgp-jasper-shared + + + + org.postgresql + postgresql + diff --git a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/client/JasperWirelessSmsClient.java b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/client/JasperWirelessSmsClient.java index 3d78fb9c286..7085873a23b 100644 --- a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/client/JasperWirelessSmsClient.java +++ b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/client/JasperWirelessSmsClient.java @@ -4,8 +4,8 @@ package org.opensmartgridplatform.adapter.protocol.jasper.client; -import org.opensmartgridplatform.adapter.protocol.jasper.exceptions.OsgpJasperException; import org.opensmartgridplatform.adapter.protocol.jasper.response.SendSMSResponse; +import org.opensmartgridplatform.jasper.exceptions.OsgpJasperException; public interface JasperWirelessSmsClient { diff --git a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/client/JasperWirelessTerminalClient.java b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/client/JasperWirelessTerminalClient.java index b04fbcf719e..eb658fc9060 100644 --- a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/client/JasperWirelessTerminalClient.java +++ b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/client/JasperWirelessTerminalClient.java @@ -4,8 +4,8 @@ package org.opensmartgridplatform.adapter.protocol.jasper.client; -import org.opensmartgridplatform.adapter.protocol.jasper.exceptions.OsgpJasperException; import org.opensmartgridplatform.adapter.protocol.jasper.response.GetSessionInfoResponse; +import org.opensmartgridplatform.jasper.exceptions.OsgpJasperException; public interface JasperWirelessTerminalClient { diff --git a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/config/JasperWirelessConfig.java b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/config/JasperWirelessConfig.java index 25374a69645..e97ab03a5c2 100644 --- a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/config/JasperWirelessConfig.java +++ b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/config/JasperWirelessConfig.java @@ -5,17 +5,25 @@ package org.opensmartgridplatform.adapter.protocol.jasper.config; import com.fasterxml.jackson.databind.ObjectMapper; +import com.zaxxer.hikari.util.DriverDataSource; import java.text.SimpleDateFormat; +import java.util.Properties; import javax.xml.soap.MessageFactory; import javax.xml.soap.SOAPException; import org.opensmartgridplatform.adapter.protocol.jasper.client.JasperWirelessSmsClient; import org.opensmartgridplatform.adapter.protocol.jasper.client.JasperWirelessTerminalClient; -import org.opensmartgridplatform.adapter.protocol.jasper.exceptions.OsgpJasperException; import org.opensmartgridplatform.adapter.protocol.jasper.infra.ws.CorrelationIdProviderService; import org.opensmartgridplatform.adapter.protocol.jasper.infra.ws.JasperWirelessSmsSoapClient; import org.opensmartgridplatform.adapter.protocol.jasper.infra.ws.JasperWirelessTerminalSoapClient; import org.opensmartgridplatform.adapter.protocol.jasper.rest.client.JasperWirelessSmsRestClient; import org.opensmartgridplatform.adapter.protocol.jasper.rest.client.JasperWirelessTerminalRestClient; +import org.opensmartgridplatform.adapter.protocol.jasper.service.DeviceSessionService; +import org.opensmartgridplatform.adapter.protocol.jasper.sessionproviders.SessionProvider; +import org.opensmartgridplatform.adapter.protocol.jasper.sessionproviders.SessionProviderKpnPollJasper; +import org.opensmartgridplatform.adapter.protocol.jasper.sessionproviders.SessionProviderKpnPushAlarm; +import org.opensmartgridplatform.adapter.protocol.jasper.sessionproviders.SessionProviderMap; +import org.opensmartgridplatform.jasper.config.JasperWirelessAccess; +import org.opensmartgridplatform.jasper.exceptions.OsgpJasperException; import org.opensmartgridplatform.shared.application.config.AbstractConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -44,10 +52,10 @@ public class JasperWirelessConfig extends AbstractConfig { private static final Logger LOGGER = LoggerFactory.getLogger(JasperWirelessConfig.class); @Value("${jwcc.getsession.retries}") - private String retries; + private int retries; @Value("${jwcc.getsession.sleep.between.retries}") - private String sleepBetweenRetries; + private int sleepBetweenRetries; @Value("${jwcc.uri.sms}") private String uri; @@ -73,6 +81,36 @@ public class JasperWirelessConfig extends AbstractConfig { @Value("${jwcc.api.type:SOAP}") private String apiType; + @Value("${jwcc.getsession.poll.jasper:false}") + private boolean pollJasper; + + @Value("${push.alarm.max-wait-in-ms:60000}") + private int maxWaitInMs; + + @Value("${push.alarm.attempts:5}") + private int attempts; + + @Value("${db.driver}") + private String databaseDriver; + + @Value("${db.host}") + private String databaseHost; + + @Value("${db.protocol}") + private String databaseProtocol; + + @Value("${db.port}") + private int databasePort; + + @Value("${db.name}") + private String databaseName; + + @Value("${db.username}") + private String databaseUsername; + + @Value("${db.password}") + private String databasePassword; + public enum ApiType { SOAP, REST @@ -137,21 +175,11 @@ public CorrelationIdProviderService correlationIdProviderService() { return new CorrelationIdProviderService(); } - @Bean - public int jasperGetSessionRetries() { - return Integer.parseInt(this.retries); - } - @Bean public short jasperGetValidityPeriod() { return Short.parseShort(this.validityPeriod); } - @Bean - public int jasperGetSessionSleepBetweenRetries() { - return Integer.parseInt(this.sleepBetweenRetries); - } - @Bean public RestTemplate jasperWirelessRestTemplate() { @@ -191,4 +219,45 @@ public JasperWirelessTerminalClient jasperWirelessTerminalClient() { return new JasperWirelessTerminalSoapClient(); } } + + @Bean + public DeviceSessionService deviceSessionService() { + final String jdbcUrl = + String.format( + "%s%s:%s/%s", + this.databaseProtocol, this.databaseHost, this.databasePort, this.databaseName); + LOGGER.info("Created jdbcUrl {} for deviceSessionService", jdbcUrl); + final DriverDataSource dataSource = + new DriverDataSource( + jdbcUrl, + this.databaseDriver, + new Properties(), + this.databaseUsername, + this.databasePassword); + + return new DeviceSessionService(dataSource, this.maxWaitInMs); + } + + @Bean + public SessionProvider sessionProviderKpn( + final SessionProviderMap sessionProviderMap, + final JasperWirelessTerminalClient jasperWirelessTerminalClient, + final JasperWirelessSmsClient jasperWirelessSmsClient, + final DeviceSessionService deviceSessionService) { + if (this.pollJasper) { + return new SessionProviderKpnPollJasper( + sessionProviderMap, + jasperWirelessTerminalClient, + jasperWirelessSmsClient, + this.retries, + this.sleepBetweenRetries); + } else { + return new SessionProviderKpnPushAlarm( + sessionProviderMap, + jasperWirelessSmsClient, + jasperWirelessTerminalClient, + deviceSessionService, + this.attempts); + } + } } diff --git a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/infra/ws/JasperWirelessSmsSoapClient.java b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/infra/ws/JasperWirelessSmsSoapClient.java index dde80e5d9cd..a7694eb5e54 100644 --- a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/infra/ws/JasperWirelessSmsSoapClient.java +++ b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/infra/ws/JasperWirelessSmsSoapClient.java @@ -12,7 +12,7 @@ import java.util.List; import org.apache.ws.security.WSConstants; import org.opensmartgridplatform.adapter.protocol.jasper.client.JasperWirelessSmsClient; -import org.opensmartgridplatform.adapter.protocol.jasper.config.JasperWirelessAccess; +import org.opensmartgridplatform.jasper.config.JasperWirelessAccess; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.ws.client.core.WebServiceTemplate; import org.springframework.ws.client.support.interceptor.ClientInterceptor; diff --git a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/infra/ws/JasperWirelessTerminalSoapClient.java b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/infra/ws/JasperWirelessTerminalSoapClient.java index 160326698e7..dbaeda08dfe 100644 --- a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/infra/ws/JasperWirelessTerminalSoapClient.java +++ b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/infra/ws/JasperWirelessTerminalSoapClient.java @@ -11,8 +11,8 @@ import lombok.extern.slf4j.Slf4j; import org.apache.ws.security.WSConstants; import org.opensmartgridplatform.adapter.protocol.jasper.client.JasperWirelessTerminalClient; -import org.opensmartgridplatform.adapter.protocol.jasper.config.JasperWirelessAccess; -import org.opensmartgridplatform.adapter.protocol.jasper.exceptions.OsgpJasperException; +import org.opensmartgridplatform.jasper.config.JasperWirelessAccess; +import org.opensmartgridplatform.jasper.exceptions.OsgpJasperException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.ws.client.core.WebServiceTemplate; import org.springframework.ws.client.support.interceptor.ClientInterceptor; diff --git a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/rest/client/JasperWirelessSmsRestClient.java b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/rest/client/JasperWirelessSmsRestClient.java index 6a582f0b19c..47cec039110 100644 --- a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/rest/client/JasperWirelessSmsRestClient.java +++ b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/rest/client/JasperWirelessSmsRestClient.java @@ -5,10 +5,11 @@ package org.opensmartgridplatform.adapter.protocol.jasper.rest.client; import org.opensmartgridplatform.adapter.protocol.jasper.client.JasperWirelessSmsClient; -import org.opensmartgridplatform.adapter.protocol.jasper.config.JasperWirelessAccess; -import org.opensmartgridplatform.adapter.protocol.jasper.exceptions.OsgpJasperException; import org.opensmartgridplatform.adapter.protocol.jasper.rest.json.SendSMSRequest; import org.opensmartgridplatform.adapter.protocol.jasper.rest.json.SendSMSResponse; +import org.opensmartgridplatform.jasper.client.JasperWirelessRestClient; +import org.opensmartgridplatform.jasper.config.JasperWirelessAccess; +import org.opensmartgridplatform.jasper.exceptions.OsgpJasperException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; diff --git a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/rest/client/JasperWirelessTerminalRestClient.java b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/rest/client/JasperWirelessTerminalRestClient.java index 904963210ba..c1501dbe303 100644 --- a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/rest/client/JasperWirelessTerminalRestClient.java +++ b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/rest/client/JasperWirelessTerminalRestClient.java @@ -5,9 +5,10 @@ package org.opensmartgridplatform.adapter.protocol.jasper.rest.client; import org.opensmartgridplatform.adapter.protocol.jasper.client.JasperWirelessTerminalClient; -import org.opensmartgridplatform.adapter.protocol.jasper.config.JasperWirelessAccess; -import org.opensmartgridplatform.adapter.protocol.jasper.exceptions.OsgpJasperException; import org.opensmartgridplatform.adapter.protocol.jasper.response.GetSessionInfoResponse; +import org.opensmartgridplatform.jasper.client.JasperWirelessRestClient; +import org.opensmartgridplatform.jasper.config.JasperWirelessAccess; +import org.opensmartgridplatform.jasper.exceptions.OsgpJasperException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; @@ -54,7 +55,10 @@ public GetSessionInfoResponse getSession(final String iccId) throws OsgpJasperEx this.jasperwirelessRestTemplate.exchange( url, HttpMethod.GET, entity, GetSessionInfoResponse.class); - getSessionInfoResponse = this.checkOnSessionValidity(getSessionInfoResponseEntity); + if (getSessionInfoResponseEntity.getBody() != null) { + getSessionInfoResponse = + this.checkOnSessionValidity(getSessionInfoResponseEntity.getBody()); + } } catch (final HttpClientErrorException | HttpServerErrorException e) { this.handleException(e); @@ -65,7 +69,7 @@ public GetSessionInfoResponse getSession(final String iccId) throws OsgpJasperEx } private GetSessionInfoResponse checkOnSessionValidity( - final ResponseEntity getSessionInfoResponseEntity) { + final GetSessionInfoResponse getSessionInfoResponse) { // To simulated to same behaviour as the SOAP interface. Session info of an expired session is // removed form the response. // REST-interface returns information about the current or most recent data session for a given @@ -73,7 +77,6 @@ private GetSessionInfoResponse checkOnSessionValidity( // SOAP-interface returns the current session information (IP address and session start time) // for one or more devices. If the specified device is not in session, no information is // returned. - final GetSessionInfoResponse getSessionInfoResponse = getSessionInfoResponseEntity.getBody(); if (this.hasCurrentSession(getSessionInfoResponse)) { return getSessionInfoResponse; } else { diff --git a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/service/DeviceSessionService.java b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/service/DeviceSessionService.java new file mode 100644 index 00000000000..8e27de724be --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/service/DeviceSessionService.java @@ -0,0 +1,108 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.adapter.protocol.jasper.service; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.Optional; +import javax.sql.DataSource; +import lombok.extern.slf4j.Slf4j; +import org.postgresql.PGConnection; +import org.postgresql.PGNotification; + +@Slf4j +public class DeviceSessionService { + private static final String IP_ADDRESS_CHANNEL = "ip_address"; + private final DataSource dataSource; + private final int maxWaitInMs; + + public DeviceSessionService(final DataSource dataSource, final int maxWaitInMs) { + this.dataSource = dataSource; + this.maxWaitInMs = maxWaitInMs; + } + + public Optional waitForIpAddress(final String deviceIdentification) { + String ipAddress = null; + Connection connection = null; + try { + connection = this.dataSource.getConnection(); + final PGConnection pgConnection = this.startListening(connection, deviceIdentification); + + final PGNotification[] notifications = pgConnection.getNotifications(this.maxWaitInMs); + if (notifications == null) { + log.info( + "Received no notifications for device {} within {} ms", + deviceIdentification, + this.maxWaitInMs); + return Optional.empty(); + } + + for (final PGNotification notification : notifications) { + ipAddress = notification.getParameter(); + log.info( + "Received notification with ipAddress {} for device {}", + ipAddress, + deviceIdentification); + } + } catch (final SQLException sqle) { + log.error( + "SQLException occurred while listening for notification for device: " + + deviceIdentification, + sqle); + } finally { + this.closeConnection(connection, deviceIdentification); + } + + return Optional.ofNullable(ipAddress); + } + + public void notifyIpAddress(final String deviceIdentification, final String ipAddress) { + Connection connection = null; + try { + connection = this.dataSource.getConnection(); + + final String sqlStatement = + String.format("NOTIFY %s, '%s'", this.getChannelName(deviceIdentification), ipAddress); + try (final PreparedStatement preparedStatement = connection.prepareStatement(sqlStatement)) { + preparedStatement.executeUpdate(); + } + } catch (final SQLException sqle) { + log.error("SQLException occurred while notify for device: " + deviceIdentification, sqle); + } finally { + this.closeConnection(connection, deviceIdentification); + } + } + + private PGConnection startListening( + final Connection connection, final String deviceIdentification) throws SQLException { + + final PGConnection pgConnection = connection.unwrap(PGConnection.class); + final String sqlStatement = + String.format("LISTEN %s", this.getChannelName(deviceIdentification)); + try (final PreparedStatement preparedStatement = connection.prepareStatement(sqlStatement)) { + preparedStatement.executeUpdate(); + } + + return pgConnection; + } + + private void closeConnection(final Connection connection, final String deviceIdentification) { + try { + if (connection != null) { + connection.close(); + } + } catch (final SQLException e) { + log.error( + "SQLException occurred while listening for notification for device: " + + deviceIdentification, + e); + } + } + + private String getChannelName(final String deviceIdentification) { + return IP_ADDRESS_CHANNEL + "_" + deviceIdentification; + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/sessionproviders/SessionProvider.java b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/sessionproviders/SessionProvider.java index a0f6b6f335f..18ec6963636 100644 --- a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/sessionproviders/SessionProvider.java +++ b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/sessionproviders/SessionProvider.java @@ -4,12 +4,17 @@ package org.opensmartgridplatform.adapter.protocol.jasper.sessionproviders; +import java.util.Optional; import org.opensmartgridplatform.shared.exceptionhandling.OsgpException; -import org.springframework.beans.factory.annotation.Autowired; public abstract class SessionProvider { - @Autowired protected SessionProviderMap sessionProviderMap; + protected SessionProviderMap sessionProviderMap; - public abstract String getIpAddress(String iccId) throws OsgpException; + public SessionProvider(final SessionProviderMap sessionProviderMap) { + this.sessionProviderMap = sessionProviderMap; + } + + public abstract Optional getIpAddress(String deviceIdentification, String iccId) + throws OsgpException; } diff --git a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/sessionproviders/SessionProviderKpn.java b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/sessionproviders/SessionProviderKpn.java deleted file mode 100644 index 00aa26025ea..00000000000 --- a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/sessionproviders/SessionProviderKpn.java +++ /dev/null @@ -1,77 +0,0 @@ -// SPDX-FileCopyrightText: Copyright Contributors to the GXF project -// -// SPDX-License-Identifier: Apache-2.0 - -package org.opensmartgridplatform.adapter.protocol.jasper.sessionproviders; - -import javax.annotation.PostConstruct; -import org.opensmartgridplatform.adapter.protocol.jasper.client.JasperWirelessTerminalClient; -import org.opensmartgridplatform.adapter.protocol.jasper.exceptions.OsgpJasperException; -import org.opensmartgridplatform.adapter.protocol.jasper.response.GetSessionInfoResponse; -import org.opensmartgridplatform.shared.exceptionhandling.ComponentType; -import org.opensmartgridplatform.shared.exceptionhandling.FunctionalException; -import org.opensmartgridplatform.shared.exceptionhandling.FunctionalExceptionType; -import org.opensmartgridplatform.shared.exceptionhandling.OsgpException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.stereotype.Component; - -@Component -public class SessionProviderKpn extends SessionProvider { - - private static final Logger LOGGER = LoggerFactory.getLogger(SessionProviderKpn.class); - - @Autowired private JasperWirelessTerminalClient jasperWirelessTerminalClient; - - /** - * Initialization function executed after dependency injection has finished. The SessionProvider - * Singleton is added to the HashMap of SessionProviderMap. - */ - @PostConstruct - public void init() { - this.sessionProviderMap.addProvider(SessionProviderEnum.KPN, this); - } - - @Override - public String getIpAddress(final String iccId) throws OsgpException { - GetSessionInfoResponse response = null; - try { - response = this.jasperWirelessTerminalClient.getSession(iccId); - } catch (final OsgpJasperException e) { - this.handleException(e); - } - return response.getIpAddress(); - } - - private void handleException(final OsgpJasperException e) throws FunctionalException { - String errorMessage = ""; - FunctionalExceptionType functionalExceptionType; - if (e.getJasperError() != null) { - if (e.getJasperError().getHttpStatus() == HttpStatus.NOT_FOUND) { - functionalExceptionType = FunctionalExceptionType.INVALID_ICCID; - } else { - errorMessage = - String.format( - "Session provider %s returned error %s : %s", - SessionProviderEnum.KPN.name(), - e.getJasperError().getCode(), - e.getJasperError().getMessage()); - LOGGER.error(errorMessage, e); - functionalExceptionType = FunctionalExceptionType.SESSION_PROVIDER_ERROR; - } - } else { - errorMessage = - String.format( - "Session provider %s returned unknown error message: %s", - SessionProviderEnum.KPN.name(), e.getMessage()); - LOGGER.error(errorMessage, e); - functionalExceptionType = FunctionalExceptionType.SESSION_PROVIDER_ERROR; - } - throw new FunctionalException( - functionalExceptionType, - ComponentType.PROTOCOL_DLMS, - new OsgpException(ComponentType.PROTOCOL_DLMS, e.getMessage())); - } -} diff --git a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/sessionproviders/SessionProviderKpnPollJasper.java b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/sessionproviders/SessionProviderKpnPollJasper.java new file mode 100644 index 00000000000..536f05a951a --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/sessionproviders/SessionProviderKpnPollJasper.java @@ -0,0 +1,144 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.adapter.protocol.jasper.sessionproviders; + +import java.util.Optional; +import javax.annotation.PostConstruct; +import org.opensmartgridplatform.adapter.protocol.jasper.client.JasperWirelessSmsClient; +import org.opensmartgridplatform.adapter.protocol.jasper.client.JasperWirelessTerminalClient; +import org.opensmartgridplatform.adapter.protocol.jasper.response.GetSessionInfoResponse; +import org.opensmartgridplatform.adapter.protocol.jasper.sessionproviders.exceptions.SessionProviderException; +import org.opensmartgridplatform.jasper.exceptions.OsgpJasperException; +import org.opensmartgridplatform.shared.exceptionhandling.ComponentType; +import org.opensmartgridplatform.shared.exceptionhandling.FunctionalException; +import org.opensmartgridplatform.shared.exceptionhandling.FunctionalExceptionType; +import org.opensmartgridplatform.shared.exceptionhandling.OsgpException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; + +public class SessionProviderKpnPollJasper extends SessionProvider { + + private static final Logger LOGGER = LoggerFactory.getLogger(SessionProviderKpnPollJasper.class); + + private final JasperWirelessTerminalClient jasperWirelessTerminalClient; + private final JasperWirelessSmsClient jasperWirelessSmsClient; + private final int jasperGetSessionRetries; + + private final int jasperGetSessionSleepBetweenRetries; + + public SessionProviderKpnPollJasper( + final SessionProviderMap sessionProviderMap, + final JasperWirelessTerminalClient jasperWirelessTerminalClient, + final JasperWirelessSmsClient jasperWirelessSmsClient, + final int jasperGetSessionRetries, + final int jasperGetSessionSleepBetweenRetries) { + super(sessionProviderMap); + this.jasperWirelessTerminalClient = jasperWirelessTerminalClient; + this.jasperWirelessSmsClient = jasperWirelessSmsClient; + this.jasperGetSessionRetries = jasperGetSessionRetries; + this.jasperGetSessionSleepBetweenRetries = jasperGetSessionSleepBetweenRetries; + } + + /** + * Initialization function executed after dependency injection has finished. The SessionProvider + * Singleton is added to the HashMap of SessionProviderMap. + */ + @PostConstruct + public void init() { + this.sessionProviderMap.addProvider(SessionProviderEnum.KPN, this); + } + + @Override + public Optional getIpAddress(final String deviceIdentification, final String iccId) + throws OsgpException { + String deviceIpAddress; + try { + deviceIpAddress = this.getIpAddressFromSessionInfo(iccId); + if (deviceIpAddress != null) { + return Optional.of(deviceIpAddress); + } + + // If the result is null then the meter is not in session (not + // awake). + // So wake up the meter and start polling for the session + this.jasperWirelessSmsClient.sendWakeUpSMS(iccId); + deviceIpAddress = this.pollForSession(iccId); + + } catch (final OsgpJasperException e) { + throw new FunctionalException( + FunctionalExceptionType.INVALID_ICCID, ComponentType.PROTOCOL_DLMS, e); + } + return Optional.ofNullable(deviceIpAddress); + } + + private String pollForSession(final String iccId) throws OsgpException { + + String deviceIpAddress = null; + try { + for (int i = 0; i < this.jasperGetSessionRetries; i++) { + Thread.sleep(this.jasperGetSessionSleepBetweenRetries); + deviceIpAddress = this.getIpAddressFromSessionInfo(iccId); + if (deviceIpAddress != null) { + return deviceIpAddress; + } + } + } catch (final InterruptedException e) { + Thread.currentThread().interrupt(); + LOGGER.error( + "Interrupted while sleeping before calling the sessionProvider.getIpAddress [iccId: " + + iccId + + "]", + e); + throw new FunctionalException( + FunctionalExceptionType.SESSION_PROVIDER_ERROR, ComponentType.PROTOCOL_DLMS, e); + } catch (final SessionProviderException e) { + LOGGER.error("SessionProviderException occurred [iccId: " + iccId + "]", e); + throw new FunctionalException( + FunctionalExceptionType.SESSION_PROVIDER_ERROR, ComponentType.PROTOCOL_DLMS, e); + } + return deviceIpAddress; + } + + private String getIpAddressFromSessionInfo(final String iccId) throws OsgpException { + try { + final GetSessionInfoResponse response = this.jasperWirelessTerminalClient.getSession(iccId); + return response.getIpAddress(); + } catch (final OsgpJasperException e) { + this.handleException(e); + return null; + } + } + + private void handleException(final OsgpJasperException e) throws FunctionalException { + String errorMessage = ""; + final FunctionalExceptionType functionalExceptionType; + if (e.getJasperError() != null) { + if (e.getJasperError().getHttpStatus() == HttpStatus.NOT_FOUND) { + functionalExceptionType = FunctionalExceptionType.INVALID_ICCID; + } else { + errorMessage = + String.format( + "Session provider %s returned error %s : %s", + SessionProviderEnum.KPN.name(), + e.getJasperError().getCode(), + e.getJasperError().getMessage()); + LOGGER.error(errorMessage, e); + functionalExceptionType = FunctionalExceptionType.SESSION_PROVIDER_ERROR; + } + } else { + errorMessage = + String.format( + "Session provider %s returned unknown error message: %s", + SessionProviderEnum.KPN.name(), e.getMessage()); + LOGGER.error(errorMessage, e); + functionalExceptionType = FunctionalExceptionType.SESSION_PROVIDER_ERROR; + } + throw new FunctionalException( + functionalExceptionType, + ComponentType.PROTOCOL_DLMS, + new OsgpException(ComponentType.PROTOCOL_DLMS, e.getMessage())); + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/sessionproviders/SessionProviderKpnPushAlarm.java b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/sessionproviders/SessionProviderKpnPushAlarm.java new file mode 100644 index 00000000000..dcf54b24699 --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/sessionproviders/SessionProviderKpnPushAlarm.java @@ -0,0 +1,146 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.adapter.protocol.jasper.sessionproviders; + +import java.util.Optional; +import javax.annotation.PostConstruct; +import org.opensmartgridplatform.adapter.protocol.jasper.client.JasperWirelessSmsClient; +import org.opensmartgridplatform.adapter.protocol.jasper.client.JasperWirelessTerminalClient; +import org.opensmartgridplatform.adapter.protocol.jasper.response.GetSessionInfoResponse; +import org.opensmartgridplatform.adapter.protocol.jasper.service.DeviceSessionService; +import org.opensmartgridplatform.jasper.exceptions.OsgpJasperException; +import org.opensmartgridplatform.shared.exceptionhandling.ComponentType; +import org.opensmartgridplatform.shared.exceptionhandling.FunctionalException; +import org.opensmartgridplatform.shared.exceptionhandling.FunctionalExceptionType; +import org.opensmartgridplatform.shared.exceptionhandling.OsgpException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; + +public class SessionProviderKpnPushAlarm extends SessionProvider { + + private static final Logger LOGGER = LoggerFactory.getLogger(SessionProviderKpnPushAlarm.class); + + private final JasperWirelessSmsClient jasperWirelessSmsClient; + private final JasperWirelessTerminalClient jasperWirelessTerminalClient; + private final DeviceSessionService deviceSessionService; + private final int nrOfAttempts; + + public SessionProviderKpnPushAlarm( + final SessionProviderMap sessionProviderMap, + final JasperWirelessSmsClient jasperWirelessSmsClient, + final JasperWirelessTerminalClient jasperWirelessTerminalClient, + final DeviceSessionService deviceSessionService, + final int nrOfAttempts) { + super(sessionProviderMap); + this.jasperWirelessSmsClient = jasperWirelessSmsClient; + this.jasperWirelessTerminalClient = jasperWirelessTerminalClient; + this.deviceSessionService = deviceSessionService; + this.nrOfAttempts = nrOfAttempts; + } + + /** + * Initialization function executed after dependency injection has finished. The SessionProvider + * Singleton is added to the HashMap of SessionProviderMap. + */ + @PostConstruct + public void init() { + this.sessionProviderMap.addProvider(SessionProviderEnum.KPN, this); + } + + @Override + public Optional getIpAddress(final String deviceIdentification, final String iccId) + throws OsgpException { + LOGGER.info("Get ip address for device: " + deviceIdentification); + try { + this.jasperWirelessSmsClient.sendWakeUpSMS(iccId); + + return this.waitForIpAddress(deviceIdentification, iccId); + } catch (final OsgpJasperException e) { + this.handleException(e); + return Optional.empty(); + } + } + + private Optional waitForIpAddress(final String deviceIdentification, final String iccId) + throws OsgpJasperException { + + Optional ipAddress = Optional.empty(); + for (int attempt = 1; attempt <= this.nrOfAttempts; attempt++) { + LOGGER.info( + "Wait for ip-address, this will be pushed by alarm for device: {}, attempt {}", + deviceIdentification, + attempt); + ipAddress = this.deviceSessionService.waitForIpAddress(deviceIdentification); + if (ipAddress.isEmpty()) { + LOGGER.info( + "Did not receive an ip-address for device: {}, try to get ip-address from session provider, attempt {}", + deviceIdentification, + attempt); + ipAddress = this.getIpAddressFromSessionInfo(deviceIdentification, iccId); + } + if (ipAddress.isPresent()) { + LOGGER.info( + "Received ip-address: {} for device: {}, attempt: {}", + ipAddress.get(), + deviceIdentification, + attempt); + return ipAddress; + } + } + + return ipAddress; + } + + private Optional getIpAddressFromSessionInfo( + final String deviceIdentification, final String iccId) throws OsgpJasperException { + final GetSessionInfoResponse response = this.jasperWirelessTerminalClient.getSession(iccId); + final Optional ipAddress = Optional.ofNullable(response.getIpAddress()); + if (ipAddress.isEmpty()) { + LOGGER.info( + "Session provider did not return an ip-address for device: {}, icc: {}", + deviceIdentification, + iccId); + } else { + LOGGER.info( + "Session provider returned ip-address: {} for device: {}, icc: {}", + ipAddress.get(), + deviceIdentification, + iccId); + } + + return ipAddress; + } + + private void handleException(final OsgpJasperException e) throws FunctionalException { + String errorMessage = ""; + final FunctionalExceptionType functionalExceptionType; + if (e.getJasperError() != null) { + if (e.getJasperError().getHttpStatus() == HttpStatus.NOT_FOUND) { + functionalExceptionType = FunctionalExceptionType.INVALID_ICCID; + } else { + errorMessage = + String.format( + "Session provider %s returned error %s : %s", + SessionProviderEnum.KPN.name(), + e.getJasperError().getCode(), + e.getJasperError().getMessage()); + LOGGER.error(errorMessage, e); + functionalExceptionType = FunctionalExceptionType.SESSION_PROVIDER_ERROR; + } + } else { + errorMessage = + String.format( + "Session provider %s returned unknown error message: %s", + SessionProviderEnum.KPN.name(), e.getMessage()); + LOGGER.error(errorMessage, e); + functionalExceptionType = FunctionalExceptionType.SESSION_PROVIDER_ERROR; + } + throw new FunctionalException( + functionalExceptionType, + ComponentType.PROTOCOL_DLMS, + new OsgpException(ComponentType.PROTOCOL_DLMS, e.getMessage())); + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/sessionproviders/SessionProviderMap.java b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/sessionproviders/SessionProviderMap.java index cd6d1c2a676..6f340d272a7 100644 --- a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/sessionproviders/SessionProviderMap.java +++ b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/sessionproviders/SessionProviderMap.java @@ -6,15 +6,27 @@ import java.util.HashMap; import java.util.Map; +import lombok.extern.slf4j.Slf4j; +import org.apache.cxf.common.util.StringUtils; import org.springframework.stereotype.Component; @Component +@Slf4j public class SessionProviderMap { private final Map map = new HashMap<>(); public SessionProvider getProvider(final String provider) { - final SessionProviderEnum sessionProviderEnum = SessionProviderEnum.valueOf(provider); - return this.map.get(sessionProviderEnum); + if (StringUtils.isEmpty(provider)) { + log.error("Could not find SessionProvider because of null value in provider parameter"); + return null; + } + try { + final SessionProviderEnum sessionProviderEnum = SessionProviderEnum.valueOf(provider); + return this.map.get(sessionProviderEnum); + } catch (final IllegalArgumentException e) { + log.error("Could not find SessionProvider for unknown provider: {}", provider); + return null; + } } public void addProvider( diff --git a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/resources/jasper-interface.properties b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/resources/jasper-interface.properties index 65e4b46bd97..e34bee38cdd 100644 --- a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/resources/jasper-interface.properties +++ b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/resources/jasper-interface.properties @@ -8,8 +8,22 @@ jwcc.api.version=0.01 jwcc.api.type=SOAP jwcc.username=TestUser jwcc.password=1234 -jwcc.getsession.retries=30 -jwcc.getsession.sleep.between.retries=10000 + # validityPeriod (0, 143) -> (validityPeriod + 1) x 5 minutes = 5, 10, 15 minutes jwcc.validity_period=0 # ========================================================= + +jwcc.getsession.poll.jasper=false +# Polling settings +jwcc.getsession.retries=30 +jwcc.getsession.sleep.between.retries=10000 +# Push settings +push.alarm.max-wait-in-ms=60000 +push.alarm.attempts=5 +db.driver=org.postgresql.Driver +db.protocol=jdbc:postgresql:// +db.host=localhost +db.port=5432 +db.name=osgp_adapter_protocol_dlms +db.username=osp_admin +db.password=1234 diff --git a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/test/java/org/opensmartgridplatform/adapter/protocol/jasper/infra/ws/JasperWirelessSmsClientTest.java b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/test/java/org/opensmartgridplatform/adapter/protocol/jasper/infra/ws/JasperWirelessSmsClientTest.java index bdc68ff8729..6a0fbcda04d 100644 --- a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/test/java/org/opensmartgridplatform/adapter/protocol/jasper/infra/ws/JasperWirelessSmsClientTest.java +++ b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/test/java/org/opensmartgridplatform/adapter/protocol/jasper/infra/ws/JasperWirelessSmsClientTest.java @@ -101,10 +101,10 @@ void testSendWakeUpSms() { + "" + ICC_ID + "" + + "" + "" + VALIDITY_PERIOD + "" - + "" + ""); final Source responsePayload = diff --git a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/test/java/org/opensmartgridplatform/adapter/protocol/jasper/infra/ws/JasperWirelessTestConfig.java b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/test/java/org/opensmartgridplatform/adapter/protocol/jasper/infra/ws/JasperWirelessTestConfig.java index 8aa481aae2c..59fd58d6ba8 100644 --- a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/test/java/org/opensmartgridplatform/adapter/protocol/jasper/infra/ws/JasperWirelessTestConfig.java +++ b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/test/java/org/opensmartgridplatform/adapter/protocol/jasper/infra/ws/JasperWirelessTestConfig.java @@ -5,7 +5,7 @@ package org.opensmartgridplatform.adapter.protocol.jasper.infra.ws; import javax.annotation.Resource; -import org.opensmartgridplatform.adapter.protocol.jasper.config.JasperWirelessAccess; +import org.opensmartgridplatform.jasper.config.JasperWirelessAccess; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; diff --git a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/test/java/org/opensmartgridplatform/adapter/protocol/jasper/rest/client/JasperWirelessSmsRestClientTest.java b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/test/java/org/opensmartgridplatform/adapter/protocol/jasper/rest/client/JasperWirelessSmsRestClientTest.java index 5ce0e0af2a6..8e9385133c2 100644 --- a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/test/java/org/opensmartgridplatform/adapter/protocol/jasper/rest/client/JasperWirelessSmsRestClientTest.java +++ b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/test/java/org/opensmartgridplatform/adapter/protocol/jasper/rest/client/JasperWirelessSmsRestClientTest.java @@ -19,9 +19,9 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import org.opensmartgridplatform.adapter.protocol.jasper.config.JasperWirelessAccess; -import org.opensmartgridplatform.adapter.protocol.jasper.exceptions.OsgpJasperException; import org.opensmartgridplatform.adapter.protocol.jasper.rest.json.SendSMSResponse; +import org.opensmartgridplatform.jasper.config.JasperWirelessAccess; +import org.opensmartgridplatform.jasper.exceptions.OsgpJasperException; import org.springframework.http.HttpEntity; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; diff --git a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/test/java/org/opensmartgridplatform/adapter/protocol/jasper/rest/client/JasperWirelessTerminalRestClientTest.java b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/test/java/org/opensmartgridplatform/adapter/protocol/jasper/rest/client/JasperWirelessTerminalRestClientTest.java index 40b9189e216..024b6f7389d 100644 --- a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/test/java/org/opensmartgridplatform/adapter/protocol/jasper/rest/client/JasperWirelessTerminalRestClientTest.java +++ b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/test/java/org/opensmartgridplatform/adapter/protocol/jasper/rest/client/JasperWirelessTerminalRestClientTest.java @@ -22,9 +22,9 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import org.opensmartgridplatform.adapter.protocol.jasper.config.JasperWirelessAccess; -import org.opensmartgridplatform.adapter.protocol.jasper.exceptions.OsgpJasperException; import org.opensmartgridplatform.adapter.protocol.jasper.response.GetSessionInfoResponse; +import org.opensmartgridplatform.jasper.config.JasperWirelessAccess; +import org.opensmartgridplatform.jasper.exceptions.OsgpJasperException; import org.springframework.http.HttpEntity; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; @@ -52,7 +52,7 @@ private enum SessionType { NEVER_HAD_SESSION, CURRENT_SESSION, EXPIRED_SESSION - }; + } @Mock private RestTemplate jasperwirelessRestTemplate; diff --git a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/test/java/org/opensmartgridplatform/adapter/protocol/jasper/service/DeviceSessionServiceTest.java b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/test/java/org/opensmartgridplatform/adapter/protocol/jasper/service/DeviceSessionServiceTest.java new file mode 100644 index 00000000000..1153901904e --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/test/java/org/opensmartgridplatform/adapter/protocol/jasper/service/DeviceSessionServiceTest.java @@ -0,0 +1,150 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.adapter.protocol.jasper.service; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.Optional; +import javax.sql.DataSource; +import org.assertj.core.util.Arrays; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.postgresql.PGConnection; +import org.postgresql.PGNotification; + +@ExtendWith(MockitoExtension.class) +public class DeviceSessionServiceTest { + private static final String IP_ADDRESS_CHANNEL = "ip_address"; + + private static final String DEVICE_IDENTIFICATION = "device-identification"; + private static final String IP_ADDRESS = "1.2.3.4"; + @Mock private DataSource dataSource; + private final int maxWaitInMs = 654321; + private DeviceSessionService deviceSessionService; + + @BeforeEach + void setUp() { + this.deviceSessionService = new DeviceSessionService(this.dataSource, this.maxWaitInMs); + } + + @Test + void testWaitForIpAddressNoNotification() throws SQLException { + final PGConnection pgConnection = this.setupPgConnectionListen(); + + when(pgConnection.getNotifications(this.maxWaitInMs)).thenReturn(null); + + final Optional ipAddress = + this.deviceSessionService.waitForIpAddress(DEVICE_IDENTIFICATION); + + assertThat(ipAddress).isEmpty(); + } + + @Test + void testWaitForIpAddress() throws SQLException { + final PGConnection pgConnection = this.setupPgConnectionListen(); + final PGNotification pgNotification = + this.newPGNotification(this.getChannelName(DEVICE_IDENTIFICATION), IP_ADDRESS); + + when(pgConnection.getNotifications(this.maxWaitInMs)).thenReturn(Arrays.array(pgNotification)); + + final Optional ipAddress = + this.deviceSessionService.waitForIpAddress(DEVICE_IDENTIFICATION); + + assertThat(ipAddress).isEqualTo(Optional.of(IP_ADDRESS)); + verify(this.dataSource.getConnection()).close(); + } + + @Test + void testWaitForIpAddressThrowSqlException() throws SQLException { + final PGConnection pgConnection = this.setupPgConnectionListen(); + + when(pgConnection.getNotifications(this.maxWaitInMs)).thenThrow(new SQLException()); + + final Optional ipAddress = + this.deviceSessionService.waitForIpAddress(DEVICE_IDENTIFICATION); + + assertThat(ipAddress).isEqualTo(Optional.empty()); + verify(this.dataSource.getConnection()).close(); + } + + @Test + void testNotifyIpAddress() throws SQLException { + this.setupPgConnectionNotify(); + + this.deviceSessionService.notifyIpAddress(DEVICE_IDENTIFICATION, IP_ADDRESS); + verify(this.dataSource.getConnection()).close(); + } + + @Test + void testNotifyIpAddressThrowSqlException() throws SQLException { + final Connection connection = mock(Connection.class); + when(this.dataSource.getConnection()).thenReturn(connection); + when(connection.prepareStatement( + String.format( + "NOTIFY %s, '%s'", this.getChannelName(DEVICE_IDENTIFICATION), IP_ADDRESS))) + .thenThrow(new SQLException()); + + this.deviceSessionService.notifyIpAddress(DEVICE_IDENTIFICATION, IP_ADDRESS); + verify(this.dataSource.getConnection()).close(); + } + + private void setupPgConnectionNotify() throws SQLException { + final Connection connection = mock(Connection.class); + final PreparedStatement preparedStatement = mock(PreparedStatement.class); + + when(this.dataSource.getConnection()).thenReturn(connection); + when(connection.prepareStatement( + String.format( + "NOTIFY %s, '%s'", this.getChannelName(DEVICE_IDENTIFICATION), IP_ADDRESS))) + .thenReturn(preparedStatement); + when(preparedStatement.executeUpdate()).thenReturn(0); + } + + private PGConnection setupPgConnectionListen() throws SQLException { + final Connection connection = mock(Connection.class); + final PGConnection pgConnection = mock(PGConnection.class); + final PreparedStatement preparedStatement = mock(PreparedStatement.class); + + when(this.dataSource.getConnection()).thenReturn(connection); + when(connection.unwrap(PGConnection.class)).thenReturn(pgConnection); + when(connection.prepareStatement("LISTEN " + this.getChannelName(DEVICE_IDENTIFICATION))) + .thenReturn(preparedStatement); + when(preparedStatement.executeUpdate()).thenReturn(0); + + return pgConnection; + } + + private String getChannelName(final String deviceIdentification) { + return IP_ADDRESS_CHANNEL + "_" + deviceIdentification; + } + + private PGNotification newPGNotification(final String name, final String parameter) { + return new PGNotification() { + @Override + public String getName() { + return name; + } + + @Override + public int getPID() { + return 666; + } + + @Override + public String getParameter() { + return parameter; + } + }; + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/test/java/org/opensmartgridplatform/adapter/protocol/jasper/sessionproviders/SessionProviderKpnPollJasperTest.java b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/test/java/org/opensmartgridplatform/adapter/protocol/jasper/sessionproviders/SessionProviderKpnPollJasperTest.java new file mode 100644 index 00000000000..de569ce2724 --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/test/java/org/opensmartgridplatform/adapter/protocol/jasper/sessionproviders/SessionProviderKpnPollJasperTest.java @@ -0,0 +1,127 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.adapter.protocol.jasper.sessionproviders; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.opensmartgridplatform.shared.exceptionhandling.ComponentType.PROTOCOL_DLMS; +import static org.opensmartgridplatform.shared.exceptionhandling.FunctionalExceptionType.INVALID_ICCID; + +import java.util.Date; +import java.util.Optional; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.opensmartgridplatform.adapter.protocol.jasper.client.JasperWirelessSmsClient; +import org.opensmartgridplatform.adapter.protocol.jasper.client.JasperWirelessTerminalClient; +import org.opensmartgridplatform.adapter.protocol.jasper.response.GetSessionInfoResponse; +import org.opensmartgridplatform.jasper.exceptions.OsgpJasperException; +import org.opensmartgridplatform.shared.exceptionhandling.FunctionalException; +import org.opensmartgridplatform.shared.exceptionhandling.OsgpException; + +@ExtendWith(MockitoExtension.class) +public class SessionProviderKpnPollJasperTest { + + private static final String DEVICE_IDENTIFICATION = "device-identification"; + private static final String ICC_ID = "icc-id"; + private static final String IP_ADDRESS = "1.2.3.4"; + + @Mock private SessionProviderMap sessionProviderMap; + @Mock private JasperWirelessTerminalClient jasperWirelessTerminalClient; + @Mock private JasperWirelessSmsClient jasperWirelessSmsClient; + private final int jasperGetSessionRetries = 1; + private final int jasperGetSessionSleepBetweenRetries = 2; + + private SessionProviderKpnPollJasper sessionProviderKpnPollJasper; + + @BeforeEach + void setUp() { + this.sessionProviderKpnPollJasper = + new SessionProviderKpnPollJasper( + this.sessionProviderMap, + this.jasperWirelessTerminalClient, + this.jasperWirelessSmsClient, + this.jasperGetSessionRetries, + this.jasperGetSessionSleepBetweenRetries); + } + + @Test + void testInit() { + this.sessionProviderKpnPollJasper.init(); + + verify(this.sessionProviderMap) + .addProvider(SessionProviderEnum.KPN, this.sessionProviderKpnPollJasper); + } + + @Test + void testGetIpAddressInSession() throws OsgpException, OsgpJasperException { + final GetSessionInfoResponse response = this.newGetSessionInfoResponse(ICC_ID, IP_ADDRESS); + when(this.jasperWirelessTerminalClient.getSession(ICC_ID)).thenReturn(response); + + final Optional ipAddress = + this.sessionProviderKpnPollJasper.getIpAddress(DEVICE_IDENTIFICATION, ICC_ID); + assertThat(ipAddress).isPresent().isEqualTo(Optional.of(IP_ADDRESS)); + } + + @Test + void testGetIpAddressNotInSession() throws OsgpException, OsgpJasperException { + final GetSessionInfoResponse emptyResponse = this.newGetSessionInfoResponse(ICC_ID, null); + final GetSessionInfoResponse response = this.newGetSessionInfoResponse(ICC_ID, IP_ADDRESS); + when(this.jasperWirelessTerminalClient.getSession(ICC_ID)) + .thenReturn(emptyResponse) + .thenReturn(response); + + final Optional ipAddress = + this.sessionProviderKpnPollJasper.getIpAddress(DEVICE_IDENTIFICATION, ICC_ID); + + verify(this.jasperWirelessSmsClient).sendWakeUpSMS(ICC_ID); + assertThat(ipAddress).isPresent().isEqualTo(Optional.of(IP_ADDRESS)); + } + + @Test + void testGetIpAddressNotInSessionMaxRetries() throws OsgpException, OsgpJasperException { + final GetSessionInfoResponse emptyResponse = this.newGetSessionInfoResponse(ICC_ID, null); + final GetSessionInfoResponse response = this.newGetSessionInfoResponse(ICC_ID, IP_ADDRESS); + when(this.jasperWirelessTerminalClient.getSession(ICC_ID)) + .thenReturn(emptyResponse) + .thenReturn(emptyResponse); + + final Optional ipAddress = + this.sessionProviderKpnPollJasper.getIpAddress(DEVICE_IDENTIFICATION, ICC_ID); + + verify(this.jasperWirelessSmsClient).sendWakeUpSMS(ICC_ID); + assertThat(ipAddress).isEmpty(); + } + + @Test + void testGetIpAddressNotInSessionJasperException() throws OsgpJasperException { + final GetSessionInfoResponse emptyResponse = this.newGetSessionInfoResponse(ICC_ID, null); + final GetSessionInfoResponse response = this.newGetSessionInfoResponse(ICC_ID, IP_ADDRESS); + when(this.jasperWirelessTerminalClient.getSession(ICC_ID)) + .thenReturn(emptyResponse) + .thenReturn(response); + + when(this.jasperWirelessSmsClient.sendWakeUpSMS(ICC_ID)).thenThrow(new OsgpJasperException("")); + + final FunctionalException functionalException = + assertThrows( + FunctionalException.class, + () -> { + this.sessionProviderKpnPollJasper.getIpAddress(DEVICE_IDENTIFICATION, ICC_ID); + }); + + assertThat(functionalException.getExceptionType()).isEqualTo(INVALID_ICCID); + assertThat(functionalException.getComponentType()).isEqualTo(PROTOCOL_DLMS); + } + + private GetSessionInfoResponse newGetSessionInfoResponse( + final String iccId, final String ipAddress) { + return new GetSessionInfoResponse(iccId, ipAddress, ipAddress, new Date(), new Date()); + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/test/java/org/opensmartgridplatform/adapter/protocol/jasper/sessionproviders/SessionProviderKpnPushAlarmTest.java b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/test/java/org/opensmartgridplatform/adapter/protocol/jasper/sessionproviders/SessionProviderKpnPushAlarmTest.java new file mode 100644 index 00000000000..c0580e3dc43 --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/test/java/org/opensmartgridplatform/adapter/protocol/jasper/sessionproviders/SessionProviderKpnPushAlarmTest.java @@ -0,0 +1,197 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.adapter.protocol.jasper.sessionproviders; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.when; + +import java.util.Date; +import java.util.Optional; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.opensmartgridplatform.adapter.protocol.jasper.client.JasperWirelessSmsClient; +import org.opensmartgridplatform.adapter.protocol.jasper.client.JasperWirelessTerminalClient; +import org.opensmartgridplatform.adapter.protocol.jasper.response.GetSessionInfoResponse; +import org.opensmartgridplatform.adapter.protocol.jasper.service.DeviceSessionService; +import org.opensmartgridplatform.jasper.exceptions.OsgpJasperException; +import org.opensmartgridplatform.jasper.rest.JasperError; +import org.opensmartgridplatform.shared.exceptionhandling.ComponentType; +import org.opensmartgridplatform.shared.exceptionhandling.FunctionalException; +import org.opensmartgridplatform.shared.exceptionhandling.FunctionalExceptionType; +import org.opensmartgridplatform.shared.exceptionhandling.OsgpException; + +@ExtendWith(MockitoExtension.class) +public class SessionProviderKpnPushAlarmTest { + + private static final String DEVICE_IDENTIFICATION = "device-identification"; + private static final String ICC_ID = "icc-id"; + private static final String IP_ADDRESS = "1.2.3.4"; + + @Mock private SessionProviderMap sessionProviderMap; + @Mock private JasperWirelessSmsClient jasperWirelessSmsClient; + @Mock private JasperWirelessTerminalClient jasperWirelessTerminalClient; + + @Mock private DeviceSessionService deviceSessionService; + private final int nrOfAttempts = 2; + private SessionProviderKpnPushAlarm sessionProviderKpnPushAlarm; + + @BeforeEach + void setUp() { + this.sessionProviderKpnPushAlarm = + new SessionProviderKpnPushAlarm( + this.sessionProviderMap, + this.jasperWirelessSmsClient, + this.jasperWirelessTerminalClient, + this.deviceSessionService, + this.nrOfAttempts); + } + + @Test + void testInit() { + this.sessionProviderKpnPushAlarm.init(); + + verify(this.sessionProviderMap) + .addProvider(SessionProviderEnum.KPN, this.sessionProviderKpnPushAlarm); + } + + @Test + void testGetIpAddress() throws OsgpException, OsgpJasperException { + when(this.deviceSessionService.waitForIpAddress(DEVICE_IDENTIFICATION)) + .thenReturn(Optional.of(IP_ADDRESS)); + + final Optional ipAddress = + this.sessionProviderKpnPushAlarm.getIpAddress(DEVICE_IDENTIFICATION, ICC_ID); + + assertThat(ipAddress).isEqualTo(Optional.of(IP_ADDRESS)); + verify(this.jasperWirelessSmsClient).sendWakeUpSMS(ICC_ID); + verifyNoInteractions(this.jasperWirelessTerminalClient); + } + + @Test + void testGetIpAddressNoAlarmIpFromSession() throws OsgpException, OsgpJasperException { + when(this.deviceSessionService.waitForIpAddress(DEVICE_IDENTIFICATION)) + .thenReturn(Optional.empty()); + when(this.jasperWirelessTerminalClient.getSession(ICC_ID)) + .thenReturn(this.newGetSessionInfoResponse(IP_ADDRESS)); + + final Optional ipAddress = + this.sessionProviderKpnPushAlarm.getIpAddress(DEVICE_IDENTIFICATION, ICC_ID); + + assertThat(ipAddress).isEqualTo(Optional.of(IP_ADDRESS)); + verify(this.jasperWirelessSmsClient).sendWakeUpSMS(ICC_ID); + } + + @Test + void testGetIpAddressNoAlarmNoSession() throws OsgpException, OsgpJasperException { + when(this.deviceSessionService.waitForIpAddress(DEVICE_IDENTIFICATION)) + .thenReturn(Optional.empty()) + .thenReturn(Optional.empty()); + when(this.jasperWirelessTerminalClient.getSession(ICC_ID)) + .thenReturn(this.newGetSessionInfoResponse(null)) + .thenReturn(this.newGetSessionInfoResponse(null)); + + final Optional ipAddress = + this.sessionProviderKpnPushAlarm.getIpAddress(DEVICE_IDENTIFICATION, ICC_ID); + + assertThat(ipAddress).isEqualTo(Optional.empty()); + verify(this.jasperWirelessSmsClient).sendWakeUpSMS(ICC_ID); + } + + @Test + void testGetIpAddressSecondAttemptAlarm() throws OsgpException, OsgpJasperException { + when(this.deviceSessionService.waitForIpAddress(DEVICE_IDENTIFICATION)) + .thenReturn(Optional.empty()) + .thenReturn(Optional.of(IP_ADDRESS)); + when(this.jasperWirelessTerminalClient.getSession(ICC_ID)) + .thenReturn(this.newGetSessionInfoResponse(null)); + + final Optional ipAddress = + this.sessionProviderKpnPushAlarm.getIpAddress(DEVICE_IDENTIFICATION, ICC_ID); + + assertThat(ipAddress).isEqualTo(Optional.of(IP_ADDRESS)); + verify(this.jasperWirelessSmsClient).sendWakeUpSMS(ICC_ID); + } + + @Test + void testGetIpAddressSecondAttemptSession() throws OsgpException, OsgpJasperException { + when(this.deviceSessionService.waitForIpAddress(DEVICE_IDENTIFICATION)) + .thenReturn(Optional.empty()) + .thenReturn(Optional.empty()); + when(this.jasperWirelessTerminalClient.getSession(ICC_ID)) + .thenReturn(this.newGetSessionInfoResponse(null)) + .thenReturn(this.newGetSessionInfoResponse(IP_ADDRESS)); + + final Optional ipAddress = + this.sessionProviderKpnPushAlarm.getIpAddress(DEVICE_IDENTIFICATION, ICC_ID); + + assertThat(ipAddress).isEqualTo(Optional.of(IP_ADDRESS)); + verify(this.jasperWirelessSmsClient).sendWakeUpSMS(ICC_ID); + } + + @Test + void testGetIpAddressJasperExceptionNotFound() throws OsgpJasperException { + when(this.jasperWirelessSmsClient.sendWakeUpSMS(ICC_ID)) + .thenThrow(new OsgpJasperException(JasperError.INVALID_ICCID)); + + final FunctionalException functionalException = + assertThrows( + FunctionalException.class, + () -> { + this.sessionProviderKpnPushAlarm.getIpAddress(DEVICE_IDENTIFICATION, ICC_ID); + }); + + assertThat(functionalException.getExceptionType()) + .isEqualTo(FunctionalExceptionType.INVALID_ICCID); + assertThat(functionalException.getComponentType()).isEqualTo(ComponentType.PROTOCOL_DLMS); + verifyNoInteractions(this.deviceSessionService); + } + + @Test + void testGetIpAddressJasperExceptionOtherError() throws OsgpJasperException { + when(this.jasperWirelessSmsClient.sendWakeUpSMS(ICC_ID)) + .thenThrow(new OsgpJasperException(JasperError.INVALID_REQUEST)); + + final FunctionalException functionalException = + assertThrows( + FunctionalException.class, + () -> { + this.sessionProviderKpnPushAlarm.getIpAddress(DEVICE_IDENTIFICATION, ICC_ID); + }); + + assertThat(functionalException.getExceptionType()) + .isEqualTo(FunctionalExceptionType.SESSION_PROVIDER_ERROR); + assertThat(functionalException.getComponentType()).isEqualTo(ComponentType.PROTOCOL_DLMS); + verifyNoInteractions(this.deviceSessionService); + } + + @Test + void testGetIpAddressJasperExceptionString() throws OsgpJasperException { + final String errorMessage = "error message"; + when(this.jasperWirelessSmsClient.sendWakeUpSMS(ICC_ID)) + .thenThrow(new OsgpJasperException("String error")); + + final FunctionalException functionalException = + assertThrows( + FunctionalException.class, + () -> { + this.sessionProviderKpnPushAlarm.getIpAddress(DEVICE_IDENTIFICATION, ICC_ID); + }); + + assertThat(functionalException.getExceptionType()) + .isEqualTo(FunctionalExceptionType.SESSION_PROVIDER_ERROR); + assertThat(functionalException.getComponentType()).isEqualTo(ComponentType.PROTOCOL_DLMS); + verifyNoInteractions(this.deviceSessionService); + } + + private GetSessionInfoResponse newGetSessionInfoResponse(final String ipAddress) { + return new GetSessionInfoResponse(ICC_ID, ipAddress, null, new Date(), new Date()); + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/test/java/org/opensmartgridplatform/adapter/protocol/jasper/sessionproviders/SessionProviderMapTest.java b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/test/java/org/opensmartgridplatform/adapter/protocol/jasper/sessionproviders/SessionProviderMapTest.java new file mode 100644 index 00000000000..fb5d7cc1005 --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/test/java/org/opensmartgridplatform/adapter/protocol/jasper/sessionproviders/SessionProviderMapTest.java @@ -0,0 +1,33 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.adapter.protocol.jasper.sessionproviders; + +import static org.junit.jupiter.api.Assertions.*; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class SessionProviderMapTest { + + @InjectMocks private SessionProviderMap sessionProviderMap; + + @Test + void callToGetProviderWithNullProviderShouldResultInNullSessionProvider() { + + final SessionProvider sessionProvider = this.sessionProviderMap.getProvider(null); + Assertions.assertThat(sessionProvider).isNull(); + } + + @Test + void callToGetProviderWithUnknownProviderShouldResultInNullSessionProvider() { + + final SessionProvider sessionProvider = this.sessionProviderMap.getProvider("NOT_KNOWN"); + Assertions.assertThat(sessionProvider).isNull(); + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/pom.xml b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/pom.xml index c534266aa48..3d9939dbaf4 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/pom.xml +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/pom.xml @@ -19,7 +19,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-pa-dlms - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-pa-dlms/pom.xml @@ -27,7 +27,7 @@ SPDX-License-Identifier: Apache-2.0 ${project.version}-${BUILD_TAG} ${project.version} true - 1.7.2.2-SNAPSHOT + 1.8.0 @@ -192,6 +192,12 @@ SPDX-License-Identifier: Apache-2.0 org.springframework.ws spring-ws-security + + + org.bouncycastle + bcprov-jdk15on + + org.springframework.ws @@ -297,6 +303,14 @@ SPDX-License-Identifier: Apache-2.0 + + org.opensmartgridplatform + osgp-dlms + ${osgp.dlms.version} + tests + test-jar + test + org.junit.jupiter junit-jupiter-api @@ -336,7 +350,7 @@ SPDX-License-Identifier: Apache-2.0 org.postgresql postgresql - test + runtime org.projectlombok diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/config/DlmsConfig.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/config/DlmsConfig.java index d6d1ae0e6d6..d1654a6faa2 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/config/DlmsConfig.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/config/DlmsConfig.java @@ -21,23 +21,22 @@ import org.opensmartgridplatform.adapter.protocol.dlms.application.services.DeviceKeyProcessingService; import org.opensmartgridplatform.adapter.protocol.dlms.application.services.DomainHelperService; import org.opensmartgridplatform.adapter.protocol.dlms.application.services.SecretManagementService; -import org.opensmartgridplatform.adapter.protocol.dlms.application.services.ThrottlingService; import org.opensmartgridplatform.adapter.protocol.dlms.application.threads.RecoverKeyProcess; import org.opensmartgridplatform.adapter.protocol.dlms.application.threads.RecoverKeyProcessInitiator; +import org.opensmartgridplatform.adapter.protocol.dlms.application.throttling.ThrottlingService; import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsDeviceAssociation; import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.Hls5Connector; import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.Lls0Connector; import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.Lls1Connector; import org.opensmartgridplatform.adapter.protocol.dlms.domain.repositories.DlmsDeviceRepository; import org.opensmartgridplatform.adapter.protocol.dlms.infra.networking.DlmsChannelHandlerServer; -import org.opensmartgridplatform.adapter.protocol.dlms.infra.networking.DlmsPushNotificationDecoder; +import org.opensmartgridplatform.adapter.protocol.dlms.infra.networking.DlmsPushNotificationReplayingDecoder; import org.opensmartgridplatform.dlms.exceptions.ObjectConfigException; import org.opensmartgridplatform.dlms.services.ObjectConfigService; import org.opensmartgridplatform.shared.application.config.AbstractConfig; import org.opensmartgridplatform.shared.infra.networking.DisposableNioEventLoopGroup; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; @@ -102,7 +101,8 @@ private ChannelPipeline createChannelPipeline( final ChannelPipeline pipeline = channel.pipeline(); pipeline.addLast("loggingHandler", new LoggingHandler(LogLevel.INFO)); - pipeline.addLast("dlmsPushNotificationDecoder", new DlmsPushNotificationDecoder()); + pipeline.addLast( + "dlmsPushNotificationReplayingDecoder", new DlmsPushNotificationReplayingDecoder()); pipeline.addLast("dlmsChannelHandler", handler); return pipeline; @@ -166,8 +166,8 @@ public RecoverKeyProcess recoverKeyProcess( final DomainHelperService domainHelperService, final Hls5Connector hls5Connector, final SecretManagementService secretManagementService, - @Autowired(required = false) final ThrottlingService throttlingService, - final ThrottlingClientConfig throttlingClientConfig, + final ThrottlingService throttlingService, + final ThrottlingConfig throttlingConfig, final DlmsDeviceRepository deviceRepository, final DeviceKeyProcessingService deviceKeyProcessingService) { return new RecoverKeyProcess( @@ -175,7 +175,7 @@ public RecoverKeyProcess recoverKeyProcess( hls5Connector, secretManagementService, throttlingService, - throttlingClientConfig, + throttlingConfig, deviceRepository, deviceKeyProcessingService); } @@ -199,7 +199,7 @@ public ScheduledExecutorService scheduledExecutorService( @Bean public ObjectConfigService objectConfigService() { try { - return new ObjectConfigService(null); + return new ObjectConfigService(); } catch (final ObjectConfigException | IOException e) { throw new IllegalStateException("Could not load object config", e); } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/config/ThrottlingClientConfig.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/config/ThrottlingClientConfig.java index 91004b4c4f4..cc61aa12330 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/config/ThrottlingClientConfig.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/config/ThrottlingClientConfig.java @@ -5,6 +5,7 @@ package org.opensmartgridplatform.adapter.protocol.dlms.application.config; import java.time.Duration; +import org.opensmartgridplatform.adapter.protocol.dlms.application.config.annotation.SharedThrottlingServiceCondition; import org.opensmartgridplatform.throttling.ThrottlingClient; import org.opensmartgridplatform.throttling.api.ThrottlingConfig; import org.springframework.beans.factory.annotation.Value; @@ -36,9 +37,6 @@ public class ThrottlingClientConfig { @Value("#{T(java.time.Duration).parse('${throttling.service.timeout:PT30S}')}") private Duration timeout; - @Value("#{T(java.time.Duration).parse('${throttling.rejected.delay:PT10S}')}") - private Duration permitRejectedDelay; - public boolean clientEnabled() { return this.clientEnabled; } @@ -48,7 +46,7 @@ public String configurationName() { } @Bean(destroyMethod = "unregister") - @Conditional(ThrottlingClientEnabledCondition.class) + @Conditional(SharedThrottlingServiceCondition.class) public ThrottlingClient throttlingClient() { return new ThrottlingClient( new ThrottlingConfig(this.configurationName, this.configurationMaxConcurrency), @@ -57,13 +55,4 @@ public ThrottlingClient throttlingClient() { this.maxConnPerRoute, this.maxConnTotal); } - - /** - * Delay to be applied before retrying some action when a requested permit was not granted. - * - * @return delay - */ - public Duration permitRejectedDelay() { - return this.permitRejectedDelay; - } } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/config/ThrottlingClientEnabledCondition.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/config/ThrottlingClientEnabledCondition.java deleted file mode 100644 index f18e44337ad..00000000000 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/config/ThrottlingClientEnabledCondition.java +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-FileCopyrightText: Copyright Contributors to the GXF project -// -// SPDX-License-Identifier: Apache-2.0 - -package org.opensmartgridplatform.adapter.protocol.dlms.application.config; - -import org.springframework.context.annotation.Condition; -import org.springframework.context.annotation.ConditionContext; -import org.springframework.core.type.AnnotatedTypeMetadata; - -public class ThrottlingClientEnabledCondition implements Condition { - - @Override - public boolean matches(final ConditionContext context, final AnnotatedTypeMetadata metadata) { - return "true" - .equalsIgnoreCase(context.getEnvironment().getProperty("throttling.client.enabled")); - } -} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/config/ThrottlingConfig.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/config/ThrottlingConfig.java new file mode 100644 index 00000000000..1f91fead2fd --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/config/ThrottlingConfig.java @@ -0,0 +1,41 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.adapter.protocol.dlms.application.config; + +import java.security.SecureRandom; +import java.time.Duration; +import org.opensmartgridplatform.shared.wsheaderattribute.priority.MessagePriorityEnum; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ThrottlingConfig { + private static final SecureRandom RANDOM = new SecureRandom(); + + @Value("#{T(java.time.Duration).parse('${throttling.rejected.min.delay:PT50S}')}") + private Duration permitRejectedMinDelay; + + @Value("#{T(java.time.Duration).parse('${throttling.rejected.max.delay:PT70S}')}") + private Duration permitRejectedMaxDelay; + + @Value("#{T(java.time.Duration).parse('${throttling.rejected.high.prio.delay:PT2S}')}") + private Duration permitRejectedHighPrioDelay; + + /** + * Delay to be applied before retrying some action when a requested permit was not granted. + * + * @return delay + */ + public Duration permitRejectedDelay(final int messagePriority) { + if (messagePriority > MessagePriorityEnum.DEFAULT.getPriority()) { + return this.permitRejectedHighPrioDelay; + } + final long minMillis = + Math.min(this.permitRejectedMinDelay.toMillis(), this.permitRejectedMaxDelay.toMillis()); + final long maxMillis = + Math.max(this.permitRejectedMinDelay.toMillis(), this.permitRejectedMaxDelay.toMillis()); + return Duration.ofMillis(RANDOM.nextLong(minMillis, maxMillis)); + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/config/ThrottlingServiceEnabledCondition.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/config/ThrottlingServiceEnabledCondition.java deleted file mode 100644 index 54ed8b016c5..00000000000 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/config/ThrottlingServiceEnabledCondition.java +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-FileCopyrightText: Copyright Contributors to the GXF project -// -// SPDX-License-Identifier: Apache-2.0 - -package org.opensmartgridplatform.adapter.protocol.dlms.application.config; - -import org.springframework.context.annotation.ConditionContext; -import org.springframework.core.type.AnnotatedTypeMetadata; - -public class ThrottlingServiceEnabledCondition extends ThrottlingClientEnabledCondition { - - @Override - public boolean matches(final ConditionContext context, final AnnotatedTypeMetadata metadata) { - // Either the ThrottlingClient or the ThrottlingService should be used for throttling. - // So, this should behave as the negation of matches in ThrottlingClientEnabledCondition. - return !super.matches(context, metadata); - } -} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/config/annotation/DisabledThrottlingServiceCondition.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/config/annotation/DisabledThrottlingServiceCondition.java new file mode 100644 index 00000000000..44c2c5a12c6 --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/config/annotation/DisabledThrottlingServiceCondition.java @@ -0,0 +1,11 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.adapter.protocol.dlms.application.config.annotation; + +public class DisabledThrottlingServiceCondition extends ThrottlingTypeCondition { + public DisabledThrottlingServiceCondition() { + super("disabled"); + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/config/annotation/LocalThrottlingServiceCondition.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/config/annotation/LocalThrottlingServiceCondition.java new file mode 100644 index 00000000000..948a9096f92 --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/config/annotation/LocalThrottlingServiceCondition.java @@ -0,0 +1,11 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.adapter.protocol.dlms.application.config.annotation; + +public class LocalThrottlingServiceCondition extends ThrottlingTypeCondition { + public LocalThrottlingServiceCondition() { + super("local"); + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/config/annotation/SharedThrottlingServiceCondition.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/config/annotation/SharedThrottlingServiceCondition.java new file mode 100644 index 00000000000..6f8dedb0b8c --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/config/annotation/SharedThrottlingServiceCondition.java @@ -0,0 +1,11 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.adapter.protocol.dlms.application.config.annotation; + +public class SharedThrottlingServiceCondition extends ThrottlingTypeCondition { + public SharedThrottlingServiceCondition() { + super("shared"); + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/config/annotation/ThrottlingTypeCondition.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/config/annotation/ThrottlingTypeCondition.java new file mode 100644 index 00000000000..2cd85e2174f --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/config/annotation/ThrottlingTypeCondition.java @@ -0,0 +1,26 @@ +/* + * SPDX-FileCopyrightText: Copyright Contributors to the GXF project + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.opensmartgridplatform.adapter.protocol.dlms.application.config.annotation; + +import org.springframework.context.annotation.Condition; +import org.springframework.context.annotation.ConditionContext; +import org.springframework.core.type.AnnotatedTypeMetadata; + +public abstract class ThrottlingTypeCondition implements Condition { + + private final String throttlingType; + + protected ThrottlingTypeCondition(final String throttlingType) { + this.throttlingType = throttlingType; + } + + @Override + public boolean matches(final ConditionContext context, final AnnotatedTypeMetadata metadata) { + return this.throttlingType.equalsIgnoreCase( + context.getEnvironment().getProperty("throttling.type")); + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/mapping/DeviceConverter.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/mapping/DeviceConverter.java index ef339177205..3e51d6d0ce9 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/mapping/DeviceConverter.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/mapping/DeviceConverter.java @@ -22,6 +22,7 @@ public DlmsDevice convertTo( dlmsDevice.setCommunicationMethod(source.getCommunicationMethod()); dlmsDevice.setCommunicationProvider(source.getCommunicationProvider()); dlmsDevice.setIccId(source.getIccId()); + dlmsDevice.setLls1Active(source.isLls1Active()); dlmsDevice.setHls3Active(source.isHls3Active()); dlmsDevice.setHls4Active(source.isHls4Active()); dlmsDevice.setHls5Active(source.isHls5Active()); diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/services/DomainHelperService.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/services/DomainHelperService.java index a80b21ff89b..92748758bb4 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/services/DomainHelperService.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/services/DomainHelperService.java @@ -4,14 +4,12 @@ package org.opensmartgridplatform.adapter.protocol.dlms.application.services; +import java.util.Optional; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDevice; import org.opensmartgridplatform.adapter.protocol.dlms.domain.repositories.DlmsDeviceRepository; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; -import org.opensmartgridplatform.adapter.protocol.jasper.client.JasperWirelessSmsClient; -import org.opensmartgridplatform.adapter.protocol.jasper.exceptions.OsgpJasperException; import org.opensmartgridplatform.adapter.protocol.jasper.sessionproviders.SessionProvider; import org.opensmartgridplatform.adapter.protocol.jasper.sessionproviders.SessionProviderService; -import org.opensmartgridplatform.adapter.protocol.jasper.sessionproviders.exceptions.SessionProviderException; import org.opensmartgridplatform.shared.exceptionhandling.ComponentType; import org.opensmartgridplatform.shared.exceptionhandling.FunctionalException; import org.opensmartgridplatform.shared.exceptionhandling.FunctionalExceptionType; @@ -28,23 +26,11 @@ public class DomainHelperService { private final SessionProviderService sessionProviderService; - private final JasperWirelessSmsClient jasperWirelessSmsClient; - - private final int jasperGetSessionRetries; - - private final int jasperGetSessionSleepBetweenRetries; - public DomainHelperService( final DlmsDeviceRepository dlmsDeviceRepository, - final SessionProviderService sessionProviderService, - final JasperWirelessSmsClient jasperWirelessSmsClient, - final int jasperGetSessionRetries, - final int jasperGetSessionSleepBetweenRetries) { + final SessionProviderService sessionProviderService) { this.dlmsDeviceRepository = dlmsDeviceRepository; this.sessionProviderService = sessionProviderService; - this.jasperWirelessSmsClient = jasperWirelessSmsClient; - this.jasperGetSessionRetries = jasperGetSessionRetries; - this.jasperGetSessionSleepBetweenRetries = jasperGetSessionSleepBetweenRetries; } /** @@ -86,7 +72,7 @@ public void setIpAddressFromMessageMetadataOrSessionProvider( } if (dlmsDevice.isIpAddressIsStatic()) { - dlmsDevice.setIpAddress(messageMetadata.getIpAddress()); + dlmsDevice.setIpAddress(messageMetadata.getNetworkAddress()); } else { final String ipAddressFromSessionProvider = this.getDeviceIpAddressFromSessionProvider(dlmsDevice); @@ -99,55 +85,29 @@ public String getDeviceIpAddressFromSessionProvider(final DlmsDevice dlmsDevice) final SessionProvider sessionProvider = this.sessionProviderService.getSessionProvider(dlmsDevice.getCommunicationProvider()); - String deviceIpAddress; - try { - deviceIpAddress = sessionProvider.getIpAddress(dlmsDevice.getIccId()); - if (deviceIpAddress != null) { - return deviceIpAddress; - } - - // If the result is null then the meter is not in session (not - // awake). - // So wake up the meter and start polling for the session - this.jasperWirelessSmsClient.sendWakeUpSMS(dlmsDevice.getIccId()); - deviceIpAddress = this.pollForSession(sessionProvider, dlmsDevice); - - } catch (final OsgpJasperException e) { - throw new FunctionalException( - FunctionalExceptionType.INVALID_ICCID, ComponentType.PROTOCOL_DLMS, e); - } - if ((deviceIpAddress == null) || "".equals(deviceIpAddress)) { + + if (sessionProvider == null) { throw new ProtocolAdapterException( - "Session provider: " - + dlmsDevice.getCommunicationProvider() - + " did not return an IP address for device: " + "Session provider: Cannot find SessionProvider for device: " + dlmsDevice.getDeviceIdentification() + " and iccId: " - + dlmsDevice.getIccId()); + + dlmsDevice.getIccId() + + " and communicationProvider: " + + dlmsDevice.getCommunicationProvider()); } - return deviceIpAddress; - } - - private String pollForSession(final SessionProvider sessionProvider, final DlmsDevice dlmsDevice) - throws OsgpException { - String deviceIpAddress = null; - try { - for (int i = 0; i < this.jasperGetSessionRetries; i++) { - Thread.sleep(this.jasperGetSessionSleepBetweenRetries); - deviceIpAddress = sessionProvider.getIpAddress(dlmsDevice.getIccId()); - if (deviceIpAddress != null) { - return deviceIpAddress; - } - } - } catch (final InterruptedException e) { - Thread.currentThread().interrupt(); - throw new ProtocolAdapterException( - "Interrupted while sleeping before calling the sessionProvider.getIpAddress", e); - } catch (final SessionProviderException e) { - throw new ProtocolAdapterException("", e); - } - return deviceIpAddress; + final Optional deviceIpAddress = + sessionProvider.getIpAddress(dlmsDevice.getDeviceIdentification(), dlmsDevice.getIccId()); + + return deviceIpAddress.orElseThrow( + () -> + new ProtocolAdapterException( + "Session provider: No IP address was returned for device: " + + dlmsDevice.getDeviceIdentification() + + " and iccId: " + + dlmsDevice.getIccId() + + " and communicationProvider: " + + dlmsDevice.getCommunicationProvider())); } public DlmsDevice findMbusDevice( diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/services/SystemEventService.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/services/SystemEventService.java index 91129abbf9d..e6fdf12a329 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/services/SystemEventService.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/services/SystemEventService.java @@ -70,7 +70,7 @@ public void verifySystemEventThresholdReachedEvent( .withDeviceIdentification(device.getDeviceIdentification()) .withCorrelationUid(correlationId) .withOrganisationIdentification(sourceMessageMetadata.getOrganisationIdentification()) - .withIpAddress(sourceMessageMetadata.getIpAddress()) + .withNetworkAddress(sourceMessageMetadata.getNetworkAddress()) .withMessagePriority(MessagePriorityEnum.HIGH.getPriority()) .withMessageType(MessageType.SYSTEM_EVENT.name()) .withDomain(sourceMessageMetadata.getDomain()) diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/services/ThrottlingService.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/services/ThrottlingService.java deleted file mode 100644 index 3f396048e71..00000000000 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/services/ThrottlingService.java +++ /dev/null @@ -1,149 +0,0 @@ -// SPDX-FileCopyrightText: Copyright Contributors to the GXF project -// -// SPDX-License-Identifier: Apache-2.0 - -package org.opensmartgridplatform.adapter.protocol.dlms.application.services; - -import java.util.Timer; -import java.util.TimerTask; -import java.util.concurrent.Semaphore; -import java.util.concurrent.locks.ReentrantLock; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; -import org.opensmartgridplatform.adapter.protocol.dlms.application.config.ThrottlingServiceEnabledCondition; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Conditional; -import org.springframework.stereotype.Component; - -@Component -@Conditional(ThrottlingServiceEnabledCondition.class) -public class ThrottlingService { - - private static final Logger LOGGER = LoggerFactory.getLogger(ThrottlingService.class); - - @Value("${throttling.max.open.connections}") - private int maxOpenConnections; - - @Value("${throttling.max.new.connection.requests}") - private int maxNewConnectionRequests; - - @Value("${throttling.reset.time}") - private int resetTime; - - private Semaphore openConnectionsSemaphore; - private Semaphore newConnectionRequestsSemaphore; - private Timer resetTimer; - private ReentrantLock resetTimerLock; - - @PostConstruct - public void postConstruct() { - - this.openConnectionsSemaphore = new Semaphore(this.maxOpenConnections); - this.newConnectionRequestsSemaphore = new Semaphore(this.maxNewConnectionRequests); - - this.resetTimerLock = new ReentrantLock(); - - this.resetTimer = new Timer(); - this.resetTimer.scheduleAtFixedRate(new ResetTask(), this.resetTime, this.resetTime); - - LOGGER.info("Initialized ThrottlingService. {}", this); - } - - @PreDestroy - public void preDestroy() { - if (this.resetTimer != null) { - this.resetTimer.cancel(); - } - } - - public void openConnection() { - - this.newConnectionRequest(); - - LOGGER.debug( - "Requesting openConnection. available = {} ", - this.openConnectionsSemaphore.availablePermits()); - - try { - this.openConnectionsSemaphore.acquire(); - LOGGER.debug( - "openConnection granted. available = {} ", - this.openConnectionsSemaphore.availablePermits()); - } catch (final InterruptedException e) { - LOGGER.warn("Unable to acquire Open Connection", e); - Thread.currentThread().interrupt(); - } - } - - public void closeConnection() { - - LOGGER.debug( - "closeConnection(). available = {} ", this.openConnectionsSemaphore.availablePermits()); - this.openConnectionsSemaphore.release(); - } - - private void newConnectionRequest() { - - this.awaitReset(); - - LOGGER.debug( - "newConnectionRequest(). available = {} ", - this.newConnectionRequestsSemaphore.availablePermits()); - - try { - this.newConnectionRequestsSemaphore.acquire(); - LOGGER.debug( - "Request newConnection granted. available = {} ", - this.newConnectionRequestsSemaphore.availablePermits()); - } catch (final InterruptedException e) { - LOGGER.warn("Unable to acquire New Connection Request", e); - Thread.currentThread().interrupt(); - } - } - - private synchronized void awaitReset() { - while (this.resetTimerLock.isLocked()) { - try { - this.resetTimerLock.wait(this.resetTime); - } catch (final InterruptedException e) { - LOGGER.warn("Unable to acquire New Connection Request Lock", e); - Thread.currentThread().interrupt(); - } - } - } - - private class ResetTask extends TimerTask { - - @Override - public void run() { - - try { - ThrottlingService.this.resetTimerLock.lock(); - - final int nrOfPermitsToBeReleased = - ThrottlingService.this.maxNewConnectionRequests - - ThrottlingService.this.newConnectionRequestsSemaphore.availablePermits(); - - LOGGER.debug( - "releasing {} permits on newConnectionRequestsSemaphore", nrOfPermitsToBeReleased); - - ThrottlingService.this.newConnectionRequestsSemaphore.release(nrOfPermitsToBeReleased); - - LOGGER.debug( - "ThrottlingService - Timer Reset and Unlocking, newConnectionRequests available = {} ", - ThrottlingService.this.newConnectionRequestsSemaphore.availablePermits()); - } finally { - ThrottlingService.this.resetTimerLock.unlock(); - } - } - } - - @Override - public String toString() { - return String.format( - "ThrottlingService. maxOpenConnections = %d, maxNewConnectionRequests=%d, resetTime=%d", - this.maxOpenConnections, this.maxNewConnectionRequests, this.resetTime); - } -} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/threads/RecoverKeyProcess.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/threads/RecoverKeyProcess.java index eaea36d6c17..a9e8802cca8 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/threads/RecoverKeyProcess.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/threads/RecoverKeyProcess.java @@ -15,11 +15,11 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.openmuc.jdlms.DlmsConnection; -import org.opensmartgridplatform.adapter.protocol.dlms.application.config.ThrottlingClientConfig; +import org.opensmartgridplatform.adapter.protocol.dlms.application.config.ThrottlingConfig; import org.opensmartgridplatform.adapter.protocol.dlms.application.services.DeviceKeyProcessingService; import org.opensmartgridplatform.adapter.protocol.dlms.application.services.DomainHelperService; import org.opensmartgridplatform.adapter.protocol.dlms.application.services.SecretManagementService; -import org.opensmartgridplatform.adapter.protocol.dlms.application.services.ThrottlingService; +import org.opensmartgridplatform.adapter.protocol.dlms.application.throttling.ThrottlingService; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDevice; import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.Hls5Connector; import org.opensmartgridplatform.adapter.protocol.dlms.domain.repositories.DlmsDeviceRepository; @@ -46,7 +46,7 @@ public class RecoverKeyProcess implements Runnable { private final ThrottlingService throttlingService; - private final ThrottlingClientConfig throttlingClientConfig; + private final ThrottlingConfig throttlingConfig; private final DlmsDeviceRepository deviceRepository; @@ -57,14 +57,14 @@ public RecoverKeyProcess( final Hls5Connector hls5Connector, final SecretManagementService secretManagementService, final ThrottlingService throttlingService, - final ThrottlingClientConfig throttlingClientConfig, + final ThrottlingConfig throttlingConfig, final DlmsDeviceRepository deviceRepository, final DeviceKeyProcessingService deviceKeyProcessingService) { this.domainHelperService = domainHelperService; this.hls5Connector = hls5Connector; this.secretManagementService = secretManagementService; this.throttlingService = throttlingService; - this.throttlingClientConfig = throttlingClientConfig; + this.throttlingConfig = throttlingConfig; this.deviceRepository = deviceRepository; this.deviceKeyProcessingService = deviceKeyProcessingService; } @@ -107,7 +107,9 @@ public void run() { RecoverKeyProcess.this.run(); } }, - this.throttlingClientConfig.permitRejectedDelay().toMillis()); + this.throttlingConfig + .permitRejectedDelay(this.messageMetadata.getMessagePriority()) + .toMillis()); this.deviceKeyProcessingService.stopProcessing(this.deviceIdentification); @@ -166,7 +168,8 @@ private DlmsDevice findDeviceAndCheckState() { } final DlmsDevice device = this.findDevice(); - if (device.isIpAddressIsStatic() && StringUtils.isBlank(this.messageMetadata.getIpAddress())) { + if (device.isIpAddressIsStatic() + && StringUtils.isBlank(this.messageMetadata.getNetworkAddress())) { throw new IllegalStateException( "IP address not set in message metadata for device \"" + device.getDeviceIdentification() @@ -194,16 +197,11 @@ private boolean canConnectUsingNewKeys(final DlmsDevice device) { return false; } - if (this.throttlingClientConfig.clientEnabled()) { - permit = - this.throttlingClientConfig - .throttlingClient() - .requestPermitUsingNetworkSegmentIfIdsAreAvailable( - this.messageMetadata.getBaseTransceiverStationId(), - this.messageMetadata.getCellId()); - } else { - this.throttlingService.openConnection(); - } + permit = + this.throttlingService.requestPermit( + this.messageMetadata.getBaseTransceiverStationId(), + this.messageMetadata.getCellId(), + this.messageMetadata.getMessagePriority()); if (device.needsInvocationCounter()) { dlmsMessageListener = new InvocationCountingDlmsMessageListener(); @@ -237,13 +235,7 @@ private boolean canConnectUsingNewKeys(final DlmsDevice device) { } } - if (this.throttlingClientConfig.clientEnabled()) { - if (permit != null) { - this.throttlingClientConfig.throttlingClient().releasePermit(permit); - } - } else { - this.throttlingService.closeConnection(); - } + this.throttlingService.releasePermit(permit); if (dlmsMessageListener != null) { final int numberOfSentMessages = dlmsMessageListener.getNumberOfSentMessages(); diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/throttling/DisabledThrottlingServiceImpl.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/throttling/DisabledThrottlingServiceImpl.java new file mode 100644 index 00000000000..037b43eb2fe --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/throttling/DisabledThrottlingServiceImpl.java @@ -0,0 +1,31 @@ +/* + * SPDX-FileCopyrightText: Copyright Contributors to the GXF project + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.opensmartgridplatform.adapter.protocol.dlms.application.throttling; + +import lombok.extern.slf4j.Slf4j; +import org.opensmartgridplatform.adapter.protocol.dlms.application.config.annotation.DisabledThrottlingServiceCondition; +import org.opensmartgridplatform.throttling.api.Permit; +import org.springframework.context.annotation.Conditional; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +@Conditional(DisabledThrottlingServiceCondition.class) +public class DisabledThrottlingServiceImpl implements ThrottlingService { + + @Override + public Permit requestPermit( + final Integer baseTransceiverStationId, final Integer cellId, final Integer priority) { + log.debug("Throttling is disabled, do nothing on openConnection"); + return null; + } + + @Override + public void releasePermit(final Permit permit) { + log.debug("Throttling is disabled, do nothing on closeConnection"); + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/throttling/LocalThrottlingServiceImpl.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/throttling/LocalThrottlingServiceImpl.java new file mode 100644 index 00000000000..85b042d82f2 --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/throttling/LocalThrottlingServiceImpl.java @@ -0,0 +1,230 @@ +/* + * SPDX-FileCopyrightText: Copyright Contributors to the GXF project + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.opensmartgridplatform.adapter.protocol.dlms.application.throttling; + +import java.time.Duration; +import java.time.Instant; +import java.util.Map.Entry; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.ReentrantLock; +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import org.opensmartgridplatform.adapter.protocol.dlms.application.config.annotation.LocalThrottlingServiceCondition; +import org.opensmartgridplatform.throttling.ThrottlingPermitDeniedException; +import org.opensmartgridplatform.throttling.api.Permit; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Conditional; +import org.springframework.stereotype.Component; + +@Component +@Conditional(LocalThrottlingServiceCondition.class) +public class LocalThrottlingServiceImpl implements ThrottlingService { + + private static final long WAIT_FOR_LOCK = 10; + + private final AtomicInteger requestIdCounter = new AtomicInteger(0); + + private static final Logger LOGGER = LoggerFactory.getLogger(LocalThrottlingServiceImpl.class); + + private final int maxOpenConnections; + private final int maxNewConnectionRequests; + + @Value("${throttling.max.wait.for.permit}") + private int maxWaitForPermitInMs; + + @Value("${throttling.max.new.connection.reset.time}") + private int maxNewConnectionResetTime; + + @Value("${cleanup.permits.interval}") + private int cleanupExpiredPermitsInterval; + + @Value("#{T(java.time.Duration).parse('${cleanup.permits.time-to-live:PT1H}')}") + private Duration timeToLive; + + private final Semaphore openConnectionsSemaphore; + private final Semaphore newConnectionRequestsSemaphore; + private final Timer resetNewConnectionRequestsTimer; + private final Timer cleanupExpiredPermitsTimer; + private final ReentrantLock resetTimerLock; + + private final ConcurrentHashMap permitsByRequestId; + + public LocalThrottlingServiceImpl( + @Value("${throttling.max.open.connections}") final int maxOpenConnections, + @Value("${throttling.max.new.connection.requests}") final int maxNewConnectionRequests) { + this.maxOpenConnections = maxOpenConnections; + this.maxNewConnectionRequests = maxNewConnectionRequests; + this.openConnectionsSemaphore = new Semaphore(maxOpenConnections); + this.newConnectionRequestsSemaphore = new Semaphore(maxNewConnectionRequests); + + this.resetNewConnectionRequestsTimer = new Timer(); + this.cleanupExpiredPermitsTimer = new Timer(); + + this.resetTimerLock = new ReentrantLock(); + this.permitsByRequestId = new ConcurrentHashMap<>(); + } + + @PostConstruct + public void postConstruct() { + this.resetNewConnectionRequestsTimer.schedule( + new ResetNewConnectionRequestsTask(), + this.maxNewConnectionResetTime, + this.maxNewConnectionResetTime); + + this.cleanupExpiredPermitsTimer.schedule( + new CleanupExpiredPermitsTask(), + this.cleanupExpiredPermitsInterval, + this.cleanupExpiredPermitsInterval); + LOGGER.info("Initialized ThrottlingService. {}", this); + } + + @PreDestroy + public void preDestroy() { + this.resetNewConnectionRequestsTimer.cancel(); + this.cleanupExpiredPermitsTimer.cancel(); + this.resetNewConnectionRequestsTimer.purge(); + this.cleanupExpiredPermitsTimer.purge(); + } + + @Override + public Permit requestPermit( + final Integer baseTransceiverStationId, final Integer cellId, final Integer priority) { + + this.awaitReset(); + + // newConnectionRequest will be released by ResetNewConnectionRequestsTask + this.requestPermit(this.newConnectionRequestsSemaphore, priority, "newConnectionRequest"); + + // openConnection will be released releasePermit method or CleanupExpiredPermitsTask + this.requestPermit(this.openConnectionsSemaphore, priority, "openConnection"); + + return this.createPermit(); + } + + @Override + public void releasePermit(final Permit permit) { + LOGGER.debug( + "closeConnection(). available = {}", this.openConnectionsSemaphore.availablePermits()); + if (this.openConnectionsSemaphore.availablePermits() < this.maxOpenConnections) { + this.openConnectionsSemaphore.release(); + } + + this.permitsByRequestId.remove(permit.getRequestId()); + } + + private void requestPermit( + final Semaphore semaphore, final int priority, final String permitDescription) { + LOGGER.debug("{}. available = {} ", permitDescription, semaphore.availablePermits()); + + try { + if (!semaphore.tryAcquire(this.maxWaitForPermitInMs, TimeUnit.MILLISECONDS)) { + throw new ThrottlingPermitDeniedException( + permitDescription + ": could not acquire permit for request with priority " + priority, + priority); + } + LOGGER.debug("{} granted. available = {} ", permitDescription, semaphore.availablePermits()); + } catch (final InterruptedException e) { + LOGGER.warn(permitDescription + ": unable to acquire permit", e); + Thread.currentThread().interrupt(); + } + } + + private void awaitReset() { + LOGGER.debug( + "Await reset for newConnection. available = {} ", + this.newConnectionRequestsSemaphore.availablePermits()); + + while (this.resetTimerLock.isLocked()) { + try { + LOGGER.info("Wait {}ms while reset timer is locked", WAIT_FOR_LOCK); + synchronized (this.requestIdCounter) { + this.requestIdCounter.wait(WAIT_FOR_LOCK); + } + } catch (final InterruptedException e) { + LOGGER.warn("Unable to acquire New Connection Request Lock", e); + Thread.currentThread().interrupt(); + } + } + } + + private class ResetNewConnectionRequestsTask extends TimerTask { + + @Override + public void run() { + + try { + LocalThrottlingServiceImpl.this.resetTimerLock.lock(); + + final int nrOfPermitsToBeReleased = + LocalThrottlingServiceImpl.this.maxNewConnectionRequests + - LocalThrottlingServiceImpl.this.newConnectionRequestsSemaphore.availablePermits(); + + LOGGER.debug( + "releasing {} permits on newConnectionRequestsSemaphore", nrOfPermitsToBeReleased); + + LocalThrottlingServiceImpl.this.newConnectionRequestsSemaphore.release( + nrOfPermitsToBeReleased); + + LOGGER.debug( + "ThrottlingService - Timer Reset and Unlocking, newConnectionRequests available = {} ", + LocalThrottlingServiceImpl.this.newConnectionRequestsSemaphore.availablePermits()); + } finally { + LocalThrottlingServiceImpl.this.resetTimerLock.unlock(); + } + } + } + + private class CleanupExpiredPermitsTask extends TimerTask { + + @Override + public void run() { + final Instant createdAtBefore = + Instant.now().minus(LocalThrottlingServiceImpl.this.timeToLive); + try { + LocalThrottlingServiceImpl.this.resetTimerLock.lock(); + + for (final Entry permitForRequestId : + LocalThrottlingServiceImpl.this.permitsByRequestId.entrySet()) { + final Permit permit = permitForRequestId.getValue(); + if (permit.getCreatedAt().isBefore(createdAtBefore)) { + LOGGER.warn("releasing expired permit: {}", permit); + LocalThrottlingServiceImpl.this.releasePermit(permit); + } + } + + LOGGER.debug( + "ThrottlingService - Timer Cleanup and Unlocking, openConnections available = {} ", + LocalThrottlingServiceImpl.this.openConnectionsSemaphore.availablePermits()); + } finally { + LocalThrottlingServiceImpl.this.resetTimerLock.unlock(); + } + } + } + + @Override + public String toString() { + return String.format( + "ThrottlingService. maxOpenConnections = %d, maxNewConnectionRequests=%d, maxNewConnectionResetTime=%d", + this.maxOpenConnections, this.maxNewConnectionRequests, this.maxNewConnectionResetTime); + } + + private Permit createPermit() { + final int requestId = this.requestIdCounter.incrementAndGet(); + + final Permit permit = new Permit(requestId); + this.permitsByRequestId.put(permit.getRequestId(), permit); + + return permit; + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/throttling/SharedThrottlingServiceImpl.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/throttling/SharedThrottlingServiceImpl.java new file mode 100644 index 00000000000..c24b5b61c2f --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/throttling/SharedThrottlingServiceImpl.java @@ -0,0 +1,38 @@ +/* + * SPDX-FileCopyrightText: Copyright Contributors to the GXF project + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.opensmartgridplatform.adapter.protocol.dlms.application.throttling; + +import org.opensmartgridplatform.adapter.protocol.dlms.application.config.ThrottlingClientConfig; +import org.opensmartgridplatform.adapter.protocol.dlms.application.config.annotation.SharedThrottlingServiceCondition; +import org.opensmartgridplatform.throttling.api.Permit; +import org.springframework.context.annotation.Conditional; +import org.springframework.stereotype.Component; + +@Component +@Conditional(SharedThrottlingServiceCondition.class) +public class SharedThrottlingServiceImpl implements ThrottlingService { + + private final ThrottlingClientConfig throttlingClientConfig; + + public SharedThrottlingServiceImpl(final ThrottlingClientConfig throttlingClientConfig) { + this.throttlingClientConfig = throttlingClientConfig; + } + + @Override + public Permit requestPermit( + final Integer baseTransceiverStationId, final Integer cellId, final Integer priority) { + return this.throttlingClientConfig + .throttlingClient() + .requestPermitUsingNetworkSegmentIfIdsAreAvailable( + baseTransceiverStationId, cellId, priority); + } + + @Override + public void releasePermit(final Permit permit) { + this.throttlingClientConfig.throttlingClient().releasePermit(permit); + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/throttling/ThrottlingService.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/throttling/ThrottlingService.java new file mode 100644 index 00000000000..0588a8d7da1 --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/throttling/ThrottlingService.java @@ -0,0 +1,17 @@ +/* + * SPDX-FileCopyrightText: Copyright Contributors to the GXF project + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.opensmartgridplatform.adapter.protocol.dlms.application.throttling; + +import org.opensmartgridplatform.throttling.api.Permit; + +public interface ThrottlingService { + + Permit requestPermit( + final Integer baseTransceiverStationId, final Integer cellId, Integer priority); + + void releasePermit(Permit permit); +} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/wsclient/SecretManagementClient.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/wsclient/SecretManagementClient.java index a8a69d2a815..fad4a5a64b8 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/wsclient/SecretManagementClient.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/application/wsclient/SecretManagementClient.java @@ -99,7 +99,7 @@ public ActivateSecretsResponse activateSecretsRequest( public HasNewSecretResponse hasNewSecretRequest( final MessageMetadata messageMetadata, final HasNewSecretRequest request) { log.info( - "Calling SecretManagement.hasNewSecretsRequest over SOAP for device {}", + "Calling SecretManagement.hasNewSecretRequest over SOAP for device {}", request.getDeviceId()); return (HasNewSecretResponse) diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/AbstractCommandExecutor.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/AbstractCommandExecutor.java index 5a2824daf68..7fb8010f72c 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/AbstractCommandExecutor.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/AbstractCommandExecutor.java @@ -29,6 +29,8 @@ public abstract class AbstractCommandExecutor implements CommandExecutor bundleExecutorMapKey; /** diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/AlarmHelperService.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/AlarmHelperService.java index f93f7b58c50..0d9504b33ae 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/AlarmHelperService.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/AlarmHelperService.java @@ -9,8 +9,8 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectType; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.ByteRegisterConverter; +import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; import org.opensmartgridplatform.dto.valueobjects.smartmetering.AlarmTypeDto; import org.springframework.stereotype.Service; diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/AlarmTypeRegisterLookup.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/AlarmTypeRegisterLookup.java index 519f81a5ada..41d8e6e2edc 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/AlarmTypeRegisterLookup.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/AlarmTypeRegisterLookup.java @@ -8,7 +8,7 @@ import java.util.Set; import java.util.stream.Collectors; import lombok.Getter; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectType; +import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; import org.opensmartgridplatform.dto.valueobjects.smartmetering.AlarmTypeDto; /** diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/ClearAlarmRegisterCommandExecutor.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/ClearAlarmRegisterCommandExecutor.java index 2806a86db29..09c84a4d2c2 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/ClearAlarmRegisterCommandExecutor.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/ClearAlarmRegisterCommandExecutor.java @@ -12,13 +12,14 @@ import org.openmuc.jdlms.SetParameter; import org.openmuc.jdlms.datatypes.DataObject; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.AbstractCommandExecutor; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectConfigService; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectType; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.JdlmsObjectToStringUtil; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.ObjectConfigServiceHelper; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDevice; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.Protocol; import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionManager; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ConnectionException; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; +import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ActionRequestDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ActionResponseDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ClearAlarmRegisterRequestDto; @@ -30,13 +31,14 @@ public class ClearAlarmRegisterCommandExecutor extends AbstractCommandExecutor { - final DlmsObjectConfigService dlmsObjectConfigService; + final ObjectConfigServiceHelper objectConfigServiceHelper; private static final int ALARM_CODE = 0; - public ClearAlarmRegisterCommandExecutor(final DlmsObjectConfigService dlmsObjectConfigService) { + public ClearAlarmRegisterCommandExecutor( + final ObjectConfigServiceHelper objectConfigServiceHelper) { super(ClearAlarmRegisterRequestDto.class); - this.dlmsObjectConfigService = dlmsObjectConfigService; + this.objectConfigServiceHelper = objectConfigServiceHelper; } @Override @@ -68,7 +70,7 @@ public AccessResultCode execute( // Clear alarm 1 final Optional optionalResultCodeAlarm1 = this.clearAlarmRegister(conn, device, DlmsObjectType.ALARM_REGISTER_1); - if (!optionalResultCodeAlarm1.isPresent()) { + if (optionalResultCodeAlarm1.isEmpty()) { throw new ProtocolAdapterException("Unable to find alarm register 1."); } final AccessResultCode resultCodeAlarmRegister1 = optionalResultCodeAlarm1.get(); @@ -79,7 +81,7 @@ public AccessResultCode execute( // Clear alarm 2 final Optional optionalResultCodeAlarm2 = this.clearAlarmRegister(conn, device, DlmsObjectType.ALARM_REGISTER_2); - if (!optionalResultCodeAlarm2.isPresent()) { + if (optionalResultCodeAlarm2.isEmpty()) { return resultCodeAlarmRegister1; } final AccessResultCode resultCodeAlarmRegister2 = optionalResultCodeAlarm2.get(); @@ -96,10 +98,12 @@ public AccessResultCode execute( private Optional clearAlarmRegister( final DlmsConnectionManager conn, final DlmsDevice device, final DlmsObjectType objectType) throws ProtocolAdapterException { + log.debug("clearAlarmRegister {}", objectType); final Optional optAlarmRegisterAttributeAddress = - this.dlmsObjectConfigService.findAttributeAddress(device, objectType, null); + this.objectConfigServiceHelper.findOptionalDefaultAttributeAddress( + Protocol.forDevice(device), objectType); - if (!optAlarmRegisterAttributeAddress.isPresent()) { + if (optAlarmRegisterAttributeAddress.isEmpty()) { return Optional.empty(); } else { final AccessResultCode resultCodeAlarmRegister = diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/ClearMBusStatusOnAllChannelsCommandExecutor.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/ClearMBusStatusOnAllChannelsCommandExecutor.java index 61d91f699e4..60bcd9dc439 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/ClearMBusStatusOnAllChannelsCommandExecutor.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/ClearMBusStatusOnAllChannelsCommandExecutor.java @@ -16,14 +16,15 @@ import org.openmuc.jdlms.SetParameter; import org.openmuc.jdlms.datatypes.DataObject; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.AbstractCommandExecutor; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectConfigService; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectType; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.JdlmsObjectToStringUtil; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.ObjectConfigServiceHelper; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDevice; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.Protocol; import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionManager; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ConnectionException; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; import org.opensmartgridplatform.dlms.interfaceclass.method.MBusClientMethod; +import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ActionRequestDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ActionResponseDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ClearMBusStatusOnAllChannelsRequestDto; @@ -38,13 +39,13 @@ public class ClearMBusStatusOnAllChannelsCommandExecutor private static final int[] CHANNELS = {1, 2, 3, 4}; - final DlmsObjectConfigService dlmsObjectConfigService; + final ObjectConfigServiceHelper config; @Autowired public ClearMBusStatusOnAllChannelsCommandExecutor( - final DlmsObjectConfigService dlmsObjectConfigService) { + final ObjectConfigServiceHelper objectConfigServiceHelper) { super(ClearMBusStatusOnAllChannelsRequestDto.class); - this.dlmsObjectConfigService = dlmsObjectConfigService; + this.config = objectConfigServiceHelper; } @Override @@ -88,15 +89,19 @@ private void clearStatusMaskForChannel( final DlmsConnectionManager conn, final int channel, final DlmsDevice device) throws IOException, ProtocolAdapterException { + final Protocol protocol = Protocol.forDevice(device); + final AttributeAddress readMBusStatusAttributeAddress = - this.dlmsObjectConfigService.getAttributeAddress( - device, DlmsObjectType.READ_MBUS_STATUS, channel); + this.config.findDefaultAttributeAddress( + device, protocol, DlmsObjectType.READ_MBUS_STATUS, channel); + final AttributeAddress clearMBusStatusAttributeAddress = - this.dlmsObjectConfigService.getAttributeAddress( - device, DlmsObjectType.CLEAR_MBUS_STATUS, channel); + this.config.findDefaultAttributeAddress( + device, protocol, DlmsObjectType.CLEAR_MBUS_STATUS, channel); + final AttributeAddress clientSetupMbus = - this.dlmsObjectConfigService.getAttributeAddress( - device, DlmsObjectType.CLIENT_SETUP_MBUS, channel); + this.config.findDefaultAttributeAddress( + device, protocol, DlmsObjectType.MBUS_CLIENT_SETUP, channel); final long statusMask = this.readStatus(conn, channel, readMBusStatusAttributeAddress); if (statusMask == 0L) { diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/ReadAlarmRegisterCommandExecutor.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/ReadAlarmRegisterCommandExecutor.java index 82d7e1a2cad..b82b8c3f502 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/ReadAlarmRegisterCommandExecutor.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/ReadAlarmRegisterCommandExecutor.java @@ -5,6 +5,7 @@ package org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.alarm; import java.io.IOException; +import java.util.HashSet; import java.util.Optional; import java.util.Set; import org.openmuc.jdlms.AccessResultCode; @@ -12,13 +13,14 @@ import org.openmuc.jdlms.GetResult; import org.openmuc.jdlms.datatypes.DataObject; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.AbstractCommandExecutor; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectConfigService; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectType; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.JdlmsObjectToStringUtil; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.ObjectConfigServiceHelper; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDevice; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.Protocol; import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionManager; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ConnectionException; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; +import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ActionRequestDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.AlarmRegisterResponseDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.AlarmTypeDto; @@ -27,7 +29,6 @@ import org.opensmartgridplatform.shared.infra.jms.MessageMetadata; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component @@ -37,13 +38,16 @@ public class ReadAlarmRegisterCommandExecutor private static final Logger LOGGER = LoggerFactory.getLogger(ReadAlarmRegisterCommandExecutor.class); - final DlmsObjectConfigService dlmsObjectConfigService; + final ObjectConfigServiceHelper objectConfigServiceHelper; - @Autowired private AlarmHelperService alarmHelperService; + private final AlarmHelperService alarmHelperService; - public ReadAlarmRegisterCommandExecutor(final DlmsObjectConfigService dlmsObjectConfigService) { + public ReadAlarmRegisterCommandExecutor( + final ObjectConfigServiceHelper objectConfigServiceHelper, + final AlarmHelperService alarmHelperService) { super(ReadAlarmRegisterDataDto.class); - this.dlmsObjectConfigService = dlmsObjectConfigService; + this.objectConfigServiceHelper = objectConfigServiceHelper; + this.alarmHelperService = alarmHelperService; } @Override @@ -68,18 +72,23 @@ public AlarmRegisterResponseDto execute( final ReadAlarmRegisterRequestDto object, final MessageMetadata messageMetadata) throws ProtocolAdapterException { + Set alarmList = new HashSet<>(); - final AttributeAddress alarmRegister1AttributeAddress = - this.dlmsObjectConfigService.getAttributeAddress( - device, DlmsObjectType.ALARM_REGISTER_1, null); + final Protocol protocol = Protocol.forDevice(device); - final Set alarmList = - this.readAlarmRegister( - conn, alarmRegister1AttributeAddress, DlmsObjectType.ALARM_REGISTER_1); + final Optional alarmRegister1AttributeAddress = + this.objectConfigServiceHelper.findOptionalDefaultAttributeAddress( + protocol, DlmsObjectType.ALARM_REGISTER_1); + + if (alarmRegister1AttributeAddress.isPresent()) { + alarmList = + this.readAlarmRegister( + conn, alarmRegister1AttributeAddress.get(), DlmsObjectType.ALARM_REGISTER_1); + } final Optional alarmRegister2AttributeAddress = - this.dlmsObjectConfigService.findAttributeAddress( - device, DlmsObjectType.ALARM_REGISTER_2, null); + this.objectConfigServiceHelper.findOptionalDefaultAttributeAddress( + protocol, DlmsObjectType.ALARM_REGISTER_2); if (alarmRegister2AttributeAddress.isPresent()) { alarmList.addAll( diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/SetAlarmNotificationsCommandExecutor.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/SetAlarmNotificationsCommandExecutor.java index c7fb9cce549..d651ec604a6 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/SetAlarmNotificationsCommandExecutor.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/SetAlarmNotificationsCommandExecutor.java @@ -16,13 +16,14 @@ import org.openmuc.jdlms.SetParameter; import org.openmuc.jdlms.datatypes.DataObject; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.AbstractCommandExecutor; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectConfigService; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectType; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.JdlmsObjectToStringUtil; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.ObjectConfigServiceHelper; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDevice; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.Protocol; import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionManager; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ConnectionException; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; +import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ActionRequestDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ActionResponseDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.AlarmNotificationDto; @@ -42,16 +43,17 @@ public class SetAlarmNotificationsCommandExecutor private static final Logger LOGGER = LoggerFactory.getLogger(SetAlarmNotificationsCommandExecutor.class); private static final int NUMBER_OF_BITS_IN_ALARM_FILTER = 32; + private static final int DEFAULT_ATTRIBUTE_ID = 2; private final AlarmHelperService alarmHelperService = new AlarmHelperService(); - private final DlmsObjectConfigService dlmsObjectConfigService; + private final ObjectConfigServiceHelper objectConfigServiceHelper; @Autowired public SetAlarmNotificationsCommandExecutor( - final DlmsObjectConfigService dlmsObjectConfigService) { + final ObjectConfigServiceHelper objectConfigServiceHelper) { super(SetAlarmNotificationsRequestDto.class); - this.dlmsObjectConfigService = dlmsObjectConfigService; + this.objectConfigServiceHelper = objectConfigServiceHelper; } @Override @@ -82,9 +84,11 @@ public AccessResultCode execute( final MessageMetadata messageMetadata) throws ProtocolAdapterException { + final Protocol protocol = Protocol.forDevice(device); + final AttributeAddress alarmFilter1AttributeAddress = - this.dlmsObjectConfigService.getAttributeAddress( - device, DlmsObjectType.ALARM_FILTER_1, null); + this.objectConfigServiceHelper.findAttributeAddress( + device, protocol, DlmsObjectType.ALARM_FILTER_1, null, DEFAULT_ATTRIBUTE_ID); final AccessResultCode resultCodeAlarmFilter1 = this.setAlarmNotifications( @@ -94,8 +98,8 @@ public AccessResultCode execute( DlmsObjectType.ALARM_REGISTER_1); final Optional alarmFilter2AttributeAddress = - this.dlmsObjectConfigService.findAttributeAddress( - device, DlmsObjectType.ALARM_FILTER_2, null); + this.objectConfigServiceHelper.findOptionalDefaultAttributeAddress( + protocol, DlmsObjectType.ALARM_FILTER_2); if (alarmFilter2AttributeAddress.isPresent()) { final AccessResultCode accessResultCode = @@ -110,8 +114,8 @@ public AccessResultCode execute( } final Optional alarmFilter3AttributeAddress = - this.dlmsObjectConfigService.findAttributeAddress( - device, DlmsObjectType.ALARM_FILTER_3, null); + this.objectConfigServiceHelper.findOptionalDefaultAttributeAddress( + protocol, DlmsObjectType.ALARM_FILTER_3); if (alarmFilter3AttributeAddress.isPresent()) { return this.setAlarmNotifications( diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/TestAlarmSchedulerCommandExecutor.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/TestAlarmSchedulerCommandExecutor.java index 9e1a3846a1b..e105384610c 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/TestAlarmSchedulerCommandExecutor.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/TestAlarmSchedulerCommandExecutor.java @@ -17,21 +17,20 @@ import org.openmuc.jdlms.datatypes.CosemTime; import org.openmuc.jdlms.datatypes.DataObject; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.AbstractCommandExecutor; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectConfigService; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectType; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.model.DlmsObject; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.DlmsDateTimeConverter; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.ObjectConfigServiceHelper; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDevice; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.Protocol; import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionManager; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ConnectionException; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; import org.opensmartgridplatform.dlms.interfaceclass.attribute.SingleActionScheduleAttribute; +import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ActionRequestDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ActionResponseDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.TestAlarmSchedulerRequestDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.TestAlarmTypeDto; import org.opensmartgridplatform.shared.infra.jms.MessageMetadata; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component @@ -39,10 +38,12 @@ public class TestAlarmSchedulerCommandExecutor extends AbstractCommandExecutor { - @Autowired private DlmsObjectConfigService dlmsObjectConfigService; + private final ObjectConfigServiceHelper objectConfigServiceHelper; - public TestAlarmSchedulerCommandExecutor() { + public TestAlarmSchedulerCommandExecutor( + final ObjectConfigServiceHelper objectConfigServiceHelper) { super(TestAlarmSchedulerRequestDto.class); + this.objectConfigServiceHelper = objectConfigServiceHelper; } @Override @@ -79,17 +80,19 @@ public AccessResultCode execute( final DlmsObjectType alarmObjectType = toAlarmObjectType(alarmTypeDto); - final DlmsObject dlmsObject = - this.dlmsObjectConfigService.getDlmsObject(device, alarmObjectType); - final DateTime convertedDateTime = - DlmsDateTimeConverter.toDateTime(scheduleDate, device.getTimezone()); + final Protocol protocol = Protocol.forDevice(device); final AttributeAddress attributeAddress = - new AttributeAddress( - dlmsObject.getClassId(), - dlmsObject.getObisCode(), + this.objectConfigServiceHelper.findAttributeAddress( + device, + protocol, + alarmObjectType, + null, SingleActionScheduleAttribute.EXECUTION_TIME.attributeId()); + final DateTime convertedDateTime = + DlmsDateTimeConverter.toDateTime(scheduleDate, device.getTimezone()); + final DataObject timeDataObject = getDataObjectTime(convertedDateTime); final DataObject dateDataObject = getDataObjectDate(convertedDateTime); diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/GetConfigurationObjectCommandExecutor.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/GetConfigurationObjectCommandExecutor.java index 5bdd13ba874..0826143ea0b 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/GetConfigurationObjectCommandExecutor.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/GetConfigurationObjectCommandExecutor.java @@ -49,8 +49,9 @@ public ConfigurationObjectDto execute( final Void object, final MessageMetadata messageMetadata) throws ProtocolAdapterException { + final Protocol protocol = Protocol.forDevice(device); return this.protocolServiceLookup - .lookupGetService(Protocol.forDevice(device)) - .getConfigurationObject(conn); + .lookupGetService(protocol) + .getConfigurationObject(conn, protocol); } } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/SetConfigurationObjectCommandExecutor.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/SetConfigurationObjectCommandExecutor.java index 13a00143e40..7119d15b6d7 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/SetConfigurationObjectCommandExecutor.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/SetConfigurationObjectCommandExecutor.java @@ -57,9 +57,11 @@ public AccessResultCode execute( final Protocol protocol = Protocol.forDevice(device); final GetConfigurationObjectService getService = this.protocolServiceLookup.lookupGetService(protocol); - final ConfigurationObjectDto configurationOnDevice = getService.getConfigurationObject(conn); + final ConfigurationObjectDto configurationOnDevice = + getService.getConfigurationObject(conn, protocol); final SetConfigurationObjectService setService = this.protocolServiceLookup.lookupSetService(protocol); - return setService.setConfigurationObject(conn, configurationToSet, configurationOnDevice); + return setService.setConfigurationObject( + conn, configurationToSet, configurationOnDevice, protocol); } } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/SetRandomisationSettingsCommandExecutor.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/SetRandomisationSettingsCommandExecutor.java index 6f978caebd9..7f0608d23b5 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/SetRandomisationSettingsCommandExecutor.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/SetRandomisationSettingsCommandExecutor.java @@ -15,13 +15,13 @@ import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.configuration.service.GetConfigurationObjectService; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.configuration.service.ProtocolServiceLookup; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.configuration.service.SetConfigurationObjectService; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectConfigService; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectType; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.ObjectConfigServiceHelper; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDevice; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.Protocol; import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionManager; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ConnectionException; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; +import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ActionRequestDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ActionResponseDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ConfigurationFlagDto; @@ -42,16 +42,16 @@ public class SetRandomisationSettingsCommandExecutor private static final Logger LOGGER = LoggerFactory.getLogger(SetRandomisationSettingsCommandExecutor.class); - private final DlmsObjectConfigService dlmsObjectConfigService; private final ProtocolServiceLookup protocolServiceLookup; + private final ObjectConfigServiceHelper objectConfigServiceHelper; @Autowired public SetRandomisationSettingsCommandExecutor( - final DlmsObjectConfigService dlmsObjectConfigService, - final ProtocolServiceLookup protocolServiceLookup) { + final ProtocolServiceLookup protocolServiceLookup, + final ObjectConfigServiceHelper objectConfigServiceHelper) { super(SetRandomisationSettingsRequestDataDto.class); - this.dlmsObjectConfigService = dlmsObjectConfigService; this.protocolServiceLookup = protocolServiceLookup; + this.objectConfigServiceHelper = objectConfigServiceHelper; } @Override @@ -109,9 +109,9 @@ private void writeRandomisationSettings( final int multiplicationFactor, final int numberOfRetries) throws ProtocolAdapterException { - final AttributeAddress randomisationSettingsAddress = - this.dlmsObjectConfigService.getAttributeAddress( - device, DlmsObjectType.RANDOMISATION_SETTINGS, null); + + final Protocol protocol = Protocol.forDevice(device); + final AttributeAddress attributeAddress = this.getAttributeAddress(protocol); final DataObject randomisationStartWindowObject = DataObject.newUInteger32Data(randomisationStartWindow); @@ -122,12 +122,21 @@ private void writeRandomisationSettings( final DataObject randomisationSettingsObject = DataObject.newStructureData( randomisationStartWindowObject, multiplicationFactorObject, numberOfRetriesObject); - final SetParameter setRandomisationSettings = - new SetParameter(randomisationSettingsAddress, randomisationSettingsObject); + new SetParameter(attributeAddress, randomisationSettingsObject); + this.writeAttribute(conn, setRandomisationSettings); } + AttributeAddress getAttributeAddress(final Protocol protocol) throws ProtocolAdapterException { + return this.objectConfigServiceHelper + .findOptionalDefaultAttributeAddress(protocol, DlmsObjectType.RANDOMISATION_SETTINGS) + .orElseThrow( + () -> + new ProtocolAdapterException( + "No object configuration found for RANDOMISATION_SETTINGS")); + } + private void writeDirectAttach( final DlmsConnectionManager conn, final DlmsDevice device, final boolean directAttach) throws ProtocolAdapterException { @@ -136,7 +145,7 @@ private void writeDirectAttach( final GetConfigurationObjectService getConfigurationObjectService = this.protocolServiceLookup.lookupGetService(protocol); final ConfigurationObjectDto configurationOnDevice = - getConfigurationObjectService.getConfigurationObject(conn); + getConfigurationObjectService.getConfigurationObject(conn, protocol); final SetConfigurationObjectService setService = this.protocolServiceLookup.lookupSetService(protocol); @@ -144,7 +153,8 @@ private void writeDirectAttach( this.createNewConfiguration(directAttach, configurationOnDevice); final AccessResultCode result = - setService.setConfigurationObject(conn, configurationToSet, configurationOnDevice); + setService.setConfigurationObject( + conn, configurationToSet, configurationOnDevice, protocol); this.checkResult(result, "directAttach"); } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/AttributeAddressFactory.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/AttributeAddressFactory.java deleted file mode 100644 index 56e52e3b316..00000000000 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/AttributeAddressFactory.java +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-FileCopyrightText: Copyright Contributors to the GXF project -// -// SPDX-License-Identifier: Apache-2.0 - -package org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.configuration.service; - -import org.openmuc.jdlms.AttributeAddress; -import org.openmuc.jdlms.ObisCode; - -public class AttributeAddressFactory { - - private static final int CLASS_ID = 1; - private static final ObisCode OBIS_CODE = new ObisCode("0.1.94.31.3.255"); - private static final int ATTRIBUTE_ID = 2; - - private AttributeAddressFactory() { - // do not instantiate utility class - } - - public static AttributeAddress getConfigurationObjectAddress() { - return new AttributeAddress(CLASS_ID, OBIS_CODE, ATTRIBUTE_ID); - } -} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/GetConfigurationObjectService.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/GetConfigurationObjectService.java index f734085d928..1a2676bb285 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/GetConfigurationObjectService.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/GetConfigurationObjectService.java @@ -12,6 +12,7 @@ import org.openmuc.jdlms.AttributeAddress; import org.openmuc.jdlms.GetResult; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.JdlmsObjectToStringUtil; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.Protocol; import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionManager; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ConnectionException; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; @@ -25,10 +26,11 @@ public abstract class GetConfigurationObjectService implements ProtocolService { private static final Logger LOGGER = LoggerFactory.getLogger(GetConfigurationObjectService.class); - public ConfigurationObjectDto getConfigurationObject(final DlmsConnectionManager conn) - throws ProtocolAdapterException { - final AttributeAddress attributeAddress = - AttributeAddressFactory.getConfigurationObjectAddress(); + public ConfigurationObjectDto getConfigurationObject( + final DlmsConnectionManager conn, final Protocol protocol) throws ProtocolAdapterException { + + final AttributeAddress attributeAddress = this.getAttributeAddress(protocol); + conn.getDlmsMessageListener() .setDescription( String.format( @@ -37,6 +39,9 @@ public ConfigurationObjectDto getConfigurationObject(final DlmsConnectionManager return this.getConfigurationObject(this.getGetResult(conn, attributeAddress)); } + abstract AttributeAddress getAttributeAddress(final Protocol protocol) + throws ProtocolAdapterException; + private GetResult getGetResult( final DlmsConnectionManager conn, final AttributeAddress attributeAddress) throws ProtocolAdapterException { diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/GetConfigurationObjectServiceDsmr4.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/GetConfigurationObjectServiceDsmr4.java index 2f0aa2e270e..7d883d74492 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/GetConfigurationObjectServiceDsmr4.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/GetConfigurationObjectServiceDsmr4.java @@ -6,12 +6,15 @@ import java.util.List; import java.util.Optional; +import org.openmuc.jdlms.AttributeAddress; import org.openmuc.jdlms.GetResult; import org.openmuc.jdlms.datatypes.BitString; import org.openmuc.jdlms.datatypes.DataObject; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.DlmsHelper; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.ObjectConfigServiceHelper; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.Protocol; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; +import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ConfigurationFlagDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ConfigurationFlagTypeDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ConfigurationFlagsDto; @@ -33,13 +36,17 @@ public class GetConfigurationObjectServiceDsmr4 extends GetConfigurationObjectSe private final DlmsHelper dlmsHelper; - public GetConfigurationObjectServiceDsmr4(final DlmsHelper dlmsHelper) { + private final ObjectConfigServiceHelper objectConfigServiceHelper; + + public GetConfigurationObjectServiceDsmr4( + final DlmsHelper dlmsHelper, final ObjectConfigServiceHelper objectConfigServiceHelper) { this.dlmsHelper = dlmsHelper; + this.objectConfigServiceHelper = objectConfigServiceHelper; } @Override public boolean handles(final Protocol protocol) { - return protocol == Protocol.DSMR_4_2_2; + return protocol != null && protocol.isDsmr42(); } @Override @@ -115,4 +122,11 @@ private ConfigurationFlagsDto getConfigurationFlags(final DataObject flags) Optional getFlagType(final int bitPosition) { return ConfigurationFlagTypeDto.getDsmr4FlagType(bitPosition); } + + @Override + AttributeAddress getAttributeAddress(final Protocol protocol) throws ProtocolAdapterException { + return this.objectConfigServiceHelper + .findOptionalDefaultAttributeAddress(protocol, DlmsObjectType.CONFIGURATION_OBJECT) + .orElseThrow(); + } } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/GetConfigurationObjectServiceDsmr43.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/GetConfigurationObjectServiceDsmr43.java new file mode 100644 index 00000000000..647b5b55581 --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/GetConfigurationObjectServiceDsmr43.java @@ -0,0 +1,31 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.configuration.service; + +import java.util.Optional; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.DlmsHelper; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.ObjectConfigServiceHelper; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.Protocol; +import org.opensmartgridplatform.dto.valueobjects.smartmetering.ConfigurationFlagTypeDto; +import org.springframework.stereotype.Component; + +@Component +public class GetConfigurationObjectServiceDsmr43 extends GetConfigurationObjectServiceDsmr4 { + + public GetConfigurationObjectServiceDsmr43( + final DlmsHelper dlmsHelper, final ObjectConfigServiceHelper objectConfigServiceHelper) { + super(dlmsHelper, objectConfigServiceHelper); + } + + @Override + public boolean handles(final Protocol protocol) { + return protocol != null && protocol.isDsmr43(); + } + + @Override + Optional getFlagType(final int bitPosition) { + return ConfigurationFlagTypeDto.getDsmr43FlagType(bitPosition); + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/GetConfigurationObjectServiceSmr5.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/GetConfigurationObjectServiceSmr5.java index a4ebe0c96ac..70e11860e1f 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/GetConfigurationObjectServiceSmr5.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/GetConfigurationObjectServiceSmr5.java @@ -6,12 +6,15 @@ import java.util.List; import java.util.Optional; +import org.openmuc.jdlms.AttributeAddress; import org.openmuc.jdlms.GetResult; import org.openmuc.jdlms.datatypes.BitString; import org.openmuc.jdlms.datatypes.DataObject; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.DlmsHelper; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.ObjectConfigServiceHelper; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.Protocol; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; +import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ConfigurationFlagDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ConfigurationFlagTypeDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ConfigurationFlagsDto; @@ -28,8 +31,12 @@ public class GetConfigurationObjectServiceSmr5 extends GetConfigurationObjectSer private final DlmsHelper dlmsHelper; - public GetConfigurationObjectServiceSmr5(final DlmsHelper dlmsHelper) { + private final ObjectConfigServiceHelper objectConfigServiceHelper; + + public GetConfigurationObjectServiceSmr5( + final DlmsHelper dlmsHelper, final ObjectConfigServiceHelper objectConfigServiceHelper) { this.dlmsHelper = dlmsHelper; + this.objectConfigServiceHelper = objectConfigServiceHelper; } @Override @@ -65,4 +72,11 @@ ConfigurationObjectDto getConfigurationObject(final GetResult result) Optional getFlagType(final int bitPosition) { return ConfigurationFlagTypeDto.getSmr5FlagType(bitPosition); } + + @Override + AttributeAddress getAttributeAddress(final Protocol protocol) throws ProtocolAdapterException { + return this.objectConfigServiceHelper + .findOptionalDefaultAttributeAddress(protocol, DlmsObjectType.CONFIGURATION_OBJECT) + .orElseThrow(); + } } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/SetConfigurationObjectService.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/SetConfigurationObjectService.java index 126fdc663c3..8a124f2e951 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/SetConfigurationObjectService.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/SetConfigurationObjectService.java @@ -16,6 +16,7 @@ import org.openmuc.jdlms.datatypes.DataObject; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.DlmsHelper; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.JdlmsObjectToStringUtil; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.Protocol; import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionManager; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ConnectionException; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.NotSupportedByProtocolException; @@ -30,6 +31,7 @@ public abstract class SetConfigurationObjectService implements ProtocolService { private static final Logger LOGGER = LoggerFactory.getLogger(SetConfigurationObjectService.class); + private static final int NUMBER_OF_FLAG_BITS = 16; private static final int BYTE_SIZE = 8; @@ -42,7 +44,8 @@ public abstract class SetConfigurationObjectService implements ProtocolService { public AccessResultCode setConfigurationObject( final DlmsConnectionManager conn, final ConfigurationObjectDto configurationToSet, - final ConfigurationObjectDto configurationOnDevice) + final ConfigurationObjectDto configurationOnDevice, + final Protocol protocol) throws ProtocolAdapterException { final DataObject dataObject = @@ -50,8 +53,8 @@ public AccessResultCode setConfigurationObject( LOGGER.debug( "ConfigurationObject SetParameter Data : {}", this.dlmsHelper.getDebugInfo(dataObject)); - final AttributeAddress attributeAddress = - AttributeAddressFactory.getConfigurationObjectAddress(); + final AttributeAddress attributeAddress = this.getAttributeAddress(protocol); + final SetParameter setParameter = new SetParameter(attributeAddress, dataObject); conn.getDlmsMessageListener() .setDescription( @@ -60,6 +63,9 @@ public AccessResultCode setConfigurationObject( return this.getAccessResultCode(conn, setParameter); } + abstract AttributeAddress getAttributeAddress(final Protocol protocol) + throws ProtocolAdapterException; + private AccessResultCode getAccessResultCode( final DlmsConnectionManager conn, final SetParameter setParameter) { LOGGER.debug("Set ConfigurationObject using SetParameter {}", setParameter); diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/SetConfigurationObjectServiceDsmr4.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/SetConfigurationObjectServiceDsmr4.java index 8e9253a6e74..301460e8524 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/SetConfigurationObjectServiceDsmr4.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/SetConfigurationObjectServiceDsmr4.java @@ -7,11 +7,14 @@ import java.util.LinkedList; import java.util.List; import java.util.Optional; +import org.openmuc.jdlms.AttributeAddress; import org.openmuc.jdlms.datatypes.BitString; import org.openmuc.jdlms.datatypes.DataObject; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.DlmsHelper; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.ObjectConfigServiceHelper; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.Protocol; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; +import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ConfigurationFlagTypeDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ConfigurationObjectDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.GprsOperationModeTypeDto; @@ -20,13 +23,17 @@ @Component public class SetConfigurationObjectServiceDsmr4 extends SetConfigurationObjectService { - public SetConfigurationObjectServiceDsmr4(final DlmsHelper dlmsHelper) { + private final ObjectConfigServiceHelper objectConfigServiceHelper; + + public SetConfigurationObjectServiceDsmr4( + final DlmsHelper dlmsHelper, final ObjectConfigServiceHelper objectConfigServiceHelper) { super(dlmsHelper); + this.objectConfigServiceHelper = objectConfigServiceHelper; } @Override public boolean handles(final Protocol protocol) { - return protocol == Protocol.DSMR_4_2_2; + return protocol != null && protocol.isDsmr42(); } @Override @@ -70,4 +77,11 @@ private void addFlags( Optional getBitPosition(final ConfigurationFlagTypeDto type) { return type.getBitPositionDsmr4(); } + + @Override + AttributeAddress getAttributeAddress(final Protocol protocol) throws ProtocolAdapterException { + return this.objectConfigServiceHelper + .findOptionalDefaultAttributeAddress(protocol, DlmsObjectType.CONFIGURATION_OBJECT) + .orElseThrow(); + } } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/SetConfigurationObjectServiceDsmr43.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/SetConfigurationObjectServiceDsmr43.java new file mode 100644 index 00000000000..130ce825b27 --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/SetConfigurationObjectServiceDsmr43.java @@ -0,0 +1,31 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.configuration.service; + +import java.util.Optional; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.DlmsHelper; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.ObjectConfigServiceHelper; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.Protocol; +import org.opensmartgridplatform.dto.valueobjects.smartmetering.ConfigurationFlagTypeDto; +import org.springframework.stereotype.Component; + +@Component +public class SetConfigurationObjectServiceDsmr43 extends SetConfigurationObjectServiceDsmr4 { + + public SetConfigurationObjectServiceDsmr43( + final DlmsHelper dlmsHelper, final ObjectConfigServiceHelper objectConfigServiceHelper) { + super(dlmsHelper, objectConfigServiceHelper); + } + + @Override + public boolean handles(final Protocol protocol) { + return protocol != null && protocol.isDsmr43(); + } + + @Override + Optional getBitPosition(final ConfigurationFlagTypeDto type) { + return type.getBitPositionDsmr43(); + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/SetConfigurationObjectServiceSmr5.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/SetConfigurationObjectServiceSmr5.java index f2a542265a5..fab362e1fc7 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/SetConfigurationObjectServiceSmr5.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/SetConfigurationObjectServiceSmr5.java @@ -5,10 +5,13 @@ package org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.configuration.service; import java.util.Optional; +import org.openmuc.jdlms.AttributeAddress; import org.openmuc.jdlms.datatypes.DataObject; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.DlmsHelper; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.ObjectConfigServiceHelper; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.Protocol; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; +import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ConfigurationFlagTypeDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ConfigurationObjectDto; import org.springframework.stereotype.Component; @@ -16,8 +19,12 @@ @Component public class SetConfigurationObjectServiceSmr5 extends SetConfigurationObjectService { - public SetConfigurationObjectServiceSmr5(final DlmsHelper dlmsHelper) { + private final ObjectConfigServiceHelper objectConfigServiceHelper; + + public SetConfigurationObjectServiceSmr5( + final DlmsHelper dlmsHelper, final ObjectConfigServiceHelper objectConfigServiceHelper) { super(dlmsHelper); + this.objectConfigServiceHelper = objectConfigServiceHelper; } @Override @@ -37,4 +44,11 @@ DataObject buildSetParameterData( Optional getBitPosition(final ConfigurationFlagTypeDto type) { return type.getBitPositionSmr5(); } + + @Override + AttributeAddress getAttributeAddress(final Protocol protocol) throws ProtocolAdapterException { + return this.objectConfigServiceHelper + .findOptionalDefaultAttributeAddress(protocol, DlmsObjectType.CONFIGURATION_OBJECT) + .orElseThrow(); + } } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/datetime/SetActivityCalendarCommandActivationExecutor.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/datetime/SetActivityCalendarCommandActivationExecutor.java index 075d6f79680..9df83967b81 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/datetime/SetActivityCalendarCommandActivationExecutor.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/datetime/SetActivityCalendarCommandActivationExecutor.java @@ -8,7 +8,6 @@ import org.openmuc.jdlms.MethodParameter; import org.openmuc.jdlms.MethodResult; import org.openmuc.jdlms.MethodResultCode; -import org.openmuc.jdlms.ObisCode; import org.openmuc.jdlms.datatypes.DataObject; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.AbstractCommandExecutor; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.JdlmsObjectToStringUtil; @@ -16,21 +15,28 @@ import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionManager; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ConnectionException; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; +import org.opensmartgridplatform.dlms.exceptions.ObjectConfigException; +import org.opensmartgridplatform.dlms.interfaceclass.method.ActivityCalendarMethod; +import org.opensmartgridplatform.dlms.objectconfig.CosemObject; +import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; +import org.opensmartgridplatform.dlms.services.ObjectConfigService; import org.opensmartgridplatform.shared.infra.jms.MessageMetadata; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -@Component() +@Component public class SetActivityCalendarCommandActivationExecutor extends AbstractCommandExecutor { private static final Logger LOGGER = LoggerFactory.getLogger(SetActivityCalendarCommandActivationExecutor.class); - private static final int CLASS_ID = 20; - private static final ObisCode OBIS_CODE = new ObisCode("0.0.13.0.0.255"); - private static final int METHOD_ID_ACTIVATE_PASSIVE_CALENDAR = 1; + private final ObjectConfigService objectConfigService; + + SetActivityCalendarCommandActivationExecutor(final ObjectConfigService objectConfigService) { + this.objectConfigService = objectConfigService; + } @Override public MethodResultCode execute( @@ -41,11 +47,22 @@ public MethodResultCode execute( throws ProtocolAdapterException { LOGGER.debug("ACTIVATING PASSIVE CALENDAR"); + final CosemObject cosemObject; + try { + cosemObject = + this.objectConfigService.getCosemObject( + device.getProtocolName(), + device.getProtocolVersion(), + DlmsObjectType.ACTIVITY_CALENDAR); + } catch (final ObjectConfigException e) { + throw new ProtocolAdapterException(AbstractCommandExecutor.ERROR_IN_OBJECT_CONFIG, e); + } + final MethodParameter method = new MethodParameter( - CLASS_ID, - OBIS_CODE, - METHOD_ID_ACTIVATE_PASSIVE_CALENDAR, + cosemObject.getClassId(), + cosemObject.getObis(), + ActivityCalendarMethod.ACTIVATE_PASSIVE_CALENDAR.getMethodId(), DataObject.newInteger8Data((byte) 0)); conn.getDlmsMessageListener() @@ -64,11 +81,11 @@ public MethodResultCode execute( "Activating the activity calendar failed. MethodResult is: " + methodResultCode.getResultCode() + " ClassId: " - + CLASS_ID + + cosemObject.getClassId() + " obisCode: " - + OBIS_CODE + + cosemObject.getObis() + " method id: " - + METHOD_ID_ACTIVATE_PASSIVE_CALENDAR); + + ActivityCalendarMethod.ACTIVATE_PASSIVE_CALENDAR.getMethodId()); } return MethodResultCode.SUCCESS; } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/datetime/SetActivityCalendarCommandExecutor.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/datetime/SetActivityCalendarCommandExecutor.java index 4329fd1ee95..f6ff84e15f7 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/datetime/SetActivityCalendarCommandExecutor.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/datetime/SetActivityCalendarCommandExecutor.java @@ -19,6 +19,10 @@ import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDevice; import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionManager; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; +import org.opensmartgridplatform.dlms.exceptions.ObjectConfigException; +import org.opensmartgridplatform.dlms.objectconfig.CosemObject; +import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; +import org.opensmartgridplatform.dlms.services.ObjectConfigService; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ActionRequestDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ActionResponseDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ActivityCalendarDataDto; @@ -40,8 +44,6 @@ public class SetActivityCalendarCommandExecutor private static final Logger LOGGER = LoggerFactory.getLogger(SetActivityCalendarCommandExecutor.class); - private static final int CLASS_ID = 20; - private static final ObisCode OBIS_CODE = new ObisCode("0.0.13.0.0.255"); private static final int ATTRIBUTE_ID_CALENDAR_NAME_PASSIVE = 6; private static final int ATTRIBUTE_ID_SEASON_PROFILE_PASSIVE = 7; private static final int ATTRIBUTE_ID_WEEK_PROFILE_TABLE_PASSIVE = 8; @@ -54,17 +56,21 @@ public class SetActivityCalendarCommandExecutor private final DlmsHelper dlmsHelper; + private final ObjectConfigService objectConfigService; + @Autowired public SetActivityCalendarCommandExecutor( final DlmsHelper dlmsHelper, final SetActivityCalendarCommandActivationExecutor setActivityCalendarCommandActivationExecutor, - final ConfigurationMapper configurationMapper) { + final ConfigurationMapper configurationMapper, + final ObjectConfigService objectConfigService) { super(ActivityCalendarDataDto.class); this.dlmsHelper = dlmsHelper; this.setActivityCalendarCommandActivationExecutor = setActivityCalendarCommandActivationExecutor; this.configurationMapper = configurationMapper; + this.objectConfigService = objectConfigService; } @Override @@ -102,12 +108,24 @@ public AccessResultCode execute( final Set weekProfileSet = this.getWeekProfileSet(seasonProfileList); final Set dayProfileSet = this.getDayProfileSet(weekProfileSet); + final CosemObject cosemObject; + + try { + cosemObject = + this.objectConfigService.getCosemObject( + device.getProtocolName(), + device.getProtocolVersion(), + DlmsObjectType.ACTIVITY_CALENDAR); + } catch (final ObjectConfigException e) { + throw new ProtocolAdapterException(AbstractCommandExecutor.ERROR_IN_OBJECT_CONFIG, e); + } + final DataObjectAttrExecutors dataObjectExecutors = new DataObjectAttrExecutors("SetActivityCalendar") - .addExecutor(this.getCalendarNameExecutor(activityCalendar)) - .addExecutor(this.getSeasonProfileExecutor(seasonProfileList)) - .addExecutor(this.getWeekProfileTableExecutor(weekProfileSet)) - .addExecutor(this.getDayProfileTablePassiveExecutor(dayProfileSet)); + .addExecutor(this.getCalendarNameExecutor(cosemObject, activityCalendar)) + .addExecutor(this.getSeasonProfileExecutor(cosemObject, seasonProfileList)) + .addExecutor(this.getWeekProfileTableExecutor(cosemObject, weekProfileSet)) + .addExecutor(this.getDayProfileTablePassiveExecutor(cosemObject, dayProfileSet)); conn.getDlmsMessageListener() .setDescription( @@ -142,24 +160,29 @@ public AccessResultCode execute( } private DataObjectAttrExecutor getCalendarNameExecutor( - final ActivityCalendarDto activityCalendar) { + final CosemObject cosemObject, final ActivityCalendarDto activityCalendar) { + final AttributeAddress calendarNamePassive = - new AttributeAddress(CLASS_ID, OBIS_CODE, ATTRIBUTE_ID_CALENDAR_NAME_PASSIVE); + new AttributeAddress( + cosemObject.getClassId(), cosemObject.getObis(), ATTRIBUTE_ID_CALENDAR_NAME_PASSIVE); final DataObject value = DataObject.newOctetStringData(activityCalendar.getCalendarName().getBytes()); return new DataObjectAttrExecutor( "CALENDARNAME", calendarNamePassive, value, - CLASS_ID, - OBIS_CODE, + cosemObject.getClassId(), + new ObisCode(cosemObject.getObis()), ATTRIBUTE_ID_CALENDAR_NAME_PASSIVE); } private DataObjectAttrExecutor getDayProfileTablePassiveExecutor( - final Set dayProfileSet) { + final CosemObject cosemObject, final Set dayProfileSet) { final AttributeAddress dayProfileTablePassive = - new AttributeAddress(CLASS_ID, OBIS_CODE, ATTRIBUTE_ID_DAY_PROFILE_TABLE_PASSIVE); + new AttributeAddress( + cosemObject.getClassId(), + cosemObject.getObis(), + ATTRIBUTE_ID_DAY_PROFILE_TABLE_PASSIVE); final DataObject dayArray = DataObject.newArrayData( this.configurationMapper.mapAsList(dayProfileSet, DataObject.class)); @@ -170,8 +193,8 @@ private DataObjectAttrExecutor getDayProfileTablePassiveExecutor( "DAYS", dayProfileTablePassive, dayArray, - CLASS_ID, - OBIS_CODE, + cosemObject.getClassId(), + new ObisCode(cosemObject.getObis()), ATTRIBUTE_ID_DAY_PROFILE_TABLE_PASSIVE); } @@ -187,10 +210,13 @@ private Set getDayProfileSet(final Set weekProfil } private DataObjectAttrExecutor getWeekProfileTableExecutor( - final Set weekProfileSet) { + final CosemObject cosemObject, final Set weekProfileSet) { final AttributeAddress weekProfileTablePassive = - new AttributeAddress(CLASS_ID, OBIS_CODE, ATTRIBUTE_ID_WEEK_PROFILE_TABLE_PASSIVE); + new AttributeAddress( + cosemObject.getClassId(), + cosemObject.getObis(), + ATTRIBUTE_ID_WEEK_PROFILE_TABLE_PASSIVE); final DataObject weekArray = DataObject.newArrayData( this.configurationMapper.mapAsList(weekProfileSet, DataObject.class)); @@ -201,8 +227,8 @@ private DataObjectAttrExecutor getWeekProfileTableExecutor( "WEEKS", weekProfileTablePassive, weekArray, - CLASS_ID, - OBIS_CODE, + cosemObject.getClassId(), + new ObisCode(cosemObject.getObis()), ATTRIBUTE_ID_WEEK_PROFILE_TABLE_PASSIVE); } @@ -218,10 +244,11 @@ private Set getWeekProfileSet(final List seaso } private DataObjectAttrExecutor getSeasonProfileExecutor( - final List seasonProfileList) { + final CosemObject cosemObject, final List seasonProfileList) { final AttributeAddress seasonProfilePassive = - new AttributeAddress(CLASS_ID, OBIS_CODE, ATTRIBUTE_ID_SEASON_PROFILE_PASSIVE); + new AttributeAddress( + cosemObject.getClassId(), cosemObject.getObis(), ATTRIBUTE_ID_SEASON_PROFILE_PASSIVE); final DataObject seasonsArray = DataObject.newArrayData( this.configurationMapper.mapAsList(seasonProfileList, DataObject.class)); @@ -232,8 +259,8 @@ private DataObjectAttrExecutor getSeasonProfileExecutor( "SEASONS", seasonProfilePassive, seasonsArray, - CLASS_ID, - OBIS_CODE, + cosemObject.getClassId(), + new ObisCode(cosemObject.getObis()), ATTRIBUTE_ID_SEASON_PROFILE_PASSIVE); } } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/dlmsobjectconfig/AttributeAddressForProfile.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/dlmsobjectconfig/AttributeAddressForProfile.java index f204bfaea49..71ab07cc293 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/dlmsobjectconfig/AttributeAddressForProfile.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/dlmsobjectconfig/AttributeAddressForProfile.java @@ -4,8 +4,11 @@ package org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig; +import java.util.ArrayList; import java.util.List; import org.openmuc.jdlms.AttributeAddress; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.model.DlmsExtendedRegister; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.model.DlmsObject; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.model.DlmsRegister; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; @@ -41,6 +44,21 @@ public Integer getIndex(final DlmsObjectType type, final Integer attributeId) { return null; } + public Integer getIndex(final DlmsObjectType type, final Integer attributeId, final int channel) { + int index = 0; + + for (final DlmsCaptureObject object : this.selectedObjects) { + if (object.getRelatedObject().getType().equals(type) + && (attributeId == null || object.getAttributeId() == attributeId) + && ((object.getChannel() == null) || (object.getChannel() == channel))) { + return index; + } + index++; + } + + return null; + } + public DlmsCaptureObject getCaptureObject(final DlmsObjectType dlmsObjectType) throws ProtocolAdapterException { return this.selectedObjects.stream() @@ -56,14 +74,51 @@ public DlmsCaptureObject getCaptureObject(final DlmsObjectType dlmsObjectType) public List getCaptureObjects( final Class dlmsObjectClass, final boolean defaultAttributeId) { - return this.selectedObjects.stream() - .filter( - c -> - !defaultAttributeId - || c.getAttributeId() == c.getRelatedObject().getDefaultAttributeId()) - .map(DlmsCaptureObject::getRelatedObject) - .filter(dlmsObjectClass::isInstance) - .map(DlmsRegister.class::cast) - .toList(); + + final List captureObjects = + this.selectedObjects.stream() + .filter( + c -> + !defaultAttributeId + || c.getAttributeId() == c.getRelatedObject().getDefaultAttributeId()) + .toList(); + + final List registers = new ArrayList<>(); + + for (final DlmsCaptureObject captureObject : captureObjects) { + final DlmsObject relatedObject = captureObject.getRelatedObject(); + if (dlmsObjectClass.isInstance(relatedObject)) { + final DlmsRegister originalRegister = (DlmsRegister) relatedObject; + final String obisCode = originalRegister.getObisCodeAsString(); + if (originalRegister instanceof DlmsExtendedRegister) { + final Integer channel = captureObject.getChannel(); + final String obisCodeWithChannel = + channel == null + ? obisCode + : obisCode.replace("", String.valueOf(captureObject.getChannel())); + final DlmsExtendedRegister register = + new DlmsExtendedRegister( + originalRegister.getType(), + obisCodeWithChannel, + originalRegister.getScaler(), + originalRegister.getUnit(), + originalRegister.getMedium()); + + registers.add(register); + } else { + final DlmsRegister register = + new DlmsRegister( + originalRegister.getType(), + obisCode, + originalRegister.getScaler(), + originalRegister.getUnit(), + originalRegister.getMedium()); + + registers.add(register); + } + } + } + + return registers; } } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/dlmsobjectconfig/DlmsCaptureObject.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/dlmsobjectconfig/DlmsCaptureObject.java index 2a972de9f33..a47c37f9d16 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/dlmsobjectconfig/DlmsCaptureObject.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/dlmsobjectconfig/DlmsCaptureObject.java @@ -46,6 +46,10 @@ public static DlmsCaptureObject createWithChannel( return new DlmsCaptureObject(relatedObject, attributeId, channel); } + public Integer getChannel() { + return this.channel; + } + public DlmsObject getRelatedObject() { return this.relatedObject; } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/dlmsobjectconfig/DlmsObjectConfigDsmr422.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/dlmsobjectconfig/DlmsObjectConfigDsmr422.java index 74010b23b28..05536d9fba9 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/dlmsobjectconfig/DlmsObjectConfigDsmr422.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/dlmsobjectconfig/DlmsObjectConfigDsmr422.java @@ -70,7 +70,7 @@ public class DlmsObjectConfigDsmr422 extends DlmsObjectConfig { @Override List initProtocols() { - return Arrays.asList(Protocol.DSMR_4_2_2, Protocol.OTHER_PROTOCOL); + return Arrays.asList(Protocol.DSMR_2_2, Protocol.DSMR_4_2_2, Protocol.OTHER_PROTOCOL); } @Override diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/dlmsobjectconfig/DlmsObjectConfigService.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/dlmsobjectconfig/DlmsObjectConfigService.java index 3538e723691..dd37411a403 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/dlmsobjectconfig/DlmsObjectConfigService.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/dlmsobjectconfig/DlmsObjectConfigService.java @@ -6,6 +6,7 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Optional; import org.joda.time.DateTime; @@ -43,7 +44,7 @@ public AttributeAddress getAttributeAddress( throws ProtocolAdapterException { // Note: channel can be null. final Optional optionalAttributeAddress = - this.findAttributeAddressForProfile(device, type, channel, null, null, null) + this.findAttributeAddressForProfile(device, type, channel) .map(AttributeAddressForProfile::getAttributeAddress); return optionalAttributeAddress.orElseThrow( @@ -57,7 +58,7 @@ public AttributeAddress getAttributeAddress( public Optional findAttributeAddress( final DlmsDevice device, final DlmsObjectType type, final Integer channel) { // Note: channel can be null. - return this.findAttributeAddressForProfile(device, type, channel, null, null, null) + return this.findAttributeAddressForProfile(device, type, channel) .map(AttributeAddressForProfile::getAttributeAddress); } @@ -67,12 +68,23 @@ public Optional findAttributeAddressForProfile( final Integer channel, final DateTime from, final DateTime to, - final Medium filterMedium) { + final Medium filterMedium, + final boolean selectiveAccessSupported) { return this.findDlmsObject(Protocol.forDevice(device), type, filterMedium) .map( dlmsObject -> this.getAttributeAddressForProfile( - new AddressRequest(device, dlmsObject, channel, from, to, filterMedium))); + new AddressRequest(device, dlmsObject, channel, from, to, filterMedium), + selectiveAccessSupported)); + } + + public Optional findAttributeAddressForProfile( + final DlmsDevice device, final DlmsObjectType type, final Integer channel) { + return this.findDlmsObject(Protocol.forDevice(device), type, null) + .map( + dlmsObject -> + this.getAttributeAddressForProfile( + new AddressRequest(device, dlmsObject, channel, null, null, null), true)); } public Optional findDlmsObject( @@ -140,11 +152,12 @@ public List getAttributeAddressesForScalerUnit( } private AttributeAddressForProfile getAttributeAddressForProfile( - final AddressRequest addressRequest) { - final List selectedObjects = new ArrayList<>(); + final AddressRequest addressRequest, final boolean selectedValuesSupported) { + final List selectedObjects = + this.getSelectedCaptureObjects(addressRequest, selectedValuesSupported); final SelectiveAccessDescription access = - this.getAccessDescription(addressRequest, selectedObjects); + this.getAccessDescription(addressRequest, selectedObjects, selectedValuesSupported); final DlmsObject dlmsObject = addressRequest.getDlmsObject(); @@ -166,7 +179,9 @@ private ObisCode replaceChannel(String obisCode, final Integer channel) { } private SelectiveAccessDescription getAccessDescription( - final AddressRequest addressRequest, final List selectedObjects) { + final AddressRequest addressRequest, + final List selectedObjects, + final boolean selectiveAccessSupported) { final DlmsObject object = addressRequest.getDlmsObject(); final DateTime from = addressRequest.getFrom(); @@ -177,52 +192,62 @@ private SelectiveAccessDescription getAccessDescription( } else { final int accessSelector = 1; - final DataObject selectedValues = this.getSelectedValues(addressRequest, selectedObjects); + final DataObject selectedValues = + this.getSelectedValuesObject(addressRequest, selectedObjects); final DataObject accessParameter = - this.dlmsHelper.getAccessSelectionTimeRangeParameter(from, to, selectedValues); + this.dlmsHelper.getAccessSelectionTimeRangeParameter( + from, + to, + selectiveAccessSupported + ? selectedValues + : DataObject.newArrayData(Collections.emptyList())); return new SelectiveAccessDescription(accessSelector, accessParameter); } } - private DataObject getSelectedValues( - final AddressRequest addressRequest, final List selectedObjects) { - List objectDefinitions = new ArrayList<>(); - + private List getSelectedCaptureObjects( + final AddressRequest addressRequest, final boolean selectedValuesSupported) { final DlmsObject object = addressRequest.getDlmsObject(); - final Protocol protocol = Protocol.forDevice(addressRequest.getDevice()); - - if (object instanceof DlmsProfile && ((DlmsProfile) object).getCaptureObjects() != null) { - - final DlmsProfile profile = (DlmsProfile) object; - objectDefinitions = - this.getObjectDefinitions( - addressRequest.getChannel(), - addressRequest.getFilterMedium(), - protocol, - profile, - selectedObjects); + + if (object instanceof final DlmsProfile profile && profile.getCaptureObjects() != null) { + if (selectedValuesSupported) { + return profile.getCaptureObjects().stream() + .filter( + o -> + o.getRelatedObject().mediumMatches(addressRequest.getFilterMedium()) + && o.channelMatches(addressRequest.getChannel())) + .toList(); + } else { + return profile.getCaptureObjects(); + } + } else { + return List.of(); } + } - return DataObject.newArrayData(objectDefinitions); + private DataObject getSelectedValuesObject( + final AddressRequest addressRequest, final List selectedObjects) { + if (selectedObjects.size() + == ((DlmsProfile) addressRequest.getDlmsObject()).getCaptureObjects().size()) { + // If all capture objects are selected then return an empty list (which means select all) + return DataObject.newArrayData(List.of()); + } else { + final List objectDefinitions = + this.getObjectDefinitions(addressRequest.getChannel(), selectedObjects); + + return DataObject.newArrayData(objectDefinitions); + } } private List getObjectDefinitions( - final Integer channel, - final Medium filterMedium, - final Protocol protocol, - final DlmsProfile profile, - final List selectedObjects) { + final Integer channel, final List selectedObjects) { final List objectDefinitions = new ArrayList<>(); - for (final DlmsCaptureObject captureObject : profile.getCaptureObjects()) { + for (final DlmsCaptureObject captureObject : selectedObjects) { final DlmsObject relatedObject = captureObject.getRelatedObject(); - if (!relatedObject.mediumMatches(filterMedium) || !captureObject.channelMatches(channel)) { - continue; - } - // Create and add object definition for this capture object final ObisCode obisCode = this.replaceChannel(relatedObject.getObisCodeAsString(), channel); objectDefinitions.add( @@ -232,17 +257,6 @@ private List getObjectDefinitions( DataObject.newOctetStringData(obisCode.bytes()), DataObject.newInteger8Data((byte) captureObject.getAttributeId()), DataObject.newUInteger16Data(0)))); - - // Add object to selected object list - if (selectedObjects != null) { - selectedObjects.add(captureObject); - } - } - - if (profile.getCaptureObjects().size() == objectDefinitions.size() - || !protocol.isSelectValuesInSelectiveAccessSupported()) { - // If all capture objects are selected then return an empty list (which means select all) - objectDefinitions.clear(); } return objectDefinitions; diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/dlmsobjectconfig/DlmsObjectConfigSmr50.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/dlmsobjectconfig/DlmsObjectConfigSmr50.java index 8ded2492325..8adf873e8a2 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/dlmsobjectconfig/DlmsObjectConfigSmr50.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/dlmsobjectconfig/DlmsObjectConfigSmr50.java @@ -33,6 +33,7 @@ import static org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectType.POWER_QUALITY_EVENT_LOG; import static org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectType.PUSH_SCHEDULER; import static org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectType.PUSH_SETUP_ALARM; +import static org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectType.PUSH_SETUP_CSD_SMS; import static org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectType.PUSH_SETUP_SCHEDULER; import static org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectType.RANDOMISATION_SETTINGS; import static org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectType.READ_MBUS_STATUS; @@ -112,6 +113,7 @@ List initObjects() { final DlmsObject internalTriggerAlarm = new DlmsRegisterMonitor(INTERNAL_TRIGGER_ALARM, "0.0.16.1.0.255"); final DlmsObject pushSetupAlarm = new DlmsPushSetup(PUSH_SETUP_ALARM, "0.1.25.9.0.255"); + final DlmsObject pushSetupCsdSms = new DlmsPushSetup(PUSH_SETUP_CSD_SMS, "0.2.25.9.0.255"); final DlmsObject schedulePhaseOutageTestAlarm = new DlmsSingleActionSchedule(PHASE_OUTAGE_TEST, "0.0.15.1.4.255"); @@ -122,6 +124,7 @@ List initObjects() { externalTriggerSmsOrCsd, internalTriggerAlarm, pushSetupAlarm, + pushSetupCsdSms, schedulePhaseOutageTestAlarm)); final DlmsObject standardEventLogCode = new DlmsData(STANDARD_EVENT_CODE, "0.0.96.11.0.255"); diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/dlmsobjectconfig/DlmsObjectType.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/dlmsobjectconfig/DlmsObjectType.java index e637b8e47c4..183b2324642 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/dlmsobjectconfig/DlmsObjectType.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/dlmsobjectconfig/DlmsObjectType.java @@ -18,6 +18,7 @@ public enum DlmsObjectType { PUSH_SCHEDULER(null), PUSH_SETUP_SCHEDULER(null), PUSH_SETUP_ALARM(null), + PUSH_SETUP_CSD_SMS(null), PUSH_SETUP_UDP(null), EXTERNAL_TRIGGER(null), EXTERNAL_TRIGGER_SMS(null), diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/firmware/ImageTransfer.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/firmware/ImageTransfer.java index 36752a09ff2..dba4b230f60 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/firmware/ImageTransfer.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/firmware/ImageTransfer.java @@ -84,6 +84,10 @@ public boolean shouldTransferImage() throws OsgpException { return this.isImageTransferStatusIn(ImageTransferStatus.INITIATED); } + public boolean isInitiated() throws OsgpException { + return this.getImageTransferStatus() == ImageTransferStatus.INITIATED.getValue(); + } + public boolean imageIsVerified() throws OsgpException { return this.isImageTransferStatusIn( ImageTransferStatus.VERIFICATION_SUCCESSFUL, @@ -153,18 +157,18 @@ public void initiateImageTransfer() throws ProtocolAdapterException { } /** - * Transfers all image blocks. + * Transfers image blocks starting from the given first block until the last. * *

    ImageBlocks are accepted only by those COSEM servers, in which the Image transfer process * has been successfully initiated. Other servers silently discard any ImageBlocks received. */ - public void transferImageBlocks() throws OsgpException { + public void transferImageBlocks(final int firstBlock) throws OsgpException { if (!this.shouldTransferImage()) { throw new ProtocolAdapterException(EXCEPTION_MSG_IMAGE_TRANSFER_NOT_INITIATED); } final int blocks = this.numberOfBlocks(); - for (int i = 0; i < blocks; i++) { + for (int i = firstBlock; i < blocks; i++) { this.logUploadPercentage(i, blocks); this.imageBlockTransfer(i); } @@ -389,7 +393,7 @@ private int getImageBlockSize() throws ProtocolAdapterException { return this.imageBlockSize; } - private int getImageFirstNotTransferredBlockNumber() throws ProtocolAdapterException { + public int getImageFirstNotTransferredBlockNumber() throws ProtocolAdapterException { this.connector .getDlmsMessageListener() .setDescription( diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/firmware/UpdateFirmwareCommandExecutor.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/firmware/UpdateFirmwareCommandExecutor.java index 9d685617807..5bc9e4be618 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/firmware/UpdateFirmwareCommandExecutor.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/firmware/UpdateFirmwareCommandExecutor.java @@ -4,6 +4,9 @@ package org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.firmware; +import java.math.BigInteger; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.util.Arrays; import lombok.extern.slf4j.Slf4j; import org.bouncycastle.util.encoders.Hex; @@ -37,9 +40,10 @@ public class UpdateFirmwareCommandExecutor private static final String EXCEPTION_MSG_FIRMWARE_IMAGE_IDENTIFIER_NOT_AVAILABLE = "Firmware Image Identifier is not available."; private static final String EXCEPTION_MSG_DEVICE_NOT_AVAILABLE_IN_DATABASE = - "Device {} not available in database."; + "Device %s not available in database."; private static final String EXCEPTION_MSG_DEVICE_HAS_NO_MBUS_IDENTIFICATION_NUMBER = - "Device {} has no M-Bus identification number."; + "Device %s has no M-Bus identification number."; + private static final String SHA256 = "SHA-256"; private final DlmsDeviceRepository dlmsDeviceRepository; @@ -81,9 +85,40 @@ public UpdateFirmwareResponseDto execute( this.getImageIdentifier(firmwareIdentification, firmwareFile), firmwareFile.getByteArray()); + // Calculate the hash of the FW file + // for mbus device get a part of the image file because we add a mac to it + // for e-meter use whole file because that is static + final String calculatedHash = + this.calculateHash( + firmwareFile.isMbusFirmware() + ? firmwareFile.getFirmwareImageByteArray() + : firmwareFile.getByteArray(), + SHA256); + + // Resume on the last not transferred block if + // a hash of a previously uploaded FW file is stored with this device + // and this hash is equal to the hash of the FW file to be uploaded + // and the image_transfer_status is INITIATED + final boolean resumeOnLastBlock = + device.getFirmwareHash() != null + && device.getFirmwareHash().equals(calculatedHash) + && transfer.isInitiated(); + try { - this.prepare(transfer); - this.transfer(transfer); + if (resumeOnLastBlock) { + this.enable(transfer); + // do not call method image_transfer_initiate (in this class' prepare method). + // This method will reset first_not_transferred_block_number to 0 (zero) + // This assumes that the image_transfer_status attribute is (1) Image transfer initiated. + final int blockNumber = transfer.getImageFirstNotTransferredBlockNumber(); + this.transfer(transfer, blockNumber); + } else { + this.storeFirmwareHashWithDlmsDevice(device, calculatedHash); + this.prepare(transfer); + this.transfer(transfer, 0); + } + // After completing the transfer removed the Firmware hash stored with the device + this.removeFirmwareHashFromDlmsDevice(device); if (!firmwareFile.isMbusFirmware()) { this.verify(transfer); this.activate(transfer); @@ -97,16 +132,19 @@ public UpdateFirmwareResponseDto execute( } private void prepare(final ImageTransfer transfer) throws ProtocolAdapterException { + this.enable(transfer); + transfer.initiateImageTransfer(); + } + + private void enable(final ImageTransfer transfer) throws ProtocolAdapterException { if (!transfer.imageTransferEnabled()) { transfer.setImageTransferEnabled(true); } - - transfer.initiateImageTransfer(); } - private void transfer(final ImageTransfer transfer) throws OsgpException { + private void transfer(final ImageTransfer transfer, final int firstBlock) throws OsgpException { if (transfer.shouldTransferImage()) { - transfer.transferImageBlocks(); + transfer.transferImageBlocks(firstBlock); transfer.transferMissingImageBlocks(); } else { log.info("The current ImageTransferStatus is not INITIATED"); @@ -216,7 +254,7 @@ private byte[] getImageIdentifier( final String firmwareIdentification, final FirmwareFile firmwareFile) throws ProtocolAdapterException { - byte[] imageIdentifier = null; + final byte[] imageIdentifier; if (firmwareFile.isMbusFirmware()) { @@ -258,4 +296,29 @@ public ActionResponseDto asBundleResponse(final UpdateFirmwareResponseDto execut return executionResult; } + + private String calculateHash(final byte[] content, final String algorithm) { + + try { + final MessageDigest messageDigest = MessageDigest.getInstance(algorithm); + final byte[] digest = messageDigest.digest(content); + return new BigInteger(1, digest).toString(16); + } catch (final NoSuchAlgorithmException e) { + log.error("Error calculating digest", e); + return ""; + } + } + + private void storeFirmwareHashWithDlmsDevice(final DlmsDevice device, final String firmwareHash) { + log.info( + "Storing Firmware hash {} for dlms-device {}", + firmwareHash, + device.getDeviceIdentification()); + this.dlmsDeviceRepository.storeFirmwareHash(device.getDeviceIdentification(), firmwareHash); + } + + private void removeFirmwareHashFromDlmsDevice(final DlmsDevice device) { + log.info("Removing Firmware hash from dlms-device {}", device.getDeviceIdentification()); + this.dlmsDeviceRepository.storeFirmwareHash(device.getDeviceIdentification(), null); + } } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/misc/GetActualPowerQualityCommandExecutor.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/misc/GetActualPowerQualityCommandExecutor.java index 167118d5724..1d2cca61a57 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/misc/GetActualPowerQualityCommandExecutor.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/misc/GetActualPowerQualityCommandExecutor.java @@ -6,7 +6,6 @@ import java.math.BigDecimal; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.EnumMap; import java.util.List; @@ -25,12 +24,13 @@ import org.opensmartgridplatform.dlms.interfaceclass.attribute.ClockAttribute; import org.opensmartgridplatform.dlms.interfaceclass.attribute.DataAttribute; import org.opensmartgridplatform.dlms.interfaceclass.attribute.RegisterAttribute; +import org.opensmartgridplatform.dlms.objectconfig.Attribute; import org.opensmartgridplatform.dlms.objectconfig.CosemObject; import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; -import org.opensmartgridplatform.dlms.objectconfig.MeterType; import org.opensmartgridplatform.dlms.objectconfig.ObjectProperty; import org.opensmartgridplatform.dlms.objectconfig.PowerQualityProfile; import org.opensmartgridplatform.dlms.objectconfig.PowerQualityRequest; +import org.opensmartgridplatform.dlms.objectconfig.ValueType; import org.opensmartgridplatform.dlms.services.ObjectConfigService; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ActualPowerQualityDataDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ActualPowerQualityRequestDto; @@ -120,12 +120,21 @@ private ActualPowerQualityDataDto makeActualPowerQualityDataDto( powerQualityObject = new PowerQualityObjectDto(pqObject.getTag(), null); } else if (pqObject.getClassId() == CLASS_ID_REGISTER) { - final String scalerUnit = - pqObject.getAttribute(RegisterAttribute.SCALER_UNIT.attributeId()).getValue(); - - final DlmsMeterValueDto meterValue = - this.dlmsHelper.getScaledMeterValueWithScalerUnit( - resultValue, scalerUnit, "Actual Power Quality - " + pqObject.getObis()); + final DlmsMeterValueDto meterValue; + if (this.readScalerValueFromMeter(pqObject)) { + final GetResult resultValueScalerUnit = resultList.get(idx++); + meterValue = + this.dlmsHelper.getScaledMeterValue( + resultValue, + resultValueScalerUnit, + "Actual Power Quality - " + pqObject.getObis()); + } else { + final String scalerUnit = + pqObject.getAttribute(RegisterAttribute.SCALER_UNIT.attributeId()).getValue(); + meterValue = + this.dlmsHelper.getScaledMeterValueWithScalerUnit( + resultValue, scalerUnit, "Actual Power Quality - " + pqObject.getObis()); + } final BigDecimal value = meterValue != null ? meterValue.getValue() : null; final String unit = meterValue != null ? meterValue.getDlmsUnit().getUnit() : null; @@ -155,6 +164,15 @@ private ActualPowerQualityDataDto makeActualPowerQualityDataDto( return new ActualPowerQualityDataDto(powerQualityObjects, powerQualityValues); } + private boolean readScalerValueFromMeter(final CosemObject pqObject) { + if (pqObject.hasAttribute(RegisterAttribute.SCALER_UNIT.attributeId())) { + final Attribute attribute = + pqObject.getAttribute(RegisterAttribute.SCALER_UNIT.attributeId()); + return attribute.getValuetype() != ValueType.FIXED_IN_PROFILE; + } + return false; + } + private PowerQualityProfile determineProfile(final ActualPowerQualityRequestDto request) { try { @@ -177,33 +195,41 @@ public List getPQObjects(final DlmsDevice device, final PowerQualit allPQObjects.add(clockObject); // Create map with the required properties and values for the power quality objects - final EnumMap> pqProperties = + final EnumMap> pqProperties = new EnumMap<>(ObjectProperty.class); pqProperties.put(ObjectProperty.PQ_PROFILE, Collections.singletonList(profile.name())); pqProperties.put( ObjectProperty.PQ_REQUEST, - Arrays.asList(PowerQualityRequest.ONDEMAND.name(), PowerQualityRequest.BOTH.name())); + List.of( + device.isPolyphase() + ? PowerQualityRequest.ACTUAL_PP.name() + : PowerQualityRequest.ACTUAL_SP.name())); // Get matching power quality objects from config - final List objectsForProfile = + final List pqObjects = this.objectConfigService.getCosemObjectsWithProperties( device.getProtocolName(), device.getProtocolVersion(), pqProperties); - // Filter for single phase / poly phase - final List pqObjects = - objectsForProfile.stream() - .filter(object -> this.objectHasCorrectMeterType(object, device)) - .toList(); - allPQObjects.addAll(pqObjects); return allPQObjects; } catch (final ObjectConfigException e) { - throw new ProtocolAdapterException("Error in object config", e); + throw new ProtocolAdapterException(AbstractCommandExecutor.ERROR_IN_OBJECT_CONFIG, e); } } private List getAttributeAddresses(final List pqObjects) { - return pqObjects.stream().map(this::getAttributeAddress).filter(Objects::nonNull).toList(); + final List attributeAddresses = new ArrayList<>(); + for (final CosemObject pqObject : pqObjects) { + attributeAddresses.add(this.getAttributeAddress(pqObject)); + if (this.readScalerValueFromMeter(pqObject)) { + attributeAddresses.add( + new AttributeAddress( + pqObject.getClassId(), + pqObject.getObis(), + RegisterAttribute.SCALER_UNIT.attributeId())); + } + } + return attributeAddresses.stream().filter(Objects::nonNull).toList(); } private AttributeAddress getAttributeAddress(final CosemObject object) { @@ -220,9 +246,4 @@ private AttributeAddress getAttributeAddress(final CosemObject object) { return null; } } - - private boolean objectHasCorrectMeterType(final CosemObject object, final DlmsDevice device) { - return (!device.isPolyphase() && object.getMeterTypes().contains(MeterType.SP)) - || (device.isPolyphase() && object.getMeterTypes().contains(MeterType.PP)); - } } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/misc/GetGsmDiagnosticCommandExecutor.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/misc/GetGsmDiagnosticCommandExecutor.java index 5cb24575ff5..9975adc6ce1 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/misc/GetGsmDiagnosticCommandExecutor.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/misc/GetGsmDiagnosticCommandExecutor.java @@ -34,7 +34,6 @@ import org.opensmartgridplatform.dlms.services.ObjectConfigService; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ActionRequestDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.AdjacentCellInfoDto; -import org.opensmartgridplatform.dto.valueobjects.smartmetering.BitErrorRateDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.CellInfoDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.CircuitSwitchedStatusDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.CosemDateTimeDto; @@ -142,7 +141,7 @@ public CosemObject getCosemObject(final DlmsDevice device) throws ProtocolAdapte device.getProtocolName(), device.getProtocolVersion(), dlmsObjectType); } catch (final ObjectConfigException e) { - throw new ProtocolAdapterException("Error in object config", e); + throw new ProtocolAdapterException(AbstractCommandExecutor.ERROR_IN_OBJECT_CONFIG, e); } } @@ -251,8 +250,7 @@ private CellInfoDto getCellInfo(final List getResultList) { cellInfoDataObjects.get(CELL_INFO_LOCATION_ID_INDEX).getValue(), SignalQualityDto.fromIndexValue( (short) cellInfoDataObjects.get(CELL_INFO_SIGNAL_QUALITY_INDEX).getValue()), - BitErrorRateDto.fromIndexValue( - (short) cellInfoDataObjects.get(CELL_INFO_BIT_ERROR_RATE_INDEX).getValue()), + (short) cellInfoDataObjects.get(CELL_INFO_BIT_ERROR_RATE_INDEX).getValue(), cellInfoDataObjects.get(CELL_INFO_MOBILE_COUNTRY_CODE_INDEX).getValue(), cellInfoDataObjects.get(CELL_INFO_MOBILE_NETWORK_CODE_INDEX).getValue(), cellInfoDataObjects.get(CELL_INFO_CHANNEL_NUMBER_INDEX).getValue()); diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/monitoring/AbstractGetPowerQualityProfileHandler.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/monitoring/AbstractGetPowerQualityProfileHandler.java index 5cdf8e5fe05..57aab0a37c4 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/monitoring/AbstractGetPowerQualityProfileHandler.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/monitoring/AbstractGetPowerQualityProfileHandler.java @@ -34,12 +34,12 @@ import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; import org.opensmartgridplatform.dlms.exceptions.ObjectConfigException; import org.opensmartgridplatform.dlms.interfaceclass.InterfaceClass; -import org.opensmartgridplatform.dlms.interfaceclass.attribute.ExtendedRegisterAttribute; +import org.opensmartgridplatform.dlms.interfaceclass.attribute.GsmDiagnosticAttribute; import org.opensmartgridplatform.dlms.interfaceclass.attribute.ProfileGenericAttribute; -import org.opensmartgridplatform.dlms.interfaceclass.attribute.RegisterAttribute; import org.opensmartgridplatform.dlms.objectconfig.CosemObject; import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; import org.opensmartgridplatform.dlms.objectconfig.ObjectProperty; +import org.opensmartgridplatform.dlms.objectconfig.PowerQualityRequest; import org.opensmartgridplatform.dlms.services.ObjectConfigService; import org.opensmartgridplatform.dto.valueobjects.smartmetering.CaptureObjectDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.CosemDateTimeDto; @@ -53,6 +53,7 @@ import org.opensmartgridplatform.dto.valueobjects.smartmetering.ProfileEntryDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ProfileEntryValueDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ProfileTypeDto; +import org.opensmartgridplatform.dto.valueobjects.smartmetering.SignalQualityDto; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -67,6 +68,9 @@ public abstract class AbstractGetPowerQualityProfileHandler { private static final int ATTRIBUTE_ID_INTERVAL = 4; + private static final int DATA_INDEX_SIGNAL_QUALITY = 3; + private static final int DATA_INDEX_BER = 4; + private static final List CHANNELS = Arrays.asList(1, 2, 3, 4); protected final DlmsHelper dlmsHelper; @@ -134,7 +138,7 @@ protected GetPowerQualityProfileResponseDto handle( // meter. This list can then be used to filter the retrieved values. A LinkedHashMap is used // to preserve the order of entries (which will be used in the handler for selective access). final LinkedHashMap selectableObjects = - this.determineSelectableObjects(captureObjects, configObjects); + this.determineSelectableObjects(conn, captureObjects, configObjects); // Get the values from the buffer in the meter final List bufferList = @@ -192,8 +196,13 @@ private void addToMapIfNeeded( final String version = device.getProtocolVersion(); try { - final CosemObject profileObject = - this.objectConfigService.getCosemObject(protocol, version, profileType); + final Optional optionalCosemObject = + this.objectConfigService.getOptionalCosemObject(protocol, version, profileType); + if (optionalCosemObject.isEmpty()) { + // Cosem object is not in profile, then skip it + return; + } + final CosemObject profileObject = optionalCosemObject.get(); // Get all selectable objects for this profile final List selectableObjectsFromConfig = @@ -205,7 +214,7 @@ private void addToMapIfNeeded( .filter( object -> object.getClassId() == InterfaceClass.CLOCK.id() - || this.hasPqProfile(object, privateOrPublic)) + || this.hasPeriodicPqProfile(device, object, privateOrPublic)) .toList(); // Use this profile when at least the clock object and one other object should be read @@ -217,8 +226,18 @@ private void addToMapIfNeeded( } } - private boolean hasPqProfile(final CosemObject object, final String privateOrPublic) { - return ((String) object.getProperty(ObjectProperty.PQ_PROFILE)).equals(privateOrPublic); + private boolean hasPeriodicPqProfile( + final DlmsDevice device, final CosemObject object, final String privateOrPublic) { + if (object.getListProperty(ObjectProperty.PQ_REQUEST) != null + && object + .getListProperty(ObjectProperty.PQ_REQUEST) + .contains( + device.isPolyphase() + ? PowerQualityRequest.PERIODIC_PP.name() + : PowerQualityRequest.PERIODIC_SP.name())) { + return ((String) object.getProperty(ObjectProperty.PQ_PROFILE)).equals(privateOrPublic); + } + return false; } private List retrieveCaptureObjects( @@ -431,6 +450,8 @@ protected ProfileEntryValueDto makeProfileEntryValueDto( final int timeInterval) { if (InterfaceClass.CLOCK.id() == selectableObject.getClassId()) { return this.makeDateProfileEntryValueDto(dataObject, previousProfileEntryDto, timeInterval); + } else if (InterfaceClass.GSM_DIAGNOSTIC.id() == selectableObject.getClassId()) { + return this.makeGsmDiagnosticProfileEntryValueDto(dataObject, selectableObject); } else if (dataObject.isNumber()) { return this.createNumericProfileEntryValueDto(dataObject, selectableObject); } else if (dataObject.isNull()) { @@ -467,6 +488,41 @@ private ProfileEntryValueDto makeDateProfileEntryValueDto( } } + private ProfileEntryValueDto makeGsmDiagnosticProfileEntryValueDto( + final DataObject dataObject, final SelectableObject selectableObject) { + + try { + if (selectableObject.attributeIndex == GsmDiagnosticAttribute.CELL_INFO.attributeId()) { + if (selectableObject.dataIndex == DATA_INDEX_SIGNAL_QUALITY) { + final Long signalQualityLong = + this.dlmsHelper.readLong(dataObject, "Read signal quality"); + if (signalQualityLong == null) { + return notKnownProfileEntryValue(); + } + final int value = signalQualityLong.intValue(); + final SignalQualityDto signalQuality = SignalQualityDto.fromIndexValue(value); + return new ProfileEntryValueDto(signalQuality.value()); + } else if (selectableObject.dataIndex == DATA_INDEX_BER) { + final Long berLong = this.dlmsHelper.readLong(dataObject, "Read ber"); + if (berLong == null) { + return notKnownProfileEntryValue(); + } + final int value = berLong.intValue(); + return new ProfileEntryValueDto(value); + } + } + } catch (final ProtocolAdapterException | IllegalArgumentException e) { + LOGGER.error("Error creating ProfileEntryDto from {}", dataObject, e); + } + + final String debugInfo = this.dlmsHelper.getDebugInfo(dataObject); + return new ProfileEntryValueDto(debugInfo); + } + + private static ProfileEntryValueDto notKnownProfileEntryValue() { + return new ProfileEntryValueDto(99); + } + private ProfileEntryValueDto createNumericProfileEntryValueDto( final DataObject dataObject, final SelectableObject selectableObject) { try { @@ -492,7 +548,9 @@ private ProfileEntryValueDto createNumericProfileEntryValueDto( } private LinkedHashMap determineSelectableObjects( - final List captureObjects, final List cosemConfigObjects) + final DlmsConnectionManager conn, + final List captureObjects, + final List cosemConfigObjects) throws ProtocolAdapterException { final LinkedHashMap selectableObjects = new LinkedHashMap<>(); @@ -525,7 +583,7 @@ private LinkedHashMap determineSelectableObjects( obis, (byte) objectDefinition.getAttributeIndex(), objectDefinition.getDataIndex(), - this.getScalerUnit(matchedCosemObject.get()))); + this.getScalerUnit(conn, matchedCosemObject.get()))); } } } @@ -544,11 +602,11 @@ private boolean obisMatches(final String captureObis, final String configObis) { return obisCodesToMatch.contains(captureObis); } - private String getScalerUnit(final CosemObject object) { - if (object.getClassId() == InterfaceClass.REGISTER.id()) { - return object.getAttribute(RegisterAttribute.SCALER_UNIT.attributeId()).getValue(); - } else if (object.getClassId() == InterfaceClass.EXTENDED_REGISTER.id()) { - return object.getAttribute(ExtendedRegisterAttribute.SCALER_UNIT.attributeId()).getValue(); + private String getScalerUnit(final DlmsConnectionManager conn, final CosemObject object) + throws ProtocolAdapterException { + if (object.getClassId() == InterfaceClass.REGISTER.id() + || object.getClassId() == InterfaceClass.EXTENDED_REGISTER.id()) { + return this.dlmsHelper.getScalerUnitValue(conn, object); } else { return null; } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/periodicmeterreads/AbstractPeriodicMeterReadsCommandExecutor.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/periodicmeterreads/AbstractPeriodicMeterReadsCommandExecutor.java index f9ffc35f5ff..c6f1b176a6a 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/periodicmeterreads/AbstractPeriodicMeterReadsCommandExecutor.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/periodicmeterreads/AbstractPeriodicMeterReadsCommandExecutor.java @@ -52,6 +52,37 @@ public abstract class AbstractPeriodicMeterReadsCommandExecutor this.amrProfileStatusCodeHelper = amrProfileStatusCodeHelper; } + protected AttributeAddressForProfile getProfileBufferAddress( + final PeriodTypeDto periodType, + final DateTime beginDateTime, + final DateTime endDateTime, + final DlmsDevice device, + final DlmsObjectConfigService dlmsObjectConfigService, + final Medium medium, + final int channelNumber) + throws ProtocolAdapterException { + + final DlmsObjectType type = DlmsObjectType.getTypeForPeriodType(periodType); + + // Add the attribute address for the profile + final AttributeAddressForProfile attributeAddressProfile = + dlmsObjectConfigService + .findAttributeAddressForProfile( + device, + type, + channelNumber, + beginDateTime, + endDateTime, + medium, + device.isSelectiveAccessPeriodicMeterReadsSupported()) + .orElseThrow(() -> new ProtocolAdapterException("No address found for " + type)); + + LOGGER.debug( + "Dlms object config service returned profile buffer address {} ", attributeAddressProfile); + + return attributeAddressProfile; + } + /** * Calculates/derives the date of the read buffered DataObject. * @@ -205,7 +236,7 @@ AmrProfileStatusCodeDto readStatus( * @return AmrProfileStatusCode object holding status enum values. * @throws ProtocolAdapterException on invalid register data. */ - private AmrProfileStatusCodeDto readAmrProfileStatusCode(final DataObject amrProfileStatusData) + AmrProfileStatusCodeDto readAmrProfileStatusCode(final DataObject amrProfileStatusData) throws ProtocolAdapterException { if (!amrProfileStatusData.isNumber()) { diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/periodicmeterreads/GetPeriodicMeterReadsCommandExecutor.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/periodicmeterreads/GetPeriodicMeterReadsCommandExecutor.java index f94e275c692..6a284eee765 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/periodicmeterreads/GetPeriodicMeterReadsCommandExecutor.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/periodicmeterreads/GetPeriodicMeterReadsCommandExecutor.java @@ -102,7 +102,8 @@ public PeriodicMeterReadsResponseDto execute( periodicMeterReadsQuery.getEndDate(), device.getTimezone()); final AttributeAddressForProfile profileBufferAddress = - this.getProfileBufferAddress(queryPeriodType, from, to, device); + this.getProfileBufferAddress( + queryPeriodType, from, to, device, this.dlmsObjectConfigService, Medium.ELECTRICITY, 0); final List scalerUnitAddresses = this.getScalerUnitAddresses(profileBufferAddress); @@ -336,28 +337,6 @@ private DataObject readScalerUnit( return null; } - private AttributeAddressForProfile getProfileBufferAddress( - final PeriodTypeDto periodType, - final DateTime beginDateTime, - final DateTime endDateTime, - final DlmsDevice device) - throws ProtocolAdapterException { - - final DlmsObjectType type = DlmsObjectType.getTypeForPeriodType(periodType); - - // Add the attribute address for the profile - final AttributeAddressForProfile attributeAddressProfile = - this.dlmsObjectConfigService - .findAttributeAddressForProfile( - device, type, 0, beginDateTime, endDateTime, Medium.ELECTRICITY) - .orElseThrow(() -> new ProtocolAdapterException("No address found for " + type)); - - LOGGER.debug( - "Dlms object config service returned profile buffer address {} ", attributeAddressProfile); - - return attributeAddressProfile; - } - private List getScalerUnitAddresses( final AttributeAddressForProfile attributeAddressForProfile) { diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/periodicmeterreads/GetPeriodicMeterReadsGasCommandExecutor.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/periodicmeterreads/GetPeriodicMeterReadsGasCommandExecutor.java index 3ae57418eb3..905e9716de0 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/periodicmeterreads/GetPeriodicMeterReadsGasCommandExecutor.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/periodicmeterreads/GetPeriodicMeterReadsGasCommandExecutor.java @@ -4,19 +4,35 @@ package org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.periodicmeterreads; +import static org.opensmartgridplatform.dlms.interfaceclass.attribute.ProfileGenericAttribute.BUFFER; +import static org.opensmartgridplatform.dlms.interfaceclass.attribute.ProfileGenericAttribute.CAPTURE_PERIOD; +import static org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.AMR_PROFILE_STATUS; +import static org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.AMR_PROFILE_STATUS_DAILY_G; +import static org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.AMR_PROFILE_STATUS_HOURLY_G; +import static org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.AMR_PROFILE_STATUS_MONTHLY_G; +import static org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.CLOCK; +import static org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.DAILY_VALUES_COMBINED; +import static org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.DAILY_VALUES_G; +import static org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.INTERVAL_VALUES_G; +import static org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.MBUS_MASTER_VALUE; +import static org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.MONTHLY_VALUES_COMBINED; +import static org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.MONTHLY_VALUES_G; + import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Optional; import org.joda.time.DateTime; +import org.openmuc.jdlms.AccessResultCode; import org.openmuc.jdlms.AttributeAddress; import org.openmuc.jdlms.GetResult; import org.openmuc.jdlms.ObisCode; +import org.openmuc.jdlms.SelectiveAccessDescription; import org.openmuc.jdlms.datatypes.DataObject; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.AttributeAddressForProfile; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsCaptureObject; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectConfigService; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectType; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.model.Medium; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.model.ProfileCaptureTime; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.AmrProfileStatusCodeHelper; @@ -25,11 +41,20 @@ import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.JdlmsObjectToStringUtil; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDevice; import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionManager; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.valueobjects.CombinedDeviceModelCode; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.BufferedDateTimeValidationException; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; +import org.opensmartgridplatform.dlms.exceptions.ObjectConfigException; +import org.opensmartgridplatform.dlms.interfaceclass.attribute.ExtendedRegisterAttribute; +import org.opensmartgridplatform.dlms.objectconfig.Attribute; +import org.opensmartgridplatform.dlms.objectconfig.CaptureObject; +import org.opensmartgridplatform.dlms.objectconfig.CosemObject; +import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; +import org.opensmartgridplatform.dlms.objectconfig.dlmsclasses.ProfileGeneric; +import org.opensmartgridplatform.dlms.objectconfig.dlmsclasses.Register; +import org.opensmartgridplatform.dlms.services.ObjectConfigService; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ActionRequestDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.AmrProfileStatusCodeDto; -import org.opensmartgridplatform.dto.valueobjects.smartmetering.ChannelDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.CosemDateTimeDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.PeriodTypeDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.PeriodicMeterReadGasResponseDto; @@ -58,16 +83,16 @@ public class GetPeriodicMeterReadsGasCommandExecutor "GetPeriodicMeterReadsGas for channel %s, %s from %s until %s, " + "retrieve attribute: %s"; private final DlmsHelper dlmsHelper; - private final DlmsObjectConfigService dlmsObjectConfigService; + private final ObjectConfigService objectConfigService; @Autowired public GetPeriodicMeterReadsGasCommandExecutor( final DlmsHelper dlmsHelper, final AmrProfileStatusCodeHelper amrProfileStatusCodeHelper, - final DlmsObjectConfigService dlmsObjectConfigService) { + final ObjectConfigService objectConfigService) { super(PeriodicMeterReadsGasRequestDto.class, amrProfileStatusCodeHelper); this.dlmsHelper = dlmsHelper; - this.dlmsObjectConfigService = dlmsObjectConfigService; + this.objectConfigService = objectConfigService; } @Override @@ -93,12 +118,14 @@ public PeriodicMeterReadGasResponseDto execute( final MessageMetadata messageMetadata) throws ProtocolAdapterException { + final CombinedDeviceModelCode combinedDeviceModelCode = + CombinedDeviceModelCode.parse(messageMetadata.getDeviceModelCode()); + if (periodicMeterReadsQuery == null) { throw new IllegalArgumentException( "PeriodicMeterReadsQuery should contain PeriodType, BeginDate and EndDate."); } - final PeriodTypeDto queryPeriodType = periodicMeterReadsQuery.getPeriodType(); final DateTime from = DlmsDateTimeConverter.toDateTime( periodicMeterReadsQuery.getBeginDate(), device.getTimezone()); @@ -106,15 +133,55 @@ public PeriodicMeterReadGasResponseDto execute( DlmsDateTimeConverter.toDateTime( periodicMeterReadsQuery.getEndDate(), device.getTimezone()); - final AttributeAddressForProfile profileBufferAddress = - this.getProfileBufferAddress( - queryPeriodType, periodicMeterReadsQuery.getChannel(), from, to, device); - - final List scalerUnitAddresses = - this.getScalerUnitAddresses(periodicMeterReadsQuery.getChannel(), profileBufferAddress); + // The query can be for 3 different types of values: Interval (hourly), daily or monthly. + final PeriodTypeDto queryPeriodType = periodicMeterReadsQuery.getPeriodType(); - final Optional intervalTime = - this.getProfileCaptureTime(device, this.dlmsObjectConfigService, Medium.GAS); + // The periodic values are stored in the meter in the buffer of a Profile Generic. + // Based on the type and the protocol version, get the information for the right Profile from + // the object configuration. + final ProfileGeneric profileObject = this.getProfileConfigObject(device, queryPeriodType); + + // A Profile Generic periodically stores values of multiple objects. Usually, this is a + // timestamp from the Clock, a status, a meter value and the timestamp when the meter value was + // stored (the capture time). For some meters, the gas values and the electricity values are + // combined in one profile. + // Values in the profile will be selected using selective access. Selecting values based on a + // start and end datetime should be supported for all devices. Selecting a subset of values to + // be retrieved (e.g. only gas values in a combined profile) is not supported by all devices. + final boolean selectedValuesSupported = device.isSelectiveAccessPeriodicMeterReadsSupported(); + + // A request can be for channel 1-4. + final int channel = periodicMeterReadsQuery.getChannel().getChannelNumber(); + + // The profile object from the object config contains information about the objects for which + // a value (one of the attributes) is stored in the profile: the capture objects. + // Note that the order is important: the meter will return the values in the order of the + // capture object definition in the profile. + // All capture objects are retrieved from the config as well to get information about the scaler + // and unit of the values. + final List allCaptureObjectsInProfile = + this.getCaptureObjectsInProfile( + profileObject, device, channel, combinedDeviceModelCode.getCodeFromChannel(channel)); + + // If it selectedValues is supported, then determine a subset of capture objects that are to be + // retrieved. E.g. when it is a combined profile, we can only get the gas values without the + // electricity values. This is more efficient and improves privacy (we only get what we need). + final List selectedCaptureObjects = + this.getSelectedCaptureObjects( + allCaptureObjectsInProfile, Medium.GAS, channel, selectedValuesSupported); + + // Check if it's needed to select values. If all values are requested, then we can skip the + // select values option in the request to the meter. + final boolean selectValues = + selectedValuesSupported + && (allCaptureObjectsInProfile.size() != selectedCaptureObjects.size()); + + // To request the values from the meter, we need the address. This contains the obis code of + // the profile object, the attribute id of the buffer (2) and the selective access parameters: + // the from and to dates and (if applicable) the selected values. + final AttributeAddress profileBufferAddress = + this.getAttributeAddressForProfile( + profileObject, from, to, channel, selectedCaptureObjects, selectValues); LOGGER.info( "Retrieving current billing period and profiles for gas for period type: {}, from: " @@ -123,45 +190,49 @@ public PeriodicMeterReadGasResponseDto execute( from, to); - /* - * workaround for a problem when using with_list and retrieving a profile - * buffer, this will be returned erroneously. - */ - final List getResultList = new ArrayList<>(); - - final List allAttributeAddresses = new ArrayList<>(); - allAttributeAddresses.add(profileBufferAddress.getAttributeAddress()); - allAttributeAddresses.addAll(scalerUnitAddresses); - - for (final AttributeAddress address : allAttributeAddresses) { - - conn.getDlmsMessageListener() - .setDescription( - String.format( - FORMAT_DESCRIPTION, - periodicMeterReadsQuery.getChannel(), - queryPeriodType, - from, - to, - JdlmsObjectToStringUtil.describeAttributes(address))); - - getResultList.addAll( - this.dlmsHelper.getAndCheck( - conn, - device, - "retrieve periodic meter reads for " - + queryPeriodType - + ", channel " - + periodicMeterReadsQuery.getChannel(), - address)); - } + conn.getDlmsMessageListener() + .setDescription( + String.format( + FORMAT_DESCRIPTION, + periodicMeterReadsQuery.getChannel(), + queryPeriodType, + from, + to, + JdlmsObjectToStringUtil.describeAttributes(profileBufferAddress))); + + // This is the actual request to the meter. The DlmsHelper will automatically check if the + // result is SUCCESS. Otherwise, it will throw an exception. + final List getResultList = + this.dlmsHelper.getAndCheck( + conn, + device, + "retrieve periodic meter reads for " + queryPeriodType + ", channel " + channel, + profileBufferAddress); LOGGER.debug("Received getResult: {} ", getResultList); + // Unpack the data from the meter response final DataObject resultData = this.dlmsHelper.readDataObject(getResultList.get(0), PERIODIC_G_METER_READS); final List bufferedObjectsList = resultData.getValue(); + // The values in the bufferedObjectList now need to be converted to a ResponseItem including + // information about the time, the type of value and the unit. + + // A capture object might not have a fixed scaler unit in the config, or the scaler unit needs + // to be chosen based on the device type. So check if that is the case and update the capture + // objects if necessary. Note: this might result in an additional request to the meter. + final List captureObjectsWithScalerUnit = + this.checkAndGetScalerUnits(selectedCaptureObjects, conn, device, Medium.GAS, channel); + + // The interval time of the profile is important. For efficiency, most meters only send a + // timestamp for the first value in the response. The timestamp of the other values should be + // calculated using the interval time. + final ProfileCaptureTime intervalTime = this.getProfileCaptureTime(profileObject); + + // Now convert the retrieved values. Each buffered object contains the values for a single + // interval (e.g. a timestamp, a status and a meter value). The values in the buffered object + // are in the order of the capture objects in the profile. final List periodicMeterReads = new ArrayList<>(); for (final DataObject bufferedObject : bufferedObjectsList) { final List bufferedObjectValue = bufferedObject.getValue(); @@ -169,19 +240,18 @@ public PeriodicMeterReadGasResponseDto execute( try { periodicMeterReads.add( this.convertToResponseItem( - new ConversionContext( - periodicMeterReadsQuery, - bufferedObjectValue, - getResultList, - profileBufferAddress, - scalerUnitAddresses, - intervalTime), + queryPeriodType, + captureObjectsWithScalerUnit, + intervalTime, + bufferedObjectValue, + channel, periodicMeterReads)); } catch (final BufferedDateTimeValidationException e) { LOGGER.warn(e.getMessage(), e); } } + // To be sure no values are returned outside the requested period, filter on from and to date. final List periodicMeterReadsWithinRequestedPeriod = periodicMeterReads.stream() .filter( @@ -196,27 +266,51 @@ public PeriodicMeterReadGasResponseDto execute( } private PeriodicMeterReadsGasResponseItemDto convertToResponseItem( - final ConversionContext ctx, + final PeriodTypeDto periodType, + final List selectedObjects, + final ProfileCaptureTime intervalTime, + final List bufferedObjects, + final int channel, final List periodicMeterReads) throws ProtocolAdapterException, BufferedDateTimeValidationException { - final Optional previousLogTime = this.getPreviousLogTime(periodicMeterReads); - final Date logTime = this.readClock(ctx, previousLogTime, this.dlmsHelper); + // The bufferedObjects contain the values retrieved from the meter for a single interval. + // The bufferedObjects contain no information about the type of value. But because the + // bufferedObjects are always in the same known order (the order of the selectedObjects), we can + // still convert the values. + // The first timestamp in the response of a meter should always be included. The following + // intervals could have a 'null' timestamp, meaning the time should be calculated based on the + // previous timestamp. + final Optional previousLogTime = this.getPreviousLogTime(periodicMeterReads); + final Date logTime = + this.readClock( + periodType, + selectedObjects, + previousLogTime, + intervalTime, + bufferedObjects, + this.dlmsHelper); + + // The status is used in most profiles. But for some it is not used. In that case, the + // selectedObjects will not contain a status object and readStatus will return null. final AmrProfileStatusCodeDto status = - this.readStatus(ctx.bufferedObjects, ctx.attributeAddressForProfile); - final DataObject gasValue = this.readValue(ctx.bufferedObjects, ctx.attributeAddressForProfile); - final DataObject scalerUnit = - this.readScalerUnit( - ctx.getResultList, - ctx.attributeAddresses, - ctx.attributeAddressForProfile, - ctx.periodicMeterReadsQuery.getChannel().getChannelNumber()); + this.readStatus(bufferedObjects, selectedObjects, periodType); + // The gasValue should always be included. The value of the meter has no information about + // the scaler or the unit, so that information is retrieved from the corresponding capture + // object in the selected objects. + final DataObject gasValue = this.readValue(bufferedObjects, selectedObjects, channel); + final String scalerUnit = this.getScalerUnit(selectedObjects, channel); + + // The capture time is used in most profiles. But for some it is not used. In that case, the + // selectedObjects will not contain a capture time object and readCaptureTime will return null. final Optional previousCaptureTime = this.getPreviousCaptureTime(periodicMeterReads); - final Date captureTime = this.readCaptureTime(ctx, previousCaptureTime); + final Date captureTime = + this.readCaptureTime( + bufferedObjects, selectedObjects, previousCaptureTime, periodType, intervalTime); - LOGGER.debug("Converting bufferObject with value: {} ", ctx.bufferedObjects); + LOGGER.debug("Converting bufferObject with value: {} ", bufferedObjects); LOGGER.debug( "Resulting values: LogTime: {}, status: {}, gasValue {}, scalerUnit: {}, captureTime {} ", logTime, @@ -227,7 +321,7 @@ private PeriodicMeterReadsGasResponseItemDto convertToResponseItem( return new PeriodicMeterReadsGasResponseItemDto( logTime, - this.dlmsHelper.getScaledMeterValue(gasValue, scalerUnit, GAS_VALUE), + this.dlmsHelper.getScaledMeterValueWithScalerUnit(gasValue, scalerUnit, GAS_VALUE), captureTime, status); } @@ -249,65 +343,142 @@ private Optional getPreviousCaptureTime( return Optional.empty(); } - return Optional.of(periodicMeterReads.get(periodicMeterReads.size() - 1).getCaptureTime()); + final PeriodicMeterReadsGasResponseItemDto meterRead = + periodicMeterReads.get(periodicMeterReads.size() - 1); + + if (meterRead.getCaptureTime() == null) { + return Optional.empty(); + } + + return Optional.of(meterRead.getCaptureTime()); } - private DataObject readValue( + private Date readClock( + final PeriodTypeDto periodType, + final List selectedObjects, + final Optional previousLogTime, + final ProfileCaptureTime intervalTime, final List bufferedObjects, - final AttributeAddressForProfile attributeAddressForProfile) { + final DlmsHelper dlmsHelper) + throws ProtocolAdapterException, BufferedDateTimeValidationException { - final Integer valueIndex = - attributeAddressForProfile.getIndex(DlmsObjectType.MBUS_MASTER_VALUE, 2); + final Date logTime; - DataObject value = null; + final Integer clockIndex = this.getIndex(selectedObjects, CLOCK, null); - if (valueIndex != null) { - value = bufferedObjects.get(valueIndex); + CosemDateTimeDto cosemDateTime = null; + + if (clockIndex != null) { + cosemDateTime = + dlmsHelper.readDateTime( + bufferedObjects.get(clockIndex), "Clock from " + periodType + " buffer"); } - return value; + final DateTime bufferedDateTime = cosemDateTime == null ? null : cosemDateTime.asDateTime(); + + if (bufferedDateTime != null) { + logTime = bufferedDateTime.toDate(); + } else { + logTime = + this.calculateIntervalTimeBasedOnPreviousValue( + periodType, previousLogTime, Optional.of(intervalTime)); + } + + if (logTime == null) { + throw new BufferedDateTimeValidationException("Unable to calculate logTime"); + } + + return logTime; } - private DataObject readScalerUnit( - final List getResultList, - final List attributeAddresses, - final AttributeAddressForProfile attributeAddressForProfile, - final Integer channel) + AmrProfileStatusCodeDto readStatus( + final List bufferedObjects, + final List selectedObjects, + final PeriodTypeDto periodType) throws ProtocolAdapterException { - final DlmsCaptureObject captureObject = - attributeAddressForProfile.getCaptureObject(DlmsObjectType.MBUS_MASTER_VALUE); + final DlmsObjectType amrStatus = + switch (periodType) { + case INTERVAL -> AMR_PROFILE_STATUS_HOURLY_G; + case DAILY -> AMR_PROFILE_STATUS_DAILY_G; + case MONTHLY -> AMR_PROFILE_STATUS_MONTHLY_G; + }; + + Integer statusIndex = this.getIndex(selectedObjects, amrStatus, null); + if (statusIndex == null) { + // If combined profiles are used, get the index for the general amr status + statusIndex = this.getIndex(selectedObjects, AMR_PROFILE_STATUS, null); + } + + AmrProfileStatusCodeDto amrProfileStatusCode = null; + + if (statusIndex != null) { + amrProfileStatusCode = this.readAmrProfileStatusCode(bufferedObjects.get(statusIndex)); + } + + return amrProfileStatusCode; + } + + public Integer getIndex( + final List selectedObjects, + final DlmsObjectType type, + final Integer attributeId) + throws ProtocolAdapterException { + return this.getIndex(selectedObjects, type, attributeId, null); + } + + public Integer getIndex( + final List selectedObjects, + final DlmsObjectType type, + final Integer attributeId, + final Integer channel) + throws ProtocolAdapterException { int index = 0; - Integer scalerUnitIndex = null; - for (final AttributeAddress address : attributeAddresses) { - final String obisCode = - captureObject.getRelatedObject().getObisCodeAsString().replace("", channel.toString()); - if (address.getInstanceId().equals(new ObisCode(obisCode))) { - scalerUnitIndex = index; + + try { + for (final CaptureObject object : selectedObjects) { + if (object.getCosemObject().getTag().equals(type.name()) + && (attributeId == null || object.getAttributeId() == attributeId) + && (channel == null || object.getCosemObject().getChannel() == channel)) { + return index; + } + index++; } - index++; + } catch (final ObjectConfigException e) { + throw new ProtocolAdapterException("Can't get index for " + type.name(), e); } - // Get scaler unit from result list. Note: "index + 1" because the first result is the array - // with values - // and should be skipped. The first scaler unit is at index 1. - if (scalerUnitIndex != null) { - return getResultList.get(scalerUnitIndex + 1).getResultData(); + return null; + } + + private DataObject readValue( + final List bufferedObjects, + final List selectedObjects, + final int channel) + throws ProtocolAdapterException { + + final Integer valueIndex = this.getIndex(selectedObjects, MBUS_MASTER_VALUE, 2, channel); + + DataObject value = null; + + if (valueIndex != null) { + value = bufferedObjects.get(valueIndex); } - return null; + return value; } private Date readCaptureTime( - final ConversionContext ctx, final Optional previousCaptureTime) + final List bufferedObjects, + final List selectedObjects, + final Optional previousCaptureTime, + final PeriodTypeDto periodType, + final ProfileCaptureTime intervalTime) throws ProtocolAdapterException, BufferedDateTimeValidationException { - final List bufferedObjects = ctx.bufferedObjects; - final AttributeAddressForProfile attributeAddressForProfile = ctx.attributeAddressForProfile; - final Integer captureTimeIndex = - attributeAddressForProfile.getIndex(DlmsObjectType.MBUS_MASTER_VALUE, 5); + this.getIndex(selectedObjects, DlmsObjectType.MBUS_MASTER_VALUE, 5); if (captureTimeIndex != null) { final CosemDateTimeDto cosemDateTime = @@ -322,47 +493,340 @@ private Date readCaptureTime( } } else { return this.calculateIntervalTimeBasedOnPreviousValue( - ctx.periodicMeterReadsQuery.getPeriodType(), previousCaptureTime, ctx.intervalTime); + periodType, previousCaptureTime, Optional.of(intervalTime)); } } return null; } - private AttributeAddressForProfile getProfileBufferAddress( - final PeriodTypeDto periodType, - final ChannelDto channel, - final DateTime beginDateTime, - final DateTime endDateTime, + private String getScalerUnit(final List selectedObjects, final int channel) + throws ProtocolAdapterException { + + final Integer index = this.getIndex(selectedObjects, MBUS_MASTER_VALUE, 2, channel); + + if (index != null) { + return ((Register) selectedObjects.get(index).getCosemObject()).getScalerUnit(); + } else { + throw new ProtocolAdapterException("Can't get scaler unit, selected object not found"); + } + } + + private ProfileGeneric getProfileConfigObject( + final DlmsDevice device, final PeriodTypeDto periodType) throws ProtocolAdapterException { + final CosemObject profile; + + final String protocol = device.getProtocolName(); + final String version = device.getProtocolVersion(); + + try { + profile = + switch (periodType) { + case DAILY -> { + final Optional optionalDaily = + this.objectConfigService.getOptionalCosemObject( + protocol, version, DAILY_VALUES_G); + if (optionalDaily.isPresent()) { + yield optionalDaily.get(); + } else { + yield this.objectConfigService.getCosemObject( + protocol, version, DAILY_VALUES_COMBINED); + } + } + case MONTHLY -> { + final Optional optionalMonthly = + this.objectConfigService.getOptionalCosemObject( + protocol, version, MONTHLY_VALUES_G); + if (optionalMonthly.isPresent()) { + yield optionalMonthly.get(); + } else { + yield this.objectConfigService.getCosemObject( + protocol, version, MONTHLY_VALUES_COMBINED); + } + } + case INTERVAL -> this.objectConfigService.getCosemObject( + protocol, version, INTERVAL_VALUES_G); + }; + } catch (final ObjectConfigException e) { + throw new ProtocolAdapterException( + "Can't find profile object in " + + protocol + + " " + + version + + " config for " + + periodType.name() + + " values", + e); + } + + return (ProfileGeneric) profile; + } + + private AttributeAddress getAttributeAddressForProfile( + final CosemObject profile, + final DateTime from, + final DateTime to, + final int channel, + final List selectedCaptureObjects, + final boolean selectValues) { + + final SelectiveAccessDescription access = + this.getAccessDescription(selectedCaptureObjects, from, to, selectValues); + + final ObisCode obisCode = new ObisCode(profile.getObis().replace("x", String.valueOf(channel))); + + return new AttributeAddress(profile.getClassId(), obisCode, BUFFER.attributeId(), access); + } + + private List getCaptureObjectsInProfile( + final ProfileGeneric profile, + final DlmsDevice device, + final Integer channel, + final String deviceModel) + throws ProtocolAdapterException { + try { + return profile.getCaptureObjects( + this.objectConfigService, + device.getProtocolName(), + device.getProtocolVersion(), + channel, + deviceModel); + } catch (final ObjectConfigException e) { + throw new ProtocolAdapterException( + "Could not get capture objects for profile " + profile.getTag(), e); + } + } + + private List getSelectedCaptureObjects( + final List allCaptureObjectsInProfile, + final Medium medium, + final int channel, + final boolean selectedValuesSupported) + throws ProtocolAdapterException { + + final List selectedObjects = new ArrayList<>(); + + try { + for (final CaptureObject captureObject : allCaptureObjectsInProfile) { + // If selectedValues is supported, then select all capture objects with the same medium and + // the same channel. All abstract objects (clock and amr status) should be selected as well. + if (!selectedValuesSupported + || (captureObject.getCosemObject().getGroup().equals(medium.name()) + && captureObject.getCosemObject().getChannel() == channel) + || (captureObject.getCosemObject().getGroup().equals(Medium.ABSTRACT.name()))) { + selectedObjects.add(captureObject); + } + } + } catch (final ObjectConfigException e) { + throw new ProtocolAdapterException("Can't get selected capture objects", e); + } + + return selectedObjects; + } + + private SelectiveAccessDescription getAccessDescription( + final List selectedCaptureObjects, + final DateTime from, + final DateTime to, + final boolean selectValues) { + + if (from == null || to == null) { + return null; + } else { + final int accessSelector = 1; + + final DataObject selectedValues = this.getSelectedValuesObject(selectedCaptureObjects); + + final DataObject accessParameter = + this.dlmsHelper.getAccessSelectionTimeRangeParameter( + from, + to, + selectValues ? selectedValues : DataObject.newArrayData(Collections.emptyList())); + + return new SelectiveAccessDescription(accessSelector, accessParameter); + } + } + + private DataObject getSelectedValuesObject(final List selectedObjects) { + final List objectDefinitions = this.getObjectDefinitions(selectedObjects); + return DataObject.newArrayData(objectDefinitions); + } + + private List getObjectDefinitions(final List selectedObjects) { + final List objectDefinitions = new ArrayList<>(); + + for (final CaptureObject captureObject : selectedObjects) { + final CosemObject relatedObject = captureObject.getCosemObject(); + objectDefinitions.add( + DataObject.newStructureData( + Arrays.asList( + DataObject.newUInteger16Data(relatedObject.getClassId()), + DataObject.newOctetStringData(new ObisCode(relatedObject.getObis()).bytes()), + DataObject.newInteger8Data((byte) captureObject.getAttributeId()), + DataObject.newUInteger16Data(0)))); + } + + return objectDefinitions; + } + + private ProfileCaptureTime getProfileCaptureTime(final CosemObject profile) + throws ProtocolAdapterException { + + final Attribute capturePeriodAttribute = profile.getAttribute(CAPTURE_PERIOD.attributeId()); + final String capturePeriodValue = capturePeriodAttribute.getValue(); + + return switch (capturePeriodValue) { + case "3600" -> ProfileCaptureTime.HOUR; + case "86400" -> ProfileCaptureTime.DAY; + case "0" -> ProfileCaptureTime.MONTH; + default -> throw new ProtocolAdapterException( + "Unexpected capture period " + capturePeriodValue); + }; + } + + private List checkAndGetScalerUnits( + final List captureObjects, + final DlmsConnectionManager conn, + final DlmsDevice device, + final Medium medium, + final int channel) + throws ProtocolAdapterException { + final List captureObjectsWithScalerUnit = new ArrayList<>(); + + // Each relevant meter value retrieved from the meter should have a scaler and unit. If values + // were retrieved from a combined (E+G) profile and selectedValues is not supported, then + // more values are retrieved than needed. For example: if the request was for gas and channel 1, + // then all electricity values and values for other channels are not relevant and no scaler and + // unit is needed for those objects. Note: order of the capture objects is important and + // should not change. + final List relevantCaptureObjects = + this.getRelevantCaptureObjects(captureObjects, medium.name(), channel); + + final List captureObjectsThatNeedScalerUnitFromMeter = new ArrayList<>(); + + for (final CaptureObject captureObject : relevantCaptureObjects) { + final Register register = (Register) captureObject.getCosemObject(); + + // There are 2 possibilities for the scalerUnit in the capture object: + // - A fixed scalerUnit is defined. In that case, we don't need to do anything. + // - No scalerUnit is defined or the scalerUnit is defined as Dynamic. In that case, the + // scaler unit needs to be read from the meter + if (register.needsScalerUnitFromMeter()) { + captureObjectsThatNeedScalerUnitFromMeter.add(captureObject); + } + } + + // Get scaler units from meter. They are read from the meter in one call for efficiency. + final Map scalerUnits = + new HashMap<>( + this.getScalerUnitsFromMeter(captureObjectsThatNeedScalerUnitFromMeter, conn, device)); + + // Create a new list with capture objects and fill in the missing scaler units. + // Note: the order should be the same as the order of the capture objects in the input param. + for (final CaptureObject captureObject : captureObjects) { + if (scalerUnits.containsKey(captureObject)) { + final CosemObject cosemObject = captureObject.getCosemObject(); + final Attribute scalerUnitAttribute = + cosemObject.getAttribute(ExtendedRegisterAttribute.SCALER_UNIT.attributeId()); + + final Attribute newScalerUnitAttribute = + scalerUnitAttribute.copyWithNewValue(scalerUnits.get(captureObject)); + + captureObjectsWithScalerUnit.add( + captureObject.copyWithNewAttribute(newScalerUnitAttribute)); + } else { + captureObjectsWithScalerUnit.add(captureObject); + } + } + + return captureObjectsWithScalerUnit; + } + + private List getRelevantCaptureObjects( + final List captureObjects, final String medium, final int channel) { + return captureObjects.stream() + .filter(captureObject -> captureObject.getCosemObject() instanceof Register) + .filter( + captureObject -> + captureObject.getAttributeId() == ExtendedRegisterAttribute.VALUE.attributeId()) + .filter(captureObject -> captureObject.getCosemObject().getGroup().equals(medium)) + .filter( + captureObject -> + this.getChannelWithoutException(captureObject.getCosemObject()) == channel) + .toList(); + } + + private int getChannelWithoutException(final CosemObject object) { + try { + return object.getChannel(); + } catch (final ObjectConfigException e) { + return -1; + } + } + + private Map getScalerUnitsFromMeter( + final List captureObjects, + final DlmsConnectionManager conn, final DlmsDevice device) throws ProtocolAdapterException { + if (captureObjects.isEmpty()) { + return Map.of(); + } - final DlmsObjectType type = DlmsObjectType.getTypeForPeriodType(periodType); + final Map captureObjectsWithScalerUnit = new HashMap<>(); - // Add the attribute address for the profile - final AttributeAddressForProfile attributeAddressProfile = - this.dlmsObjectConfigService - .findAttributeAddressForProfile( - device, type, channel.getChannelNumber(), beginDateTime, endDateTime, Medium.GAS) - .orElseThrow(() -> new ProtocolAdapterException("No address found for " + type)); + final AttributeAddress[] scalerUnitAddresses = this.getScalerUnitAddresses(captureObjects); - LOGGER.debug( - "Dlms object config service returned profile buffer address {} ", attributeAddressProfile); + conn.getDlmsMessageListener() + .setDescription( + String.format( + "GetPeriodicMeterReadsGas scaler units, retrieve attribute: %s", + JdlmsObjectToStringUtil.describeAttributes(scalerUnitAddresses))); + + final List getResults = + this.dlmsHelper.getWithList(conn, device, scalerUnitAddresses); + + if (getResults.stream().anyMatch(result -> result.getResultCode() != AccessResultCode.SUCCESS) + || getResults.size() != captureObjects.size()) { + throw new ProtocolAdapterException( + "Could not get all scaler units from meter: " + getResults); + } + + final List scalerUnits = this.readScalerUnits(getResults); + + for (int i = 0; i < scalerUnits.size(); i++) { + captureObjectsWithScalerUnit.put(captureObjects.get(i), scalerUnits.get(i)); + } - return attributeAddressProfile; + return captureObjectsWithScalerUnit; } - private List getScalerUnitAddresses( - final ChannelDto channel, final AttributeAddressForProfile attributeAddressForProfile) { + private AttributeAddress[] getScalerUnitAddresses(final List captureObjects) { + return captureObjects.stream().map(this::getScalerUnitAddress).toArray(AttributeAddress[]::new); + } - final List attributeAddresses = - this.dlmsObjectConfigService.getAttributeAddressesForScalerUnit( - attributeAddressForProfile, channel.getChannelNumber()); + private AttributeAddress getScalerUnitAddress(final CaptureObject captureObject) { + final CosemObject cosemObject = captureObject.getCosemObject(); + return new AttributeAddress( + cosemObject.getClassId(), + new ObisCode(cosemObject.getObis()), + ExtendedRegisterAttribute.SCALER_UNIT.attributeId()); + } - LOGGER.debug( - "Dlms object config service returned scaler unit addresses {} ", attributeAddresses); + private List readScalerUnits(final List getResultList) + throws ProtocolAdapterException { + + final List scalerUnits = new ArrayList<>(); + + for (final GetResult getResult : getResultList) { + final DataObject scalerUnitObject = getResult.getResultData(); + + scalerUnits.add( + this.dlmsHelper.getScalerUnit( + scalerUnitObject, "get scaler unit for periodic meter reads")); + } - return attributeAddresses; + return scalerUnits; } @Override diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/pushsetup/SetPushSetupUdpCommandExecutor.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/pushsetup/SetPushSetupUdpCommandExecutor.java index 8318af2dc17..c3c135f7735 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/pushsetup/SetPushSetupUdpCommandExecutor.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/pushsetup/SetPushSetupUdpCommandExecutor.java @@ -17,6 +17,7 @@ import org.openmuc.jdlms.AttributeAddress; import org.openmuc.jdlms.SetParameter; import org.openmuc.jdlms.datatypes.DataObject; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.AbstractCommandExecutor; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDevice; import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionManager; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; @@ -100,7 +101,7 @@ private SetParameter getSetParameterCommunicationWindow(final DlmsDevice device) return new SetParameter(communicationWindowAddress, value); } catch (final ObjectConfigException e) { - throw new ProtocolAdapterException("Error in object config", e); + throw new ProtocolAdapterException(AbstractCommandExecutor.ERROR_IN_OBJECT_CONFIG, e); } } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/utils/DlmsHelper.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/utils/DlmsHelper.java index 172f68d186e..910f1417001 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/utils/DlmsHelper.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/utils/DlmsHelper.java @@ -34,6 +34,12 @@ import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionManager; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ConnectionException; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; +import org.opensmartgridplatform.dlms.interfaceclass.InterfaceClass; +import org.opensmartgridplatform.dlms.interfaceclass.attribute.ExtendedRegisterAttribute; +import org.opensmartgridplatform.dlms.interfaceclass.attribute.RegisterAttribute; +import org.opensmartgridplatform.dlms.objectconfig.Attribute; +import org.opensmartgridplatform.dlms.objectconfig.CosemObject; +import org.opensmartgridplatform.dlms.objectconfig.ValueType; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ClockStatusDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.CosemDateDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.CosemDateTimeDto; @@ -309,6 +315,13 @@ public DlmsMeterValueDto getScaledMeterValue( final DataObject value, final DataObject scalerUnitObject, final String description) throws ProtocolAdapterException { + final String scalerUnit = this.getScalerUnit(scalerUnitObject, description); + + return this.getScaledMeterValueWithScalerUnit(value, scalerUnit, description); + } + + public String getScalerUnit(final DataObject scalerUnitObject, final String description) + throws ProtocolAdapterException { LOGGER.debug(this.getDebugInfo(scalerUnitObject)); if (!scalerUnitObject.isComplex()) { @@ -332,7 +345,7 @@ public DlmsMeterValueDto getScaledMeterValue( "expected a unit instead of unit UNDEFINED." + this.getDebugInfo(scalerUnitObject)); } - return this.createDlmsMeterValueBasedOnValueAndScalerAndUnit(value, scaler, unit, description); + return scaler + ", " + unit.getUnit(); } private DlmsMeterValueDto createDlmsMeterValueBasedOnValueAndScalerAndUnit( @@ -1035,4 +1048,53 @@ private void logAndThrowExceptionForUnexpectedResultData( + ", value type: " + resultDataType); } + + public String getScalerUnitValue(final DlmsConnectionManager conn, final CosemObject object) + throws ProtocolAdapterException { + final int attributeId; + if (object.getClassId() == InterfaceClass.REGISTER.id()) { + attributeId = RegisterAttribute.SCALER_UNIT.attributeId(); + } else if (object.getClassId() == InterfaceClass.EXTENDED_REGISTER.id()) { + attributeId = ExtendedRegisterAttribute.SCALER_UNIT.attributeId(); + } else { + return null; + } + + final Attribute attribute = object.getAttribute(attributeId); + if (attribute.getValuetype() == ValueType.FIXED_IN_PROFILE) { + return attribute.getValue(); + } else { + final AttributeAddress attributeAddress = + new AttributeAddress(object.getClassId(), object.getObis(), attributeId); + + try { + final DataObject scalerUnitObject = this.getAttributeValue(conn, attributeAddress); + LOGGER.debug(this.getDebugInfo(scalerUnitObject)); + + if (!scalerUnitObject.isComplex()) { + throw new ProtocolAdapterException( + "complex data (structure) expected while retrieving scaler and unit." + + this.getDebugInfo(scalerUnitObject)); + } + final List dataObjects = scalerUnitObject.getValue(); + if (dataObjects.size() != 2) { + throw new ProtocolAdapterException( + "expected 2 values while retrieving scaler and unit." + + this.getDebugInfo(scalerUnitObject)); + } + final int scaler = + this.readLongNotNull(dataObjects.get(0), object.getDescription()).intValue(); + final DlmsUnitTypeDto unit = + DlmsUnitTypeDto.getUnitType( + this.readLongNotNull(dataObjects.get(1), object.getDescription()).intValue()); + + return String.format("%s, %s", scaler, unit.getUnit()); + } catch (final FunctionalException e) { + throw new ProtocolAdapterException( + "FunctionalException occurred when reading dynamic scalar unit for object: " + + object.getObis(), + e); + } + } + } } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/utils/ObjectConfigServiceHelper.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/utils/ObjectConfigServiceHelper.java new file mode 100644 index 00000000000..a4498e43890 --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/utils/ObjectConfigServiceHelper.java @@ -0,0 +1,174 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils; + +import java.util.Optional; +import org.openmuc.jdlms.AttributeAddress; +import org.openmuc.jdlms.ObisCode; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDevice; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.Protocol; +import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; +import org.opensmartgridplatform.dlms.exceptions.ObjectConfigException; +import org.opensmartgridplatform.dlms.objectconfig.Attribute; +import org.opensmartgridplatform.dlms.objectconfig.CosemObject; +import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; +import org.opensmartgridplatform.dlms.services.ObjectConfigService; +import org.springframework.stereotype.Component; + +@Component +/** + * Is an intermediate class to get acces from the dlms-protocol-adapter to the ObjectConfigService. + * It contains helper functions to lookup CosemObjects and Attributes. + */ +public class ObjectConfigServiceHelper { + + private static final int DEFAULT_ATTRIBUTE_ID = 2; + + private final ObjectConfigService objectConfigService; + + public ObjectConfigServiceHelper(final ObjectConfigService objectConfigService) { + this.objectConfigService = objectConfigService; + } + + /** + * Find an optional attribute from the ObjectConfigService based on the protocol and + * protocolVersion, DlmsObjectType name and channel. When not found the Optional empty is + * returned. + * + * @param protocol protocol like DSMR or SMR 5.5 + * @param dlmsObjectType the DlmsObjectType to find + * @param channel the channel of the device to access + * @return Optional when found it returns a newly created AttributeAddress or + * else Optional.empty() + */ + public Optional findOptionalDefaultAttributeAddress( + final Protocol protocol, final DlmsObjectType dlmsObjectType, final Integer channel) { + + return this.findOptionalAttributeAddress( + protocol, dlmsObjectType, channel, DEFAULT_ATTRIBUTE_ID); + } + + /** + * Find an optional default attribute from the ObjectConfigService based on the protocol and + * protocolVersion and a DlmsObjectType name. When not found the Optional empty is returned. + * + * @param protocol protocol like DSMR or SMR 5.5 + * @param dlmsObjectType the DlmsObjectType to find + * @return Optional when found it returns a newly created AttributeAddress or + * else Optional.empty() + */ + public Optional findOptionalDefaultAttributeAddress( + final Protocol protocol, final DlmsObjectType dlmsObjectType) { + + return this.findOptionalAttributeAddress(protocol, dlmsObjectType, null, DEFAULT_ATTRIBUTE_ID); + } + + /** + * Find an optional attribute from the ObjectConfigService based on the protocol and + * protocolVersion , DlmsObjectType name, channel and attributeId. When not found the Optional + * empty is returned. + * + * @param protocol protocol like SMR 5.5 + * @param dlmsObjectType the DlmsObjectType to find + * @param channel the channel of the device to access + * @param attributeId the attributeId to find + * @return Optional when found it returns a newly created AttributeAddress or + * else Optional.empty() + */ + public Optional findOptionalAttributeAddress( + final Protocol protocol, + final DlmsObjectType dlmsObjectType, + final Integer channel, + final int attributeId) { + + final Optional optObject = + this.getOptionalCosemObject(protocol.getName(), protocol.getVersion(), dlmsObjectType); + if (optObject.isEmpty()) { + return Optional.empty(); + } + + final CosemObject cosemObject = optObject.get(); + final int classId = cosemObject.getClassId(); + final ObisCode obisCode = this.replaceChannel(cosemObject.getObis(), channel); + + final Optional attributeOpt = + Optional.ofNullable(cosemObject.getAttribute(attributeId)); + + return attributeOpt.map(value -> new AttributeAddress(classId, obisCode, value.getId())); + } + + private Optional getOptionalCosemObject( + final String protocol, final String protocolVersion, final DlmsObjectType objectType) { + + try { + return this.objectConfigService.getOptionalCosemObject(protocol, protocolVersion, objectType); + } catch (final ObjectConfigException e) { + return Optional.empty(); + } + } + + /** + * Find a required default attribute from the ObjectConfigService based on the protocol and + * protocolVersion and a DlmsObjectType name. When not found a ProtocolAdapterException is thrown. + * + * @param dlmsDevice The device to find the object for + * @param protocol protocol like SMR 5.5 + * @param dlmsObjectType the DlmsObjectType to find + * @param channel the channel of the device to access + * @return AttributeAddress when found it returns a newly created AttributeAddress or else a + * ProtocolAdapterException is thrown + */ + public AttributeAddress findDefaultAttributeAddress( + final DlmsDevice dlmsDevice, + final Protocol protocol, + final DlmsObjectType dlmsObjectType, + final Integer channel) + throws ProtocolAdapterException { + + return this.findAttributeAddress( + dlmsDevice, protocol, dlmsObjectType, channel, DEFAULT_ATTRIBUTE_ID); + } + + /** + * Find a required attribute from the ObjectConfigService based on the protocol and + * protocolVersion and a DlmsObjectType name. When not found a ProtocolAdapterException is thrown. + * + * @param dlmsDevice The device to find the object for + * @param protocol protocol like SMR 5.5 + * @param dlmsObjectType the DlmsObjectType to find + * @param channel the channel of the device to access + * @param attributeId the attributeId to find + * @return AttributeAddress when found it returns a newly created AttributeAddress or else a + * ProtocolAdapterException is thrown + */ + public AttributeAddress findAttributeAddress( + final DlmsDevice dlmsDevice, + final Protocol protocol, + final DlmsObjectType dlmsObjectType, + final Integer channel, + final int attributeId) + throws ProtocolAdapterException { + + final Optional attributeAddressOpt = + this.findOptionalAttributeAddress(protocol, dlmsObjectType, channel, attributeId); + + return attributeAddressOpt.orElseThrow( + () -> { + final String message = + String.format( + "Did not find %s object for device %s for channel %s", + dlmsObjectType, dlmsDevice.getDeviceId(), channel); + return new ProtocolAdapterException(message); + }); + } + + private ObisCode replaceChannel(String obisCode, final Integer channel) { + if (channel != null) { + obisCode = obisCode.replace("x", channel.toString()); + } + + return new ObisCode(obisCode); + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/entities/DlmsDevice.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/entities/DlmsDevice.java index 73b64ae87f2..b33643ae761 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/entities/DlmsDevice.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/entities/DlmsDevice.java @@ -28,7 +28,7 @@ public class DlmsDevice extends AbstractEntity { @Column private String iccId; - @Column private boolean lls1Active = true; + @Column private boolean lls1Active; @Column private boolean hls3Active; @@ -42,6 +42,8 @@ public class DlmsDevice extends AbstractEntity { @Column private boolean selectiveAccessSupported; + @Column private boolean selectiveAccessPeriodicMeterReadsSupported = true; + @Column private boolean ipAddressIsStatic; // The following three are optional columns that are used in the device @@ -89,6 +91,9 @@ public class DlmsDevice extends AbstractEntity { // session. @Column private Long invocationCounter = 0L; + @Column(length = 64) + private String firmwareHash; + public DlmsDevice() { // Default constructor } @@ -240,6 +245,15 @@ public void setSelectiveAccessSupported(final boolean selectiveAccessSupported) this.selectiveAccessSupported = selectiveAccessSupported; } + public boolean isSelectiveAccessPeriodicMeterReadsSupported() { + return this.selectiveAccessPeriodicMeterReadsSupported; + } + + public void setSelectiveAccessPeriodicMeterReadsSupported( + final boolean selectiveAccessPeriodicMeterReadsSupported) { + this.selectiveAccessPeriodicMeterReadsSupported = selectiveAccessPeriodicMeterReadsSupported; + } + public void setDeviceIdentification(final String deviceIdentification) { this.deviceIdentification = deviceIdentification; } @@ -403,4 +417,12 @@ public String getTimezone() { public void setTimezone(final String timezone) { this.timezone = timezone; } + + public String getFirmwareHash() { + return this.firmwareHash; + } + + public void setFirmwareHash(final String firmwareHash) { + this.firmwareHash = firmwareHash; + } } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/entities/Protocol.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/entities/Protocol.java index 49766008e0b..5db36faf0b1 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/entities/Protocol.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/entities/Protocol.java @@ -5,25 +5,21 @@ package org.opensmartgridplatform.adapter.protocol.dlms.domain.entities; public enum Protocol { - DSMR_4_2_2("DSMR", "4.2.2", true), - SMR_4_3("SMR", "4.3", true), - SMR_5_0_0("SMR", "5.0.0", true), - SMR_5_1("SMR", "5.1", true), - SMR_5_2("SMR", "5.2", true), - SMR_5_5("SMR", "5.5", true), - OTHER_PROTOCOL("?", "?", true); + DSMR_2_2("DSMR", "2.2"), + DSMR_4_2_2("DSMR", "4.2.2"), + SMR_4_3("SMR", "4.3"), + SMR_5_0_0("SMR", "5.0.0"), + SMR_5_1("SMR", "5.1"), + SMR_5_2("SMR", "5.2"), + SMR_5_5("SMR", "5.5"), + OTHER_PROTOCOL("?", "?"); private final String name; private final String version; - private final boolean selectValuesInSelectiveAccessSupported; - Protocol( - final String name, - final String version, - final boolean selectValuesInSelectiveAccessSupported) { + Protocol(final String name, final String version) { this.name = name; this.version = version; - this.selectValuesInSelectiveAccessSupported = selectValuesInSelectiveAccessSupported; } public String getName() { @@ -34,10 +30,6 @@ public String getVersion() { return this.version; } - public boolean isSelectValuesInSelectiveAccessSupported() { - return this.selectValuesInSelectiveAccessSupported; - } - public static Protocol forDevice(final DlmsDevice device) { return withNameAndVersion(device.getProtocolName(), device.getProtocolVersion()); } @@ -55,6 +47,22 @@ public static Protocol withNameAndVersion( return OTHER_PROTOCOL; } + public boolean isDsmr2() { + return this.version.startsWith("2."); + } + + public boolean isDsmr4() { + return this.version.startsWith("4."); + } + + public boolean isDsmr42() { + return this.version.startsWith("4.2"); + } + + public boolean isDsmr43() { + return this.version.startsWith("4.3"); + } + public boolean isSmr5() { return this.version.startsWith("5."); } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/DlmsConnectionFactory.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/DlmsConnectionFactory.java index 271d8c64d2b..a0fedd38d98 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/DlmsConnectionFactory.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/DlmsConnectionFactory.java @@ -111,37 +111,6 @@ public void createAndHandleConnection( taskForConnectionManager); } - /** - * Creates an open connection to the device using its Public client association and passes the - * connection to the {@code taskForConnectionManager} to execute the tasks before closing the - * connection. - * - *

    This does not use a throttling permit for network access. When such a permit is required, - * make sure to obtain one that is granted and call {@link - * #createAndHandlePublicClientConnection(MessageMetadata, DlmsDevice, DlmsMessageListener, Permit, Consumer). - * - * @param messageMetadata the metadata of the request message - * @param device The device to connect to. This reference can be updated when the invalid but - * correctable connection credentials are detected. - * @param dlmsMessageListener A message listener that will be provided to the {@link - * DlmsConnection} that is initialized if the given {@code device} is in {@link - * DlmsDevice#isInDebugMode() debug mode}. If this is {@code null} no DLMS device - * communication debug logging will be done. - * @param taskForConnectionManager A task for the DLMS connection manager to handle when the DLMS - * connection is open - * @throws OsgpException in case of a TechnicalException or FunctionalException - */ - public void createAndHandlePublicClientConnection( - final MessageMetadata messageMetadata, - final DlmsDevice device, - final DlmsMessageListener dlmsMessageListener, - final Consumer taskForConnectionManager) - throws OsgpException { - - this.createAndHandlePublicClientConnection( - messageMetadata, device, dlmsMessageListener, null, taskForConnectionManager); - } - /** * Creates an open connection to the device using its Public client association and passes the * connection to the {@code taskForConnectionManager} to execute the tasks before closing the diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/InvocationCounterManager.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/InvocationCounterManager.java index d58b4fb9783..ff553883c15 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/InvocationCounterManager.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/InvocationCounterManager.java @@ -59,8 +59,24 @@ public InvocationCounterManager( */ public void initializeInvocationCounter( final MessageMetadata messageMetadata, final DlmsDevice device) throws OsgpException { + /* + * When the invocation counter is out of sync, some devices close the session. + * By setting the ip-address to null, the application will be forced to get a new ip-address. + * The meter will start a new session. + * This is done by the DlmsConnectionFactory in the method: + * this.domainHelperService.setIpAddressFromMessageMetadataOrSessionProvider + */ + device.setIpAddress(null); this.initializeWithInvocationCounterStoredOnDevice(messageMetadata, device, null); + + /* + * by setting the ip-address to null again, the application will be forced to get a new ip-address. + * The meter will start a new session. + * This is done by the DlmsConnectionFactory in the method: + * this.domainHelperService.setIpAddressFromMessageMetadataOrSessionProvider + */ + device.setIpAddress(null); } /** @@ -68,12 +84,6 @@ public void initializeInvocationCounter( * be called for a device that actually has an invocation counter stored on the device itself. If * a permit for network access is passed, it is to be released upon closing the connection. */ - public void initializeInvocationCounter( - final MessageMetadata messageMetadata, final DlmsDevice device, final Permit permit) - throws OsgpException { - this.initializeWithInvocationCounterStoredOnDevice(messageMetadata, device, permit); - } - private void initializeWithInvocationCounterStoredOnDevice( final MessageMetadata messageMetadata, final DlmsDevice device, final Permit permit) throws OsgpException { diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/SecureDlmsConnector.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/SecureDlmsConnector.java index 2059dc873b2..63421ad58ba 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/SecureDlmsConnector.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/SecureDlmsConnector.java @@ -65,6 +65,10 @@ DlmsConnection createConnection( .setReferencingMethod( device.isUseSn() ? ReferencingMethod.SHORT : ReferencingMethod.LOGICAL); + if (device.isLls1Active()) { + tcpConnectionBuilder.setAlwaysSendSecurityMechanismName(true).setSkipAARQEncryption(true); + } + if (device.isUseHdlc()) { tcpConnectionBuilder.useHdlc(); } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/repositories/DlmsDeviceRepository.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/repositories/DlmsDeviceRepository.java index 66bd25c41b3..47471025946 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/repositories/DlmsDeviceRepository.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/repositories/DlmsDeviceRepository.java @@ -43,4 +43,15 @@ int setProcessingStartTime( int updateInvocationCounter( @Param("deviceIdentification") String deviceIdentification, @Param("invocationCounter") Long invocationCounter); + + @Transactional + @Modifying + @Query( + value = + "UPDATE DlmsDevice" + + " SET firmwareHash = :firmwareHash" + + " WHERE deviceIdentification = :deviceIdentification") + int storeFirmwareHash( + @Param("deviceIdentification") String deviceIdentification, + @Param("firmwareHash") String firmwareHash); } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/valueobjects/CombinedDeviceModelCode.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/valueobjects/CombinedDeviceModelCode.java new file mode 100644 index 00000000000..5388eb49eb8 --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/valueobjects/CombinedDeviceModelCode.java @@ -0,0 +1,133 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 +package org.opensmartgridplatform.adapter.protocol.dlms.domain.valueobjects; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +/** + * Container for combined DeviceModelCodes that contains a gateway device model code and multiple + * channel based device model codes in the order of the channels 1-4. The format is : + * GatewayDeviceModelCode,Channel1DeviceModelCode,Channel2DeviceModelCode,Channel3DeviceModelCode,Channel4DeviceModelCode + */ +@Slf4j +public class CombinedDeviceModelCode { + + public static final String SEPERATOR = ","; + + public static final int SEPERATOR_COUNT_4 = 4; + + private final String gatewayDeviceModelCode; + private final Map channelBasedDeviceModelCodes; + + private CombinedDeviceModelCode() { + this.gatewayDeviceModelCode = null; + this.channelBasedDeviceModelCodes = new HashMap<>(); + } + + private CombinedDeviceModelCode( + final String gatewayDeviceModelCode, + final Map channelBasedDeviceModelCodes) { + this.gatewayDeviceModelCode = gatewayDeviceModelCode; + this.channelBasedDeviceModelCodes = channelBasedDeviceModelCodes; + } + + public static CombinedDeviceModelCode parse(final String combinedDeviceModelCodes) { + if (!hasCombinedDeviceModelCodes(combinedDeviceModelCodes)) { + log.info( + "Devicemodelcode field on MessageMetaData does not contain expected combined device model codes, got: [{}]", + combinedDeviceModelCodes); + return new CombinedDeviceModelCode(); + } + + if (!hasContent(combinedDeviceModelCodes)) { + log.info( + "Devicemodelcode field on MessageMetaData does not contain device model codes, got: [{}]", + combinedDeviceModelCodes); + return new CombinedDeviceModelCode(); + } + + final String[] codes = combinedDeviceModelCodes.split(SEPERATOR); + + final String gatewayDeviceModelCode = getGatewayDeciceModelCode(codes); + final Map channelBasedDeviceModelCodes = getMbusDeviceModelCodes(codes); + + return new CombinedDeviceModelCode(gatewayDeviceModelCode, channelBasedDeviceModelCodes); + } + + private static Map getMbusDeviceModelCodes(final String[] codes) { + final Map channelBasedDeviceModelCodes = new HashMap<>(); + for (int i = 1; i < codes.length; i++) { + channelBasedDeviceModelCodes.put(i, codes[i]); + } + return channelBasedDeviceModelCodes; + } + + private static String getGatewayDeciceModelCode(final String[] codes) { + return codes.length >= 1 ? codes[0] : null; + } + + private static boolean hasCombinedDeviceModelCodes(final String combinedDeviceModelCodes) { + + return combinedDeviceModelCodes != null + && combinedDeviceModelCodes.chars().filter(ch -> ch == SEPERATOR.charAt(0)).count() + == SEPERATOR_COUNT_4; + } + + private static boolean hasContent(final String combinedDeviceModelCodes) { + + return combinedDeviceModelCodes.length() > SEPERATOR_COUNT_4; + } + + public String getCodeFromChannel(final int i) { + return this.channelBasedDeviceModelCodes.get(i); + } + + @Override + public String toString() { + final List codes = new ArrayList<>(); + codes.add( + StringUtils.isNotBlank(this.gatewayDeviceModelCode) ? this.gatewayDeviceModelCode : ""); + for (int i = 1; i < 5; i++) { + final String code = this.channelBasedDeviceModelCodes.get(i); + codes.add(StringUtils.isNotBlank(code) ? code : ""); + } + return String.join(SEPERATOR, codes); + } + + public String getGatewayDeviceModelCode() { + return this.gatewayDeviceModelCode; + } + + // Builder Class + public static class CombinedDeviceModelCodeBuilder { + + private String gatewayDeviceModelCode; + private Map channelBasedDeviceModelCodes; + + public CombinedDeviceModelCodeBuilder gatewayDeviceModelCode( + final String gatewayDeviceModelCode) { + this.gatewayDeviceModelCode = gatewayDeviceModelCode; + return this; + } + + public CombinedDeviceModelCodeBuilder channelBasedDeviceModelCode( + final int channel, final String code) { + if (this.channelBasedDeviceModelCodes == null) { + this.channelBasedDeviceModelCodes = new HashMap<>(); + } + this.channelBasedDeviceModelCodes.put(channel, code); + return this; + } + + public CombinedDeviceModelCode build() { + return new CombinedDeviceModelCode( + this.gatewayDeviceModelCode, this.channelBasedDeviceModelCodes); + } + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/DeviceRequestMessageProcessor.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/DeviceRequestMessageProcessor.java index 48d79527795..fc080e87854 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/DeviceRequestMessageProcessor.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/DeviceRequestMessageProcessor.java @@ -11,6 +11,7 @@ import javax.jms.JMSException; import javax.jms.ObjectMessage; import lombok.extern.slf4j.Slf4j; +import org.opensmartgridplatform.adapter.protocol.dlms.application.config.ThrottlingConfig; import org.opensmartgridplatform.adapter.protocol.dlms.application.services.DomainHelperService; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDevice; import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionManager; @@ -57,6 +58,8 @@ public abstract class DeviceRequestMessageProcessor extends DlmsConnectionMessag @Autowired private DeviceRequestMessageSender deviceRequestMessageSender; + @Autowired private ThrottlingConfig throttlingConfig; + protected final MessageType messageType; /** @@ -91,7 +94,7 @@ public void processMessage(final ObjectMessage message) throws JMSException { } else { device = null; } - if (this.usesDeviceConnection()) { + if (this.usesDeviceConnection(messageObject)) { /* * Set up a consumer to be called back with a DlmsConnectionManager for which the connection * with the device has been created. Note that when usesDeviceConnection is true, in this @@ -111,15 +114,17 @@ public void processMessage(final ObjectMessage message) throws JMSException { * Throttling permit for network access not granted, send the request back to the queue to be * picked up again a little later by the message listener for device requests. */ + final Duration permitRejectDelay = + this.throttlingConfig.permitRejectedDelay(messageMetadata.getMessagePriority()); log.info( - "Throttling permit was denied for deviceIdentification {} for network segment ({}, {}) for {}. retry message in {} ms", + "Throttling permit was denied for deviceIdentification {} for network segment ({}, {}) with priority {} for {}. retry message in {} ms", messageMetadata.getDeviceIdentification(), exception.getBaseTransceiverStationId(), exception.getCellId(), + exception.getPriority(), exception.getConfigurationName(), - this.throttlingClientConfig.permitRejectedDelay().toMillis()); - this.deviceRequestMessageSender.send( - messageObject, messageMetadata, this.throttlingClientConfig.permitRejectedDelay()); + permitRejectDelay.toMillis()); + this.deviceRequestMessageSender.send(messageObject, messageMetadata, permitRejectDelay); } catch (final DeviceKeyProcessAlreadyRunningException exception) { @@ -239,7 +244,7 @@ protected Serializable handleMessage( final MessageMetadata messageMetadata) throws OsgpException { throw new UnsupportedOperationException( - "handleMessage(Serializable) should be overriden by a subclass, or usesDeviceConnection should return" + "handleMessage(Serializable) should be overridden by a subclass, or usesDeviceConnection should return" + " true."); } @@ -249,7 +254,7 @@ protected Serializable handleMessage( * * @return Use device connection in handleMessage. */ - protected boolean usesDeviceConnection() { + protected boolean usesDeviceConnection(final Serializable messageObject) { return true; } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/DlmsConnectionMessageProcessor.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/DlmsConnectionMessageProcessor.java index d8268e6b15e..6d9bd05ae6b 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/DlmsConnectionMessageProcessor.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/DlmsConnectionMessageProcessor.java @@ -7,9 +7,8 @@ import java.io.Serializable; import java.util.function.Consumer; import javax.jms.JMSException; -import org.opensmartgridplatform.adapter.protocol.dlms.application.config.ThrottlingClientConfig; import org.opensmartgridplatform.adapter.protocol.dlms.application.services.SystemEventService; -import org.opensmartgridplatform.adapter.protocol.dlms.application.services.ThrottlingService; +import org.opensmartgridplatform.adapter.protocol.dlms.application.throttling.ThrottlingService; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDevice; import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionHelper; import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionManager; @@ -47,10 +46,7 @@ public abstract class DlmsConnectionMessageProcessor { @Autowired protected DlmsDeviceRepository deviceRepository; - @Autowired(required = false) - protected ThrottlingService throttlingService; - - @Autowired protected ThrottlingClientConfig throttlingClientConfig; + @Autowired protected ThrottlingService throttlingService; @Autowired private SystemEventService systemEventService; @@ -60,16 +56,11 @@ public void createAndHandleConnectionForDevice( final Consumer taskForConnectionManager) throws OsgpException { - Permit permit = null; - if (this.throttlingClientConfig.clientEnabled()) { - permit = - this.throttlingClientConfig - .throttlingClient() - .requestPermitUsingNetworkSegmentIfIdsAreAvailable( - messageMetadata.getBaseTransceiverStationId(), messageMetadata.getCellId()); - } else { - this.throttlingService.openConnection(); - } + final Permit permit = + this.throttlingService.requestPermit( + messageMetadata.getBaseTransceiverStationId(), + messageMetadata.getCellId(), + messageMetadata.getMessagePriority()); final DlmsMessageListener dlmsMessageListener = this.createMessageListenerForDeviceConnection(device, messageMetadata); @@ -95,11 +86,7 @@ public void createAndHandleConnectionForDevice( * DeviceRequestMessageProcessor.processMessageTasks(), where * this.doConnectionPostProcessing() is called in a finally block. */ - if (this.throttlingClientConfig.clientEnabled()) { - this.throttlingClientConfig.throttlingClient().releasePermit(permit); - } else { - this.throttlingService.closeConnection(); - } + this.throttlingService.releasePermit(permit); throw e; } } @@ -136,11 +123,7 @@ protected void doConnectionPostProcessing( this.setClosingDlmsConnectionMessageListener(device, conn); - if (this.throttlingClientConfig.clientEnabled()) { - this.throttlingClientConfig.throttlingClient().releasePermit(conn.getPermit()); - } else { - this.throttlingService.closeConnection(); - } + this.throttlingService.releasePermit(conn.getPermit()); if (device.needsInvocationCounter()) { this.updateInvocationCounterForDevice(device, conn); @@ -178,6 +161,7 @@ void updateInvocationCounterForDevice(final DlmsDevice device, final DlmsConnect this.deviceRepository.updateInvocationCounter( device.getDeviceIdentification(), device.getInvocationCounter()); } + /** * @param logger the logger from the calling subClass * @param exception the exception to be logged diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/AddMeterRequestMessageProcessor.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/AddMeterRequestMessageProcessor.java index a3f063811ce..43c19deeb1d 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/AddMeterRequestMessageProcessor.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/AddMeterRequestMessageProcessor.java @@ -26,7 +26,7 @@ public AddMeterRequestMessageProcessor() { } @Override - protected boolean usesDeviceConnection() { + protected boolean usesDeviceConnection(final Serializable messageObject) { return false; } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/DisableDebuggingRequestMessageProcessor.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/DisableDebuggingRequestMessageProcessor.java index a0e5f6442f3..3598df91583 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/DisableDebuggingRequestMessageProcessor.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/DisableDebuggingRequestMessageProcessor.java @@ -24,7 +24,7 @@ public DisableDebuggingRequestMessageProcessor() { } @Override - protected boolean usesDeviceConnection() { + protected boolean usesDeviceConnection(final Serializable messageObject) { return false; } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/EnableDebuggingRequestMessageProcessor.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/EnableDebuggingRequestMessageProcessor.java index af45a152c3d..91dcf7735f5 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/EnableDebuggingRequestMessageProcessor.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/EnableDebuggingRequestMessageProcessor.java @@ -24,7 +24,7 @@ public EnableDebuggingRequestMessageProcessor() { } @Override - protected boolean usesDeviceConnection() { + protected boolean usesDeviceConnection(final Serializable messageObject) { return false; } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/GetKeysRequestMessageProcessor.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/GetKeysRequestMessageProcessor.java index 267834997b6..0c8e3f2e4f1 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/GetKeysRequestMessageProcessor.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/GetKeysRequestMessageProcessor.java @@ -25,7 +25,7 @@ protected GetKeysRequestMessageProcessor() { } @Override - protected boolean usesDeviceConnection() { + protected boolean usesDeviceConnection(final Serializable messageObject) { return false; } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/SetDeviceCommunicationSettingsRequestMessageProcessor.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/SetDeviceCommunicationSettingsRequestMessageProcessor.java index fa3976e98a3..7bb2b6618ec 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/SetDeviceCommunicationSettingsRequestMessageProcessor.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/SetDeviceCommunicationSettingsRequestMessageProcessor.java @@ -26,7 +26,7 @@ public SetDeviceCommunicationSettingsRequestMessageProcessor() { } @Override - protected boolean usesDeviceConnection() { + protected boolean usesDeviceConnection(final Serializable messageObject) { return false; } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/UpdateFirmwareRequestMessageProcessor.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/UpdateFirmwareRequestMessageProcessor.java index 70c1658063c..e6505145dfd 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/UpdateFirmwareRequestMessageProcessor.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/UpdateFirmwareRequestMessageProcessor.java @@ -37,6 +37,54 @@ protected UpdateFirmwareRequestMessageProcessor() { super(MessageType.UPDATE_FIRMWARE); } + @Override + protected boolean usesDeviceConnection(final Serializable messageObject) { + if (messageObject instanceof final UpdateFirmwareRequestDto requestDto) { + final String firmwareIdentification = requestDto.getFirmwareIdentification(); + final boolean usesDeviceConnection = + this.firmwareService.isFirmwareFileAvailable(firmwareIdentification); + if (!usesDeviceConnection) { + LOGGER.info( + "Firmware file [{}] not available for device {}. So no device connection required for sending GetFirmwareFile request to core.", + firmwareIdentification, + requestDto.getDeviceIdentification()); + } + return usesDeviceConnection; + } + return super.usesDeviceConnection(messageObject); + } + + @Override + protected Serializable handleMessage( + final DlmsDevice device, + final Serializable requestObject, + final MessageMetadata messageMetadata) + throws OsgpException { + // This method will be invoked when usesDeviceConnection returns false (firmwareFile is not + // available) + final String deviceIdentification = messageMetadata.getDeviceIdentification(); + final String organisationIdentification = messageMetadata.getOrganisationIdentification(); + final String correlationUid = messageMetadata.getCorrelationUid(); + + final UpdateFirmwareRequestDto updateFirmwareRequestDto = + (UpdateFirmwareRequestDto) requestObject; + final String firmwareIdentification = updateFirmwareRequestDto.getFirmwareIdentification(); + + LOGGER.info( + "[{}] - Firmware file [{}] not available. Sending GetFirmwareFile request to core.", + correlationUid, + firmwareIdentification); + final RequestMessage message = + new RequestMessage( + correlationUid, + organisationIdentification, + deviceIdentification, + updateFirmwareRequestDto); + this.osgpRequestMessageSender.sendWithReplyToThisInstance( + message, MessageType.GET_FIRMWARE_FILE.name(), messageMetadata); + return NO_RESPONSE; + } + @Override protected Serializable handleMessage( final DlmsConnectionManager conn, @@ -44,6 +92,8 @@ protected Serializable handleMessage( final Serializable requestObject, final MessageMetadata messageMetadata) throws OsgpException { + // This method will be invoked when usesDeviceConnection returns true (firmwareFile is + // available) final String deviceIdentification = messageMetadata.getDeviceIdentification(); final String organisationIdentification = messageMetadata.getOrganisationIdentification(); final String correlationUid = messageMetadata.getCorrelationUid(); @@ -61,28 +111,12 @@ protected Serializable handleMessage( (UpdateFirmwareRequestDto) requestObject; final String firmwareIdentification = updateFirmwareRequestDto.getFirmwareIdentification(); - if (this.firmwareService.isFirmwareFileAvailable(firmwareIdentification)) { - LOGGER.info( - "[{}] - Firmware file [{}] available. Updating firmware on device [{}]", - correlationUid, - firmwareIdentification, - deviceIdentification); - return this.configurationService.updateFirmware( - conn, device, updateFirmwareRequestDto, messageMetadata); - } else { - LOGGER.info( - "[{}] - Firmware file [{}] not available. Sending GetFirmwareFile request to core.", - correlationUid, - firmwareIdentification); - final RequestMessage message = - new RequestMessage( - correlationUid, - organisationIdentification, - deviceIdentification, - updateFirmwareRequestDto); - this.osgpRequestMessageSender.sendWithReplyToThisInstance( - message, MessageType.GET_FIRMWARE_FILE.name(), messageMetadata); - return NO_RESPONSE; - } + LOGGER.info( + "[{}] - Firmware file [{}] available. Updating firmware on device [{}]", + correlationUid, + firmwareIdentification, + deviceIdentification); + return this.configurationService.updateFirmware( + conn, device, updateFirmwareRequestDto, messageMetadata); } } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/UpdateProtocolRequestMessageProcessor.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/UpdateProtocolRequestMessageProcessor.java index 09a2228758c..bef43d29567 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/UpdateProtocolRequestMessageProcessor.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/UpdateProtocolRequestMessageProcessor.java @@ -25,7 +25,7 @@ public UpdateProtocolRequestMessageProcessor() { } @Override - protected boolean usesDeviceConnection() { + protected boolean usesDeviceConnection(final Serializable messageObject) { return false; } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/requests/to/core/OsgpRequestMessageSender.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/requests/to/core/OsgpRequestMessageSender.java index d1edbbc645f..4e5fac856d9 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/requests/to/core/OsgpRequestMessageSender.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/requests/to/core/OsgpRequestMessageSender.java @@ -64,7 +64,8 @@ private void send( objectMessage.setStringProperty(Constants.DOMAIN, messageMetadata.getDomain()); objectMessage.setStringProperty( Constants.DOMAIN_VERSION, messageMetadata.getDomainVersion()); - objectMessage.setStringProperty(Constants.IP_ADDRESS, messageMetadata.getIpAddress()); + objectMessage.setStringProperty( + Constants.NETWORK_ADDRESS, messageMetadata.getNetworkAddress()); objectMessage.setBooleanProperty(Constants.IS_SCHEDULED, messageMetadata.isScheduled()); objectMessage.setIntProperty(Constants.RETRY_COUNT, messageMetadata.getRetryCount()); objectMessage.setBooleanProperty( diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/AlarmDecoder.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/AlarmDecoder.java index 3cdeda586e5..92a78195a93 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/AlarmDecoder.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/AlarmDecoder.java @@ -9,8 +9,8 @@ import java.util.Arrays; import java.util.Set; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.alarm.AlarmHelperService; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectType; import org.opensmartgridplatform.dlms.DlmsPushNotification; +import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; import org.opensmartgridplatform.dto.valueobjects.smartmetering.AlarmTypeDto; public class AlarmDecoder { @@ -69,6 +69,15 @@ byte[] readBytes(final InputStream inputStream, final int length) } } + byte[] resetAndReadAllBytes(final InputStream inputStream) + throws UnrecognizedMessageDataException { + try { + return inputStream.readAllBytes(); + } catch (final IOException io) { + throw new UnrecognizedMessageDataException(io.getMessage(), io); + } + } + void skip(final InputStream inputStream, final int length) throws UnrecognizedMessageDataException { try { diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/ConnectionProtocol.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/ConnectionProtocol.java new file mode 100644 index 00000000000..25d9b7a3b42 --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/ConnectionProtocol.java @@ -0,0 +1,12 @@ +/* + * SPDX-FileCopyrightText: Copyright Contributors to the GXF project + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.opensmartgridplatform.adapter.protocol.dlms.infra.networking; + +public enum ConnectionProtocol { + TCP, + UDP +} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/DlmsChannelHandlerServer.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/DlmsChannelHandlerServer.java index dabf206a4f5..e581f87db73 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/DlmsChannelHandlerServer.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/DlmsChannelHandlerServer.java @@ -9,6 +9,7 @@ import java.net.InetSocketAddress; import java.util.UUID; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.opensmartgridplatform.dlms.DlmsPushNotification; import org.springframework.beans.factory.annotation.Autowired; @@ -24,6 +25,13 @@ public void channelRead0(final ChannelHandlerContext ctx, final DlmsPushNotifica final String deviceIdentification = message.getEquipmentIdentifier(); final String ipAddress = this.retrieveIpAddress(ctx, deviceIdentification); + if (StringUtils.isEmpty(deviceIdentification)) { + log.warn( + "Skip pushed message [{}] without a device identification from IP address {}", + message.toString(), + ipAddress); + return; + } this.pushedMessageProcessor.process(message, correlationId, deviceIdentification, ipAddress); } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/DlmsPushNotificationDecoder.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/DlmsPushNotificationDecoder.java index daec9433158..3b903d72e4c 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/DlmsPushNotificationDecoder.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/DlmsPushNotificationDecoder.java @@ -4,18 +4,13 @@ package org.opensmartgridplatform.adapter.protocol.dlms.infra.networking; -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.ReplayingDecoder; import java.io.ByteArrayInputStream; import java.io.InputStream; -import java.util.List; import org.opensmartgridplatform.dlms.DlmsPushNotification; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class DlmsPushNotificationDecoder - extends ReplayingDecoder { +public class DlmsPushNotificationDecoder { private static final Logger LOGGER = LoggerFactory.getLogger(DlmsPushNotificationDecoder.class); @@ -25,27 +20,8 @@ public class DlmsPushNotificationDecoder private static final byte DATA_NOTIFICATION = 0x0F; private static final byte EVENT_NOTIFICATION_REQUEST = (byte) 0xC2; - public enum DecodingState { - EQUIPMENT_IDENTIFIER - } - - public DlmsPushNotificationDecoder() { - LOGGER.debug("Created new DLMS Push Notification decoder"); - } - - /** - * Decoded the alarm bytes in the buffer. Could be either a MX382, DSMR4 or SMR5 alarm. If there - * are not enough bytes while decoding, the ReplayingDecoder rewinds and tries the decoding again - * when there are more bytes received. - * - * @param ctx the context from the ReplayingDecoder. Not used in decoding the alarm. - * @param byteBuf the bytes of the alarm. - * @param out decoded list of objects - * @throws UnrecognizedMessageDataException - */ - @Override - protected void decode( - final ChannelHandlerContext ctx, final ByteBuf byteBuf, final List out) + public DlmsPushNotification decode( + final byte[] message, final ConnectionProtocol connectionProtocol) throws UnrecognizedMessageDataException { /** * MX382 alarm examples (in HEX bytes): @@ -97,28 +73,25 @@ protected void decode( */ final DlmsPushNotification pushNotification; - final byte[] byteArray = new byte[byteBuf.readableBytes()]; - byteBuf.readBytes(byteArray); - // Determine whether the alarm is in MX382, DSMR4 or SMR5 format. - final boolean smr5alarm = byteArray[8] == DATA_NOTIFICATION; - final boolean mx382alarm = byteArray[8] == EVENT_NOTIFICATION_REQUEST; + final boolean smr5alarm = message[8] == DATA_NOTIFICATION; + final boolean mx382alarm = message[8] == EVENT_NOTIFICATION_REQUEST; - final InputStream inputStream = new ByteArrayInputStream(byteArray); - LOGGER.info("Decoding state: {}, SMR5 alarm: {}", this.state(), smr5alarm); + final InputStream inputStream = new ByteArrayInputStream(message); + LOGGER.info("Decoding alarm, SMR5 alarm: {}, MX382 alarm: {}", smr5alarm, mx382alarm); if (smr5alarm) { final Smr5AlarmDecoder alarmDecoder = new Smr5AlarmDecoder(); pushNotification = alarmDecoder.decodeSmr5alarm(inputStream); } else if (mx382alarm) { final Mx382AlarmDecoder alarmDecoder = new Mx382AlarmDecoder(); - pushNotification = alarmDecoder.decodeMx382alarm(inputStream); + pushNotification = alarmDecoder.decodeMx382alarm(inputStream, connectionProtocol); } else { final Dsmr4AlarmDecoder alarmDecoder = new Dsmr4AlarmDecoder(); pushNotification = alarmDecoder.decodeDsmr4alarm(inputStream); } LOGGER.info("Decoded push notification: {}", pushNotification); - out.add(pushNotification); + return pushNotification; } } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/DlmsPushNotificationReplayingDecoder.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/DlmsPushNotificationReplayingDecoder.java new file mode 100644 index 00000000000..8a8c2b19f80 --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/DlmsPushNotificationReplayingDecoder.java @@ -0,0 +1,62 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.adapter.protocol.dlms.infra.networking; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufInputStream; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.ReplayingDecoder; +import java.io.IOException; +import java.util.List; +import org.opensmartgridplatform.dlms.DlmsPushNotification; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DlmsPushNotificationReplayingDecoder + extends ReplayingDecoder { + + private static final Logger LOGGER = + LoggerFactory.getLogger(DlmsPushNotificationReplayingDecoder.class); + + private final DlmsPushNotificationDecoder decoder = new DlmsPushNotificationDecoder(); + + public enum DecodingState { + EQUIPMENT_IDENTIFIER + } + + public DlmsPushNotificationReplayingDecoder() { + LOGGER.debug("Created new DLMS Push Notification replaying decoder"); + } + + /** + * Decoded the alarm bytes in the buffer. Could be either a MX382, DSMR4 or SMR5 alarm. If there + * are not enough bytes while decoding, the ReplayingDecoder rewinds and tries the decoding again + * when there are more bytes received. + * + * @param ctx the context from the ReplayingDecoder. Not used in decoding the alarm. + * @param byteBuf the bytes of the alarm. + * @param out decoded list of objects + * @throws UnrecognizedMessageDataException + */ + @Override + protected void decode( + final ChannelHandlerContext ctx, final ByteBuf byteBuf, final List out) + throws UnrecognizedMessageDataException { + final byte[] byteArray = getBytes(byteBuf); + final DlmsPushNotification dlmsPushNotification = + this.decoder.decode(byteArray, ConnectionProtocol.TCP); + + LOGGER.info("Decoded push notification: {}", dlmsPushNotification); + out.add(dlmsPushNotification); + } + + private static byte[] getBytes(final ByteBuf byteBuf) throws UnrecognizedMessageDataException { + try (final ByteBufInputStream inputStream = new ByteBufInputStream(byteBuf)) { + return inputStream.readAllBytes(); + } catch (final IOException e) { + throw new UnrecognizedMessageDataException(e.getMessage(), e); + } + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/Dsmr4AlarmDecoder.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/Dsmr4AlarmDecoder.java index 35cafd357c9..3dff52ab540 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/Dsmr4AlarmDecoder.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/Dsmr4AlarmDecoder.java @@ -14,9 +14,9 @@ import java.nio.charset.StandardCharsets; import java.util.Arrays; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectConfigDsmr422; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectType; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; import org.opensmartgridplatform.dlms.DlmsPushNotification; +import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/Mx382AlarmDecoder.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/Mx382AlarmDecoder.java index 608cb9a0460..60e7819badd 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/Mx382AlarmDecoder.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/Mx382AlarmDecoder.java @@ -4,7 +4,9 @@ package org.opensmartgridplatform.adapter.protocol.dlms.infra.networking; +import java.io.IOException; import java.io.InputStream; +import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.HashSet; @@ -16,61 +18,120 @@ public class Mx382AlarmDecoder extends AlarmDecoder { private static final byte EVENT_NOTIFICATION_REQUEST = (byte) 0xC2; - private static final byte[] WPDU_HEADER = - new byte[] {0x00, 0x01, 0x00, 0x67, 0x00, 0x66, 0x00, 0x1b}; + private static final byte[] WPDU_HEADER = new byte[] {0x00, 0x01, 0x00, 0x67, 0x00, 0x66}; private static final byte[] AMM_FORWARDED_ALARM_VERSION_0 = new byte[] {(byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x00}; - private static final byte[] DEVICE_ID_2_CLASS_ID = new byte[] {0x00, 0x01}; - private static final byte VALUE_ATTRIBUTE_ID = 0x02; - private static final byte DSMR22_EQUIPMENT_IDENTIFIER_LENGTH = 0x10; + static final byte[] CLASS_ID_1 = new byte[] {0x00, 0x01}; + static final byte ATTRIBUTE_ID_2 = 0x02; + + public static final int DATA_TYPE_OCTET_STRING = 0x09; + + public static final String EXPECTED_MESSAGE_TEMPLATE = "Expected a %s (%s), within message: (%s)"; + private final DlmsPushNotification.Builder builder = new DlmsPushNotification.Builder(); - public DlmsPushNotification decodeMx382alarm(final InputStream inputStream) + public DlmsPushNotification decodeMx382alarm( + final InputStream inputStream, final ConnectionProtocol connectionProtocol) throws UnrecognizedMessageDataException { - this.checkBytes(inputStream, WPDU_HEADER, "WPDU-header"); + if (connectionProtocol == ConnectionProtocol.UDP) { + return this.decodeMx382alarmUdp(inputStream); + } + return this.decodeMx382alarmTcp(inputStream); + } + + private DlmsPushNotification decodeMx382alarmTcp(final InputStream inputStream) + throws UnrecognizedMessageDataException { + this.handleWpduHeaderBytes(inputStream, "WPDU-header"); this.checkByte(inputStream, EVENT_NOTIFICATION_REQUEST, "event-notification-request"); - // Datetime is not used, so can be skipped as well - this.skipDateTime(inputStream); + // Datetime is read and skipped + this.handleDateTime(inputStream); + this.handleCosemAttributeDescriptor(inputStream); // Get equipment identifier and add it to the new push notification - this.decodeEquipmentIdentifier(inputStream); + this.handleEquipmentIdentifier(inputStream); + // Add alarmbits to the new push notification + this.addTriggerType(PUSH_ALARM_TRIGGER); + this.addAlarm(AlarmTypeDto.LAST_GASP); + + return this.builder.build(); + } + private DlmsPushNotification decodeMx382alarmUdp(final InputStream inputStream) + throws UnrecognizedMessageDataException { + this.handleWpduHeaderBytes(inputStream, "WPDU-header"); + this.checkByte(inputStream, EVENT_NOTIFICATION_REQUEST, "event-notification-request"); + + // Datetime is read and skipped + this.handleDateTime(inputStream); + + // Get equipment identifier and add it to the new push notification + this.readEquipmentIdentifierAtEndOfMessage(inputStream); // Add alarmbits to the new push notification - this.addAlarm(); + this.addTriggerType(PUSH_SMS_TRIGGER); return this.builder.build(); } - private void skipDateTime(final InputStream inputStream) throws UnrecognizedMessageDataException { - // The first byte of the datetime is the length byte - final byte dateTimeLength = this.readByte(inputStream); - this.builder.appendByte(dateTimeLength); - // Skip the rest of the datetime bytes - final byte[] dateTimeBytes = this.readBytes(inputStream, dateTimeLength); - this.builder.appendBytes(dateTimeBytes); + private void handleDateTime(final InputStream inputStream) + throws UnrecognizedMessageDataException { + // The first byte tells if datetime is provided 0x00 is not provided and 0x09 is provided + final byte dataType = this.readByte(inputStream); + + // read the rest of the datetime bytes date is provided + if (dataType == DATA_TYPE_OCTET_STRING) { + // The next byte of the datetime is the length byte + final byte lengthOfData = this.readByte(inputStream); + this.readBytes(inputStream, lengthOfData); + } } - private void decodeEquipmentIdentifier(final InputStream inputStream) + private void handleEquipmentIdentifier(final InputStream inputStream) throws UnrecognizedMessageDataException { - // Check bytes of incoming mx382 message - this.checkBytes(inputStream, DEVICE_ID_2_CLASS_ID, "class-id"); - this.checkBytes(inputStream, AMM_FORWARDED_ALARM_VERSION_0, "logical name forwarded alarm"); - this.checkByte(inputStream, VALUE_ATTRIBUTE_ID, "attribute-id"); + final byte dataType = this.readByte(inputStream); + this.builder.appendByte(dataType); + final byte length = this.readByte(inputStream); + this.builder.appendByte(length); // Read the equipment identifier from incoming mx382 message - final byte[] equipmentIdentifierBytes = - this.readBytes(inputStream, DSMR22_EQUIPMENT_IDENTIFIER_LENGTH); + final byte[] equipmentIdentifierBytes = this.readBytes(inputStream, length); this.builder.withEquipmentIdentifier( new String(equipmentIdentifierBytes, StandardCharsets.US_ASCII)); } - private void addAlarm() { - this.builder.withTriggerType(PUSH_ALARM_TRIGGER); + private void readEquipmentIdentifierAtEndOfMessage(final InputStream inputStream) + throws UnrecognizedMessageDataException { + try { + this.readBytes(inputStream, inputStream.available() - 17); + // Read the equipment identifier from incoming mx382 message + final byte[] equipmentIdentifierBytes = this.readBytes(inputStream, 17); + final String equipmentIdentifier = + new String(equipmentIdentifierBytes, StandardCharsets.US_ASCII).trim(); + if (equipmentIdentifier.matches("[a-zA-Z0-9]+")) { + this.builder.withEquipmentIdentifier(equipmentIdentifier); + } + } catch (final IOException io) { + throw new UnrecognizedMessageDataException(io.getMessage(), io); + } + } + + private void handleCosemAttributeDescriptor(final InputStream inputStream) + throws UnrecognizedMessageDataException { + // Check bytes of incoming mx382 message + this.checkBytes(inputStream, CLASS_ID_1, "class-id"); + this.checkBytes(inputStream, AMM_FORWARDED_ALARM_VERSION_0, "logical name forwarded alarm"); + this.checkByte(inputStream, ATTRIBUTE_ID_2, "attribute-id"); + } + + private void addTriggerType(final String triggerType) { + this.builder.withTriggerType(triggerType); + } + + private void addAlarm(final AlarmTypeDto alarmType) { final Set alarmSet = new HashSet<>(); - alarmSet.add(AlarmTypeDto.LAST_GASP); + alarmSet.add(alarmType); this.builder.addAlarms(alarmSet); } @@ -81,8 +142,33 @@ private void checkByte(final InputStream inputStream, final byte expectedByte, f if (readByte != expectedByte) { throw new UnrecognizedMessageDataException( String.format( - "Expected a %s (%s), but encountered: (%s)", - name, toHexString(expectedByte), toHexString(readByte))); + EXPECTED_MESSAGE_TEMPLATE, + expectedByte, + name, + toHexString(this.resetAndReadAllBytes(inputStream)))); + } + } + + private void handleWpduHeaderBytes(final InputStream inputStream, final String name) + throws UnrecognizedMessageDataException { + final byte[] readBytes = this.readBytes(inputStream, WPDU_HEADER.length); + this.builder.appendBytes(readBytes); + if (!Arrays.equals(readBytes, WPDU_HEADER)) { + throw new UnrecognizedMessageDataException( + String.format( + EXPECTED_MESSAGE_TEMPLATE, + toHexString(WPDU_HEADER), + name, + toHexString(this.resetAndReadAllBytes(inputStream)))); + } + + final byte[] apduLengthBytes = this.readBytes(inputStream, 2); + this.builder.appendBytes(apduLengthBytes); + final int adpuLength = new BigInteger(apduLengthBytes).intValue(); + if (adpuLength != 29 && adpuLength != 30 && adpuLength != 42 && adpuLength != 43) { + throw new UnrecognizedMessageDataException( + String.format( + "Expected length value of 29,30,42 or 43, but found length of %d", adpuLength)); } } @@ -94,15 +180,13 @@ private void checkBytes( if (!Arrays.equals(readBytes, expectedBytes)) { throw new UnrecognizedMessageDataException( String.format( - "Expected a %s (%s), but encountered: (%s)", - name, toHexString(expectedBytes), toHexString(readBytes))); + EXPECTED_MESSAGE_TEMPLATE, + toHexString(expectedBytes), + name, + toHexString(this.resetAndReadAllBytes(inputStream)))); } } - private static String toHexString(final byte b) { - return toHexString(new byte[] {b}); - } - public static String toHexString(final byte[] ba) { final StringBuilder sb = new StringBuilder("["); boolean first = true; diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/PushedMessageProcessor.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/PushedMessageProcessor.java index b907ac77657..22bb9e5cd92 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/PushedMessageProcessor.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/PushedMessageProcessor.java @@ -8,6 +8,7 @@ import org.opensmartgridplatform.adapter.protocol.dlms.infra.messaging.DlmsLogItemRequestMessage; import org.opensmartgridplatform.adapter.protocol.dlms.infra.messaging.DlmsLogItemRequestMessageSender; import org.opensmartgridplatform.adapter.protocol.dlms.infra.messaging.requests.to.core.OsgpRequestMessageSender; +import org.opensmartgridplatform.adapter.protocol.jasper.service.DeviceSessionService; import org.opensmartgridplatform.dlms.DlmsPushNotification; import org.opensmartgridplatform.dto.valueobjects.smartmetering.PushNotificationAlarmDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.PushNotificationSmsDto; @@ -17,6 +18,7 @@ import org.opensmartgridplatform.shared.infra.jms.RequestMessage; import org.opensmartgridplatform.shared.wsheaderattribute.priority.MessagePriorityEnum; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Slf4j @@ -28,6 +30,10 @@ public class PushedMessageProcessor { @Autowired private OsgpRequestMessageSender osgpRequestMessageSender; @Autowired private DlmsLogItemRequestMessageSender dlmsLogItemRequestMessageSender; + @Autowired private DeviceSessionService deviceSessionService; + + @Value("${push.wakeup.alarm.to.core}") + private boolean pushWakeupAlarmToCore; public void process( final DlmsPushNotification message, @@ -94,9 +100,14 @@ private void processPushedSms( null, pushNotificationSms); - log.info("Sending push notification sms wakeup to GXF with correlation ID: {}", correlationId); - this.osgpRequestMessageSender.send( - requestMessage, MessageType.PUSH_NOTIFICATION_SMS.name(), null); + if (this.pushWakeupAlarmToCore) { + log.info( + "Sending push notification sms wakeup to GXF with correlation ID: {}", correlationId); + this.osgpRequestMessageSender.send( + requestMessage, MessageType.PUSH_NOTIFICATION_SMS.name(), null); + } + + this.deviceSessionService.notifyIpAddress(deviceIdentification, ipAddress); } protected void logMessage(final DlmsPushNotification message) { diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/Smr5AlarmDecoder.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/Smr5AlarmDecoder.java index 8f8ff8b0d6d..a810fa461dd 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/Smr5AlarmDecoder.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/Smr5AlarmDecoder.java @@ -8,6 +8,7 @@ import static org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectType.INTERNAL_TRIGGER_ALARM; import static org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectType.PUSH_SCHEDULER; import static org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectType.PUSH_SETUP_ALARM; +import static org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectType.PUSH_SETUP_CSD_SMS; import static org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectType.PUSH_SETUP_SCHEDULER; import static org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectType.PUSH_SETUP_UDP; @@ -16,9 +17,9 @@ import java.util.Arrays; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectConfigSmr50; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectConfigSmr55; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectType; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; import org.opensmartgridplatform.dlms.DlmsPushNotification; +import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -212,7 +213,10 @@ private boolean isLogicalNameSmsTrigger(final byte[] logicalNameBytes) throws ProtocolAdapterException { // SMR5 has one general object for the SMS and CSD triggers return Arrays.equals( - this.dlmsObjectConfigSmr50.getObisForObject(EXTERNAL_TRIGGER).bytes(), logicalNameBytes); + this.dlmsObjectConfigSmr50.getObisForObject(EXTERNAL_TRIGGER).bytes(), logicalNameBytes) + || Arrays.equals( + this.dlmsObjectConfigSmr50.getObisForObject(PUSH_SETUP_CSD_SMS).bytes(), + logicalNameBytes); } private boolean isLogicalNameCsdTrigger(final byte[] logicalNameBytes) diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/UdpInboundMessageHandler.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/UdpInboundMessageHandler.java index 68426990827..8dd5a799238 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/UdpInboundMessageHandler.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/UdpInboundMessageHandler.java @@ -4,10 +4,10 @@ package org.opensmartgridplatform.adapter.protocol.dlms.infra.networking; -import java.io.ByteArrayInputStream; import java.util.Map; import java.util.UUID; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.codec.binary.Hex; import org.opensmartgridplatform.dlms.DlmsPushNotification; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.integration.annotation.MessageEndpoint; @@ -23,15 +23,19 @@ public class UdpInboundMessageHandler { @Autowired private PushedMessageProcessor pushedMessageProcessor; + private final DlmsPushNotificationDecoder decoder = new DlmsPushNotificationDecoder(); + @ServiceActivator(inputChannel = "inboundChannel") public void handeMessage(final Message message, @Headers final Map headerMap) throws UnrecognizedMessageDataException { final byte[] payload = (byte[]) message.getPayload(); - log.info("Received UDP message: {}", new String(payload)); + log.info( + "Received UDP message: {}, hex-representation: {}", + new String(payload), + Hex.encodeHexString(payload)); - final ByteArrayInputStream inputStream = new ByteArrayInputStream(payload); - final Smr5AlarmDecoder alarmDecoder = new Smr5AlarmDecoder(); - final DlmsPushNotification dlmsPushNotification = alarmDecoder.decodeSmr5alarm(inputStream); + final DlmsPushNotification dlmsPushNotification = + this.decoder.decode(payload, ConnectionProtocol.UDP); final String correlationId = UUID.randomUUID().toString().replace("-", ""); final String deviceIdentification = dlmsPushNotification.getEquipmentIdentifier(); diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/simulator/trigger/SessionProviderSimulator.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/simulator/trigger/SessionProviderSimulator.java index a5ecfa395f4..f36d92ac256 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/simulator/trigger/SessionProviderSimulator.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/java/org/opensmartgridplatform/adapter/protocol/dlms/simulator/trigger/SessionProviderSimulator.java @@ -4,14 +4,15 @@ package org.opensmartgridplatform.adapter.protocol.dlms.simulator.trigger; +import java.util.Optional; import javax.annotation.PostConstruct; import org.opensmartgridplatform.adapter.protocol.dlms.application.services.DomainHelperService; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDevice; import org.opensmartgridplatform.adapter.protocol.jasper.sessionproviders.SessionProvider; import org.opensmartgridplatform.adapter.protocol.jasper.sessionproviders.SessionProviderEnum; +import org.opensmartgridplatform.adapter.protocol.jasper.sessionproviders.SessionProviderMap; import org.opensmartgridplatform.adapter.protocol.jasper.sessionproviders.exceptions.SessionProviderException; import org.opensmartgridplatform.shared.exceptionhandling.FunctionalException; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; @@ -33,12 +34,22 @@ @PropertySource(value = "file:${osgp/AdapterProtocolDlms/config}", ignoreResourceNotFound = true) public class SessionProviderSimulator extends SessionProvider { - @Value("${triggered.simulator.ipaddress}") - private String ipAddress; + private final String ipAddress; - @Autowired private DomainHelperService domainHelperService; + private final DomainHelperService domainHelperService; - @Autowired private SimulatorTriggerClient simulatorTriggerClient; + private final SimulatorTriggerClient simulatorTriggerClient; + + public SessionProviderSimulator( + final SessionProviderMap sessionProviderMap, + final DomainHelperService dlmsDomainHelperService, + final SimulatorTriggerClient simulatorTriggerClient, + @Value("${triggered.simulator.ipaddress}") final String ipAddress) { + super(sessionProviderMap); + this.domainHelperService = dlmsDomainHelperService; + this.simulatorTriggerClient = simulatorTriggerClient; + this.ipAddress = ipAddress; + } /** * Initialization function executed after dependency injection has finished. The SessionProvider @@ -50,19 +61,16 @@ public void init() { } /** - * This implementation depends on the iccId having the same value as the device identification (in - * order to be able to look up some data with the device for calling the simulator starting web - * service, like the port number and logicalId of a simulated device). - * * @throws SessionProviderException when no dlmsDevice can be found with a deviceId equal to the * given iccId, or the simulator was not successfully started. */ @Override - public String getIpAddress(final String iccId) throws SessionProviderException { + public Optional getIpAddress(final String deviceIdentification, final String iccId) + throws SessionProviderException { - DlmsDevice dlmsDevice; + final DlmsDevice dlmsDevice; try { - dlmsDevice = this.domainHelperService.findDlmsDevice(iccId); + dlmsDevice = this.domainHelperService.findDlmsDevice(deviceIdentification); this.simulatorTriggerClient.sendTrigger(dlmsDevice); } catch (final FunctionalException e) { throw new SessionProviderException("Unable to find dlmsDevice. ", e); @@ -70,6 +78,6 @@ public String getIpAddress(final String iccId) throws SessionProviderException { throw new SessionProviderException("Unable to successfully start a simulator. ", e); } - return this.ipAddress; + return Optional.of(this.ipAddress); } } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/db/migration/V20230811114500000__add_fw_hash_to_dlms_device_table.sql b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/db/migration/V20230811114500000__add_fw_hash_to_dlms_device_table.sql new file mode 100644 index 00000000000..ad4909e3127 --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/db/migration/V20230811114500000__add_fw_hash_to_dlms_device_table.sql @@ -0,0 +1,6 @@ +DO +$$ +BEGIN + ALTER TABLE dlms_device ADD COLUMN firmware_hash VARCHAR(64) null; +END; +$$ \ No newline at end of file diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/db/migration/V20230811114500000__add_fw_hash_to_dlms_device_table.sql.license b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/db/migration/V20230811114500000__add_fw_hash_to_dlms_device_table.sql.license new file mode 100644 index 00000000000..1a239a486fb --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/db/migration/V20230811114500000__add_fw_hash_to_dlms_device_table.sql.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: 2023 Contributors to the GXF project + +SPDX-License-Identifier: Apache-2.0 diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/db/migration/V20230913121109000__added_device_selective_access_meter_reads_support_flag.sql b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/db/migration/V20230913121109000__added_device_selective_access_meter_reads_support_flag.sql new file mode 100644 index 00000000000..538fee481fc --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/db/migration/V20230913121109000__added_device_selective_access_meter_reads_support_flag.sql @@ -0,0 +1 @@ +ALTER TABLE dlms_device ADD COLUMN selective_access_periodic_meter_reads_supported boolean DEFAULT true; diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-dsmr422.json.license b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-dsmr422.json.license deleted file mode 100644 index cf92a544c48..00000000000 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-dsmr422.json.license +++ /dev/null @@ -1,2 +0,0 @@ -SPDX-FileCopyrightText: Contributors to the GXF project -SPDX-License-Identifier: Apache-2.0 diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr43.json b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr43.json deleted file mode 100644 index 835cc724c20..00000000000 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr43.json +++ /dev/null @@ -1,83 +0,0 @@ -{ - "profile": "SMR", - "version": "4.3", - "description": "Profile for Smart Meter Requirements 4.3", - "inherit": { - "profile": "DSMR", - "version": "4.2.2" - }, - "properties": [], - "objects": [ - { - "tag": "CDMA_DIAGNOSTIC", - "description": "CDMA Diagnostic", - "class-id": 47, - "version": 0, - "obis": "0.1.25.6.0.255", - "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "PERIODIC" - }, - "attributes": [ - { - "id": 2, - "description": "operator", - "datatype": "visible-string", - "valuetype": "DYNAMIC", - "value": "EMPTY", - "access": "R" - }, - { - "id": 3, - "description": "status", - "datatype": "enum", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 4, - "description": "cs attachment", - "datatype": "enum", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 5, - "description": "ps status", - "datatype": "enum", - "valuetype": "DYNAMIC", - "value": "255", - "access": "R" - }, - { - "id": 6, - "description": "cell info", - "datatype": "cell_info_type", - "valuetype": "DYNAMIC", - "value": "EMPTY", - "access": "R" - }, - { - "id": 7, - "description": "adjacent cells", - "datatype": "array", - "valuetype": "DYNAMIC", - "value": "EMPTY", - "access": "R" - }, - { - "id": 8, - "description": "capture time", - "datatype": "date-time", - "valuetype": "DYNAMIC", - "value": "EMPTY", - "access": "R" - } - ] - } - ] -} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr43.json.license b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr43.json.license deleted file mode 100644 index cf92a544c48..00000000000 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr43.json.license +++ /dev/null @@ -1,2 +0,0 @@ -SPDX-FileCopyrightText: Contributors to the GXF project -SPDX-License-Identifier: Apache-2.0 diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr50.json.license b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr50.json.license deleted file mode 100644 index cf92a544c48..00000000000 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr50.json.license +++ /dev/null @@ -1,2 +0,0 @@ -SPDX-FileCopyrightText: Contributors to the GXF project -SPDX-License-Identifier: Apache-2.0 diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr51.json b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr51.json deleted file mode 100644 index 6a48426391d..00000000000 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr51.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "profile": "SMR", - "version": "5.1", - "description": "Profile for Smart Meter Requirements 5.1", - "inherit": { - "profile": "SMR", - "version": "5.0.0" - }, - "properties": [], - "objects": [] -} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr51.json.license b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr51.json.license deleted file mode 100644 index cf92a544c48..00000000000 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr51.json.license +++ /dev/null @@ -1,2 +0,0 @@ -SPDX-FileCopyrightText: Contributors to the GXF project -SPDX-License-Identifier: Apache-2.0 diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr52.json b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr52.json deleted file mode 100644 index 06b802753b4..00000000000 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr52.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "profile": "SMR", - "version": "5.2", - "description": "Profile for Smart Meter Requirements 5.2", - "inherit": { - "profile": "SMR", - "version": "5.1" - }, - "properties": [], - "objects": [ - { - "tag": "LTE_DIAGNOSTIC", - "description": "LTE Diagnostic", - "class-id": 47, - "version": 0, - "obis": "0.2.25.6.0.255", - "group": "ELECTRICITY", - "meterTypes": ["SP","PP"], - "properties": { - "PQ_PROFILE": "PUBLIC", - "PQ_REQUEST": "PERIODIC" - }, - "attributes": [ - { - "id": 2, - "description": "operator", - "datatype": "visible-string", - "valuetype": "DYNAMIC", - "value": "EMPTY", - "access": "R" - }, - { - "id": 3, - "description": "status", - "datatype": "enum", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 4, - "description": "cs attachment", - "datatype": "enum", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 5, - "description": "ps status", - "datatype": "enum", - "valuetype": "DYNAMIC", - "value": "0", - "access": "R" - }, - { - "id": 6, - "description": "cell info", - "datatype": "cell_info_type", - "valuetype": "DYNAMIC", - "value": "EMPTY", - "access": "R" - }, - { - "id": 7, - "description": "adjacent cells", - "datatype": "array", - "valuetype": "DYNAMIC", - "value": "EMPTY", - "access": "R" - }, - { - "id": 8, - "description": "capture time", - "datatype": "date-time", - "valuetype": "DYNAMIC", - "value": "EMPTY", - "access": "R" - } - ] - }] -} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr52.json.license b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr52.json.license deleted file mode 100644 index cf92a544c48..00000000000 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr52.json.license +++ /dev/null @@ -1,2 +0,0 @@ -SPDX-FileCopyrightText: Contributors to the GXF project -SPDX-License-Identifier: Apache-2.0 diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr55.json b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr55.json deleted file mode 100644 index 3a1abbbf05e..00000000000 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr55.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "profile": "SMR", - "version": "5.5", - "description": "Profile for Smart Meter Requirements 5.5", - "inherit": { - "profile": "SMR", - "version": "5.2" - }, - "properties": [], - "objects": [{ - "tag": "PUSH_SETUP_UDP", - "description": "Push Setup UDP", - "class-id": 40, - "version": 0, - "obis": "0.3.25.9.0.255", - "group": "ABSTRACT", - "meterTypes": ["SP","PP"], - "attributes": [ - { - "id": 2, - "description": "push_object_list", - "datatype": "array", - "valuetype": "DYNAMIC", - "value": "EMPTY", - "access": "RW" - }, - { - "id": 3, - "description": "send_destination_and_method", - "datatype": "structure", - "valuetype": "DYNAMIC", - "value": "EMPTY", - "access": "RW" - }, - { - "id": 4, - "description": "communication_window", - "datatype": "array", - "valuetype": "DYNAMIC", - "value": "EMPTY", - "access": "RW" - }, - { - "id": 5, - "description": "randomisation_start_interval", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "5", - "access": "RW" - }, - { - "id": 6, - "description": "number of retries", - "datatype": "unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "RW" - }, - { - "id": 7, - "description": "repetition_delay", - "datatype": "long-unsigned", - "valuetype": "DYNAMIC", - "value": "0", - "access": "RW" - } - ] - }] -} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr55.json.license b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr55.json.license deleted file mode 100644 index cf92a544c48..00000000000 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/dlmsprofiles/dlmsprofile-smr55.json.license +++ /dev/null @@ -1,2 +0,0 @@ -SPDX-FileCopyrightText: Contributors to the GXF project -SPDX-License-Identifier: Apache-2.0 diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/osgp-adapter-protocol-dlms.properties b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/osgp-adapter-protocol-dlms.properties index 1451010b1f1..80241fdffe4 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/osgp-adapter-protocol-dlms.properties +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/main/resources/osgp-adapter-protocol-dlms.properties @@ -177,6 +177,8 @@ command.updatefirmware.initiationstatuscheck.timeout=60000 #========================================================== # Throttling #========================================================== +# Throttling type can be local, shared or disabled +throttling.type=local # Set throttling.client.enabled to true to use the throttling client for max concurrency on the CDMA # network. Set the value to false to use the earlier created throttling service on the GPRS network. throttling.client.enabled=false @@ -187,11 +189,23 @@ throttling.configuration.name=CDMA throttling.configuration.max.concurrency=1000 throttling.service.url=http://localhost:9090 throttling.service.timeout=PT30S -throttling.rejected.delay=PT10S +throttling.rejected.min.delay=PT50S +throttling.rejected.max.delay=PT70S +throttling.rejected.high.prio.delay=PT2S # Configuration for the throttling service on the GPRS network throttling.max.open.connections=1000 +throttling.max.wait.for.permit=60000 +throttling.max.new.connection.reset.time=1000 throttling.max.new.connection.requests=30 -throttling.reset.time=1000 + +# Any permits that have not been released or discarded will be deleted after a certain period of +# time, in order to prevent permits being kept in case a throttling client crashed. +cleanup.permits.time-to-live=PT1H +# The task to clean up permits that exceeded their time-to-live is executed by fixed rate. +# cleanup.permits.interval is in ms +cleanup.permits.interval=1800000 udp.channel=inboundChannel udp.port=9598 + +push.wakeup.alarm.to.core=false \ No newline at end of file diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/application/config/ThrottlingConfigTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/application/config/ThrottlingConfigTest.java new file mode 100644 index 00000000000..05dc2a94396 --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/application/config/ThrottlingConfigTest.java @@ -0,0 +1,44 @@ +/* + * SPDX-FileCopyrightText: Copyright Contributors to the GXF project + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.opensmartgridplatform.adapter.protocol.dlms.application.config; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +import java.time.Duration; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.opensmartgridplatform.shared.wsheaderattribute.priority.MessagePriorityEnum; +import org.springframework.test.util.ReflectionTestUtils; + +class ThrottlingConfigTest { + private final Duration permitRejectedMinDelay = Duration.parse("PT50S"); + private final Duration permitRejectedMaxDelay = Duration.parse("PT70S"); + private final Duration permitRejectedHighPrioDelay = Duration.parse("PT2S"); + + @ParameterizedTest + @EnumSource(MessagePriorityEnum.class) + void testHttpComponentsMessageSender(final MessagePriorityEnum messagePriority) { + final ThrottlingConfig throttlingConfig = new ThrottlingConfig(); + + ReflectionTestUtils.setField( + throttlingConfig, "permitRejectedMinDelay", this.permitRejectedMinDelay, Duration.class); + ReflectionTestUtils.setField( + throttlingConfig, "permitRejectedMaxDelay", this.permitRejectedMaxDelay, Duration.class); + ReflectionTestUtils.setField( + throttlingConfig, + "permitRejectedHighPrioDelay", + this.permitRejectedHighPrioDelay, + Duration.class); + + final Duration result = throttlingConfig.permitRejectedDelay(messagePriority.getPriority()); + if (messagePriority.getPriority() > MessagePriorityEnum.DEFAULT.getPriority()) { + assertThat(result).isEqualTo(this.permitRejectedHighPrioDelay); + } else { + assertThat(result).isBetween(this.permitRejectedMinDelay, this.permitRejectedMaxDelay); + } + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/application/mapping/DeviceConverterTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/application/mapping/DeviceConverterTest.java index f683d47fbc1..f9571a5450f 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/application/mapping/DeviceConverterTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/application/mapping/DeviceConverterTest.java @@ -43,6 +43,7 @@ private DlmsDevice converted(final SmartMeteringDeviceDto dto) { dlmsDevice.setCommunicationMethod(dto.getCommunicationMethod()); dlmsDevice.setCommunicationProvider(dto.getCommunicationProvider()); dlmsDevice.setIccId(dto.getIccId()); + dlmsDevice.setLls1Active(dto.isLls1Active()); dlmsDevice.setHls3Active(dto.isHls3Active()); dlmsDevice.setHls4Active(dto.isHls4Active()); dlmsDevice.setHls5Active(dto.isHls5Active()); diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/application/services/DomainHelperServiceTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/application/services/DomainHelperServiceTest.java index 474b6bdcea1..f6bde0b6d90 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/application/services/DomainHelperServiceTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/application/services/DomainHelperServiceTest.java @@ -8,9 +8,9 @@ import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import java.util.Optional; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -34,8 +34,6 @@ class DomainHelperServiceTest { @Mock private SessionProviderService sessionProviderService; @Mock private SessionProvider sessionProvider; @Mock private JasperWirelessSmsRestClient jasperWirelessSmsRestClient; - private final int jasperGetSessionRetries = 1; - private final int jasperGetSessionSleepBetweenRetries = 2; private DomainHelperService domainHelperService; @@ -45,12 +43,7 @@ class DomainHelperServiceTest { @BeforeEach void setUp() { this.domainHelperService = - new DomainHelperService( - this.dlmsDeviceRepository, - this.sessionProviderService, - this.jasperWirelessSmsRestClient, - this.jasperGetSessionRetries, - this.jasperGetSessionSleepBetweenRetries); + new DomainHelperService(this.dlmsDeviceRepository, this.sessionProviderService); } @Test @@ -81,6 +74,7 @@ void getDeviceIpAddressFromSessionProviderReturnsAddressFromProviderIfDeviceIsIn this.whenSessionProviderReturnsIpAddress(communicationProvider, iccId, ipAddress); final DlmsDevice dlmsDevice = new DlmsDeviceBuilder() + .withDeviceIdentification(DEVICE_IDENTIFICATION) .withCommunicationProvider(communicationProvider) .setIccId(iccId) .build(); @@ -97,37 +91,8 @@ private void whenSessionProviderReturnsIpAddress( when(this.sessionProviderService.getSessionProvider(communicationProvider)) .thenReturn(this.sessionProvider); - when(this.sessionProvider.getIpAddress(iccId)).thenReturn(IP_ADDRESS); - } - - @Test - void getDeviceIpAddressFromSessionProviderReturnsIpAddressOnlyAfterWakeUp() throws Exception { - - final String communicationProvider = "comm-prov"; - final String iccId = "icc-id"; - final String ipAddress = IP_ADDRESS; - this.whenSessionProviderReturnsIpAddressAfterWakeUp(communicationProvider, iccId, ipAddress); - final DlmsDevice dlmsDevice = - new DlmsDeviceBuilder() - .withCommunicationProvider(communicationProvider) - .setIccId(iccId) - .build(); - - final String actualIpAddress = - this.domainHelperService.getDeviceIpAddressFromSessionProvider(dlmsDevice); - - assertThat(actualIpAddress).isEqualTo(ipAddress); - - verify(this.jasperWirelessSmsRestClient).sendWakeUpSMS(iccId); - } - - private void whenSessionProviderReturnsIpAddressAfterWakeUp( - final String communicationProvider, final String iccId, final String ipAddress) - throws Exception { - - when(this.sessionProviderService.getSessionProvider(communicationProvider)) - .thenReturn(this.sessionProvider); - when(this.sessionProvider.getIpAddress(iccId)).thenReturn(null).thenReturn(IP_ADDRESS); + when(this.sessionProvider.getIpAddress(DEVICE_IDENTIFICATION, iccId)) + .thenReturn(Optional.of(IP_ADDRESS)); } @Test @@ -136,7 +101,7 @@ void setsIpAddressFromMessageMetadataIfIpAddressIsStatic() throws Exception { final DlmsDevice dlmsDevice = new DlmsDeviceBuilder().withIpAddress(null).withIpAddressStatic(true).build(); final MessageMetadata messageMetadata = - MessageMetadata.newBuilder().withIpAddress(ipAddress).build(); + MessageMetadata.newBuilder().withNetworkAddress(ipAddress).build(); this.domainHelperService.setIpAddressFromMessageMetadataOrSessionProvider( dlmsDevice, messageMetadata); @@ -149,15 +114,21 @@ void setsIpAddressFromSessionProviderIfIpAddressIsNotStatic() throws Exception { final String communicationProvider = "comm-prov"; final String iccId = "icc-id"; final String ipAddress = IP_ADDRESS; - this.whenSessionProviderReturnsIpAddressAfterWakeUp(communicationProvider, iccId, ipAddress); + + when(this.sessionProviderService.getSessionProvider(communicationProvider)) + .thenReturn(this.sessionProvider); + when(this.sessionProvider.getIpAddress(DEVICE_IDENTIFICATION, iccId)) + .thenReturn(Optional.of(ipAddress)); + final DlmsDevice dlmsDevice = new DlmsDeviceBuilder() + .withDeviceIdentification(DEVICE_IDENTIFICATION) .withIpAddressStatic(false) .withCommunicationProvider(communicationProvider) .setIccId(iccId) .build(); final MessageMetadata messageMetadata = - MessageMetadata.newBuilder().withIpAddress(null).build(); + MessageMetadata.newBuilder().withNetworkAddress(null).build(); this.domainHelperService.setIpAddressFromMessageMetadataOrSessionProvider( dlmsDevice, messageMetadata); @@ -171,7 +142,7 @@ void doesNotSetIpAddressWhenItIsAlreadySetInDlmsDevice() throws Exception { final DlmsDevice dlmsDevice = new DlmsDeviceBuilder().withIpAddress(IP_ADDRESS).withIpAddressStatic(true).build(); final MessageMetadata messageMetadata = - MessageMetadata.newBuilder().withIpAddress(ipAddressInMessageMetaData).build(); + MessageMetadata.newBuilder().withNetworkAddress(ipAddressInMessageMetaData).build(); this.domainHelperService.setIpAddressFromMessageMetadataOrSessionProvider( dlmsDevice, messageMetadata); diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/application/services/SystemEventServiceTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/application/services/SystemEventServiceTest.java index 6fb14675d25..6450fed6b02 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/application/services/SystemEventServiceTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/application/services/SystemEventServiceTest.java @@ -94,7 +94,7 @@ void verifyMaxValueReachedEvent() { final MessageMetadata messageMetadata = new Builder() - .withIpAddress("127.0-.0.1") + .withNetworkAddress("127.0-.0.1") .withOrganisationIdentification("org-id") .withDomain("domain") .withDomainVersion("1.0") @@ -123,7 +123,7 @@ void verifyMaxValueReachedEvent() { assertThat(requestMessage.getCorrelationUid()).isEqualTo("corr-id"); assertThat(requestMessage.getOrganisationIdentification()) .isEqualTo(messageMetadata.getOrganisationIdentification()); - assertThat(requestMessage.getIpAddress()).isEqualTo(messageMetadata.getIpAddress()); + assertThat(requestMessage.getIpAddress()).isEqualTo(messageMetadata.getNetworkAddress()); assertThat(requestMessage.getRequest()).isInstanceOf(SystemEventDto.class); final SystemEventDto systemEventDto = (SystemEventDto) requestMessage.getRequest(); @@ -138,7 +138,7 @@ void verifyMaxValueReachedEvent() { assertThat(metadata.getCorrelationUid()).isEqualTo("corr-id"); assertThat(metadata.getOrganisationIdentification()) .isEqualTo(messageMetadata.getOrganisationIdentification()); - assertThat(metadata.getIpAddress()).isEqualTo(messageMetadata.getIpAddress()); + assertThat(metadata.getNetworkAddress()).isEqualTo(messageMetadata.getNetworkAddress()); assertThat(metadata.getMessagePriority()).isEqualTo(MessagePriorityEnum.HIGH.getPriority()); assertThat(metadata.getMessageType()).isEqualTo(MessageType.SYSTEM_EVENT.name()); assertThat(metadata.getDomain()).isEqualTo(messageMetadata.getDomain()); diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/application/services/ThrottlingServiceTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/application/services/ThrottlingServiceTest.java deleted file mode 100644 index b3c6586a005..00000000000 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/application/services/ThrottlingServiceTest.java +++ /dev/null @@ -1,83 +0,0 @@ -// SPDX-FileCopyrightText: Copyright Contributors to the GXF project -// -// SPDX-License-Identifier: Apache-2.0 - -package org.opensmartgridplatform.adapter.protocol.dlms.application.services; - -import static org.assertj.core.api.Assertions.assertThat; - -import java.util.concurrent.atomic.AtomicBoolean; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -@ExtendWith(SpringExtension.class) -@ContextConfiguration(classes = ThrottlingService.class) -@TestPropertySource( - properties = { - "throttling.max.open.connections=10", - "throttling.max.new.connection.requests=30", - "throttling.reset.time=2000" - }) -public class ThrottlingServiceTest { - - private static final Logger LOGGER = LoggerFactory.getLogger(ThrottlingServiceTest.class); - - @Autowired ThrottlingService throttlingService; - - AtomicBoolean openingThreadDone; - AtomicBoolean closingThreadDone; - - @Test - public void testThrottling() throws InterruptedException { - - this.openingThreadDone = new AtomicBoolean(false); - this.closingThreadDone = new AtomicBoolean(false); - - this.openingThread().start(); - this.closingThread().start(); - - assertThat(true).isEqualTo(true); - - while (!this.openingThreadDone.get() && !this.closingThreadDone.get()) { - Thread.sleep(1000); - } - } - - private Thread openingThread() { - return new Thread( - () -> { - for (int i = 0; i < 100; i++) { - - LOGGER.info("Incoming request {}", i); - this.throttlingService.openConnection(); - } - - LOGGER.info("Opening Connection Thread done"); - this.openingThreadDone.set(true); - }); - } - - private Thread closingThread() { - return new Thread( - () -> { - for (int i = 0; i < 100; i++) { - LOGGER.info("Closing Connection {}", i); - this.throttlingService.closeConnection(); - try { - Thread.sleep(200); - } catch (final InterruptedException e) { - this.closingThreadDone.set(true); - } - } - - LOGGER.info("CLosing Connection Thread done"); - this.closingThreadDone.set(true); - }); - } -} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/application/threads/RecoverKeyProcessTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/application/threads/RecoverKeyProcessTest.java index 68eceea0547..b609a39baf9 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/application/threads/RecoverKeyProcessTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/application/threads/RecoverKeyProcessTest.java @@ -8,7 +8,6 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; @@ -31,7 +30,7 @@ import org.opensmartgridplatform.adapter.protocol.dlms.application.services.DeviceKeyProcessingService; import org.opensmartgridplatform.adapter.protocol.dlms.application.services.DomainHelperService; import org.opensmartgridplatform.adapter.protocol.dlms.application.services.SecretManagementService; -import org.opensmartgridplatform.adapter.protocol.dlms.application.services.ThrottlingService; +import org.opensmartgridplatform.adapter.protocol.dlms.application.throttling.LocalThrottlingServiceImpl; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDevice; import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.Hls5Connector; import org.opensmartgridplatform.adapter.protocol.dlms.domain.repositories.DlmsDeviceRepository; @@ -41,6 +40,7 @@ import org.opensmartgridplatform.shared.exceptionhandling.FunctionalExceptionType; import org.opensmartgridplatform.shared.exceptionhandling.OsgpException; import org.opensmartgridplatform.shared.infra.jms.MessageMetadata; +import org.opensmartgridplatform.throttling.api.Permit; @ExtendWith(MockitoExtension.class) class RecoverKeyProcessTest { @@ -52,7 +52,7 @@ class RecoverKeyProcessTest { @Mock DomainHelperService domainHelperService; @Mock Hls5Connector hls5Connector; @Mock SecretManagementService secretManagementService; - @Mock ThrottlingService throttlingService; + @Mock LocalThrottlingServiceImpl throttlingService; @Mock DlmsDeviceRepository dlmsDeviceRepository; @Mock ThrottlingClientConfig throttlingClientConfig; @Mock DeviceKeyProcessingService deviceKeyProcessingService; @@ -64,7 +64,6 @@ class RecoverKeyProcessTest { public void before() { this.recoverKeyProcess.setDeviceIdentification(DEVICE_IDENTIFICATION); this.recoverKeyProcess.setMessageMetadata(this.messageMetadata); - lenient().when(this.throttlingClientConfig.clientEnabled()).thenReturn(false); } @Test @@ -82,6 +81,9 @@ void testWhenDeviceNotFoundThenException() throws OsgpException { @Test void testWhenHasNoNewKeysToConnectWith() throws OsgpException, IOException { + final int btsId = 1; + final int cellId = 2; + final int priority = 3; when(this.domainHelperService.findDlmsDevice(DEVICE_IDENTIFICATION)) .thenReturn(this.dlmsDevice); @@ -95,7 +97,7 @@ void testWhenHasNoNewKeysToConnectWith() throws OsgpException, IOException { verify(this.secretManagementService, times(1)) .hasNewSecret(this.messageMetadata, DEVICE_IDENTIFICATION); verify(this.domainHelperService).findDlmsDevice(DEVICE_IDENTIFICATION); - verify(this.throttlingService, never()).openConnection(); + verify(this.throttlingService, never()).requestPermit(btsId, cellId, priority); } @Test @@ -121,6 +123,10 @@ void testWhenNotAbleToConnectWithNewKeys() throws OsgpException, IOException { @Test void testThrottlingServiceCalledAndKeysActivated() throws Exception { + final int btsId = 1; + final int cellId = 2; + final int priority = 3; + final Permit permit = mock(Permit.class); when(this.domainHelperService.findDlmsDevice(DEVICE_IDENTIFICATION)) .thenReturn(this.dlmsDevice); @@ -133,15 +139,20 @@ void testThrottlingServiceCalledAndKeysActivated() throws Exception { eq(this.messageMetadata), eq(DEVICE_IDENTIFICATION))) .thenReturn(true); + when(this.messageMetadata.getBaseTransceiverStationId()).thenReturn(btsId); + when(this.messageMetadata.getCellId()).thenReturn(cellId); + when(this.messageMetadata.getMessagePriority()).thenReturn(priority); + when(this.throttlingService.requestPermit(btsId, cellId, priority)).thenReturn(permit); + this.recoverKeyProcess.run(); final InOrder inOrder = inOrder(this.throttlingService, this.hls5Connector); - inOrder.verify(this.throttlingService).openConnection(); + inOrder.verify(this.throttlingService).requestPermit(btsId, cellId, priority); inOrder .verify(this.hls5Connector) .connectUnchecked(eq(this.messageMetadata), eq(this.dlmsDevice), any(), any()); - inOrder.verify(this.throttlingService).closeConnection(); + inOrder.verify(this.throttlingService).releasePermit(permit); verify(this.secretManagementService) .activateNewKeys( @@ -155,11 +166,20 @@ void testThrottlingServiceCalledAndKeysActivated() throws Exception { @Test void testWhenConnectionFailedThenConnectionClosedAtThrottlingService() throws Exception { + final int btsId = 1; + final int cellId = 2; + final int priority = 3; + final Permit permit = mock(Permit.class); when(this.domainHelperService.findDlmsDevice(DEVICE_IDENTIFICATION)) .thenReturn(this.dlmsDevice); when(this.hls5Connector.connectUnchecked(any(), any(), any(), any())).thenReturn(null); + when(this.messageMetadata.getBaseTransceiverStationId()).thenReturn(btsId); + when(this.messageMetadata.getCellId()).thenReturn(cellId); + when(this.messageMetadata.getMessagePriority()).thenReturn(priority); + when(this.throttlingService.requestPermit(btsId, cellId, priority)).thenReturn(permit); + when(this.secretManagementService.hasNewSecret( eq(this.messageMetadata), eq(DEVICE_IDENTIFICATION))) .thenReturn(true); @@ -168,9 +188,9 @@ void testWhenConnectionFailedThenConnectionClosedAtThrottlingService() throws Ex final InOrder inOrder = inOrder(this.throttlingService, this.hls5Connector); - inOrder.verify(this.throttlingService).openConnection(); + inOrder.verify(this.throttlingService).requestPermit(btsId, cellId, priority); inOrder.verify(this.hls5Connector).connectUnchecked(any(), any(), any(), any()); - inOrder.verify(this.throttlingService).closeConnection(); + inOrder.verify(this.throttlingService).releasePermit(permit); verify(this.secretManagementService, never()).activateNewKeys(any(), any(), any()); } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/application/throttling/LocalThrottlingServiceImplTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/application/throttling/LocalThrottlingServiceImplTest.java new file mode 100644 index 00000000000..9830182eb45 --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/application/throttling/LocalThrottlingServiceImplTest.java @@ -0,0 +1,251 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.adapter.protocol.dlms.application.throttling; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.time.Duration; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.List; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Semaphore; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.mockito.junit.jupiter.MockitoExtension; +import org.opensmartgridplatform.throttling.ThrottlingPermitDeniedException; +import org.opensmartgridplatform.throttling.api.Permit; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.test.util.ReflectionTestUtils; + +@ExtendWith(MockitoExtension.class) +class LocalThrottlingServiceImplTest { + + private static final Logger LOGGER = + LoggerFactory.getLogger(LocalThrottlingServiceImplTest.class); + + private static final Integer MAX_NEW_CONNECTION_REQUESTS = 10; + private static final Integer MAX_OPEN_CONNECTIONS = MAX_NEW_CONNECTION_REQUESTS * 2; + private static final Integer MAX_NEW_CONNECTION_RESET_TIME = 200; + private static final Integer MAX_WAIT_FOR_PERMIT = 500; + private static final Integer CLEANUP_PERMITS_INTERVAL = 200; + private static final Duration PERMIT_TTL = Duration.of(2, ChronoUnit.SECONDS); + + private LocalThrottlingServiceImpl throttlingService; + + @BeforeEach + void setUp() { + this.throttlingService = + new LocalThrottlingServiceImpl(MAX_OPEN_CONNECTIONS, MAX_NEW_CONNECTION_REQUESTS); + ReflectionTestUtils.setField( + this.throttlingService, "maxNewConnectionResetTime", MAX_NEW_CONNECTION_RESET_TIME); + ReflectionTestUtils.setField( + this.throttlingService, "maxWaitForPermitInMs", MAX_WAIT_FOR_PERMIT); + ReflectionTestUtils.setField( + this.throttlingService, "cleanupExpiredPermitsInterval", CLEANUP_PERMITS_INTERVAL); + ReflectionTestUtils.setField(this.throttlingService, "timeToLive", PERMIT_TTL); + this.throttlingService.postConstruct(); + } + + @ParameterizedTest + @ValueSource(ints = {4, 5}) + void testThrottlingOpenConnections(final int priority) throws InterruptedException { + ReflectionTestUtils.setField(this.throttlingService, "maxWaitForPermitInMs", 0); + + // Claim 10 + final List firstBatch = this.requestPermitLowPrio(MAX_NEW_CONNECTION_REQUESTS); + // Sleep longer than reset time + Thread.sleep(MAX_NEW_CONNECTION_RESET_TIME + 100); + // Next 10 + this.requestPermitLowPrio(MAX_NEW_CONNECTION_REQUESTS); + // Sleep longer than reset time + Thread.sleep(MAX_NEW_CONNECTION_RESET_TIME + 100); + this.assertPermitsInMemory(MAX_OPEN_CONNECTIONS); + + assertThrows(ThrottlingPermitDeniedException.class, () -> this.requestPermit(1, priority)); + + // Free one + this.releasePermit(List.of(firstBatch.get(0))); + this.assertPermitsInMemory(MAX_OPEN_CONNECTIONS - 1); + // Claim one + this.requestPermit(1, priority); + this.assertPermitsInMemory(MAX_OPEN_CONNECTIONS); + // Next causes PermitDenied + assertThrows(ThrottlingPermitDeniedException.class, () -> this.requestPermit(1, priority)); + + this.assertPermitsInMemory(MAX_OPEN_CONNECTIONS); + this.assertAvailablePermits(0); + } + + @ParameterizedTest + @ValueSource(ints = {4, 5}) + void testThrottlingMaxNewConnections(final int priority) { + this.assertAvailableNewConnections(MAX_NEW_CONNECTION_REQUESTS); + // Claim max new + final List permits = this.requestPermit(MAX_NEW_CONNECTION_REQUESTS, priority); + this.assertAvailableNewConnections(0); + + this.releasePermitWithDelay(permits, MAX_WAIT_FOR_PERMIT / 2); + + this.requestPermit(MAX_NEW_CONNECTION_REQUESTS, priority); + final int nrOfOpenConnections = MAX_NEW_CONNECTION_REQUESTS * 2; + + this.assertPermitsInMemory(nrOfOpenConnections); + this.assertAvailablePermits(MAX_OPEN_CONNECTIONS - nrOfOpenConnections); + this.assertAvailableNewConnections(0); + } + + @Test + void testReleaseUnknownPermit() { + final Permit unknownPermit = new Permit(666); + this.releasePermit(List.of(unknownPermit)); + this.assertPermitsInMemory(0); + this.assertAvailablePermits(MAX_OPEN_CONNECTIONS); + } + + @Test + void testPermit() { + final Permit permit = this.requestPermitLowPrio(1).get(0); + assertThat(permit.getThrottlingConfigId()).isEqualTo((short) 0); + assertThat(permit.getClientId()).isEqualTo((short) 0); + assertThat(permit.getRequestId()).isEqualTo(1); + + final Permit secondPermit = this.requestPermitLowPrio(1).get(0); + assertThat(secondPermit.getRequestId()).isEqualTo(2); + + this.assertPermitsInMemory(2); + this.assertAvailablePermits(MAX_OPEN_CONNECTIONS - 2); + } + + @Test + void testCleanupPermit() throws InterruptedException { + final long minCleanupInterval = PERMIT_TTL.toMillis() + CLEANUP_PERMITS_INTERVAL + 10; + + // First 5 permits + this.requestPermitLowPrio(5); + this.assertPermitsInMemory(5); + Thread.sleep(minCleanupInterval / 2); + + // one more permit + this.assertPermitsInMemory(5); + this.requestPermitLowPrio(1); + this.assertPermitsInMemory(6); + Thread.sleep(minCleanupInterval / 2); + + // First 5 are cleaned + this.assertPermitsInMemory(1); + this.assertAvailablePermits(MAX_OPEN_CONNECTIONS - 1); + } + + @ParameterizedTest + @ValueSource(ints = {0, 600, 1200}) + void testPermitMaxWait(final int releaseDelay) throws InterruptedException { + final int priority = 4; + // Claim 10 + final List firstBatch = this.requestPermit(MAX_NEW_CONNECTION_REQUESTS, priority); + // Sleep longer than reset time + Thread.sleep(MAX_NEW_CONNECTION_RESET_TIME + 100); + // Next 10 + this.requestPermit(MAX_NEW_CONNECTION_REQUESTS, priority); + // Sleep longer than reset time + Thread.sleep(MAX_NEW_CONNECTION_RESET_TIME + 100); + + final long startTime = System.currentTimeMillis(); + if (releaseDelay == 0) { + this.releasePermit(List.of(firstBatch.get(0))); + this.assertPermitsInMemory(MAX_OPEN_CONNECTIONS - 1); + this.assertAvailablePermits(1); + } else { + this.releasePermitWithDelay(List.of(firstBatch.get(0)), releaseDelay); + this.assertPermitsInMemory(MAX_OPEN_CONNECTIONS); + this.assertAvailablePermits(0); + } + + if (releaseDelay > MAX_WAIT_FOR_PERMIT) { + assertThrows(ThrottlingPermitDeniedException.class, () -> this.requestPermit(1, priority)); + assertThat(System.currentTimeMillis() - startTime) + .isGreaterThanOrEqualTo(MAX_WAIT_FOR_PERMIT); + } else { + this.requestPermit(1, priority); + assertThat(System.currentTimeMillis() - startTime).isGreaterThanOrEqualTo(releaseDelay); + } + + this.assertPermitsInMemory(MAX_OPEN_CONNECTIONS); + this.assertAvailablePermits(0); + } + + private List requestPermitLowPrio(final int requests) { + return this.requestPermit(requests, 3); + } + + private List requestPermitHighPrio(final int requests) { + return this.requestPermit(requests, 8); + } + + private List requestPermit(final int requests, final int priority) { + final int btsId = 1; + final int cellId = 2; + + final List permits = new ArrayList<>(); + for (int i = 0; i < requests; i++) { + LOGGER.info("Incoming request {}", i); + final Permit permit = this.throttlingService.requestPermit(btsId, cellId, priority); + permits.add(permit); + } + + return permits; + } + + private void releasePermit(final List permits) { + for (final Permit permit : permits) { + LOGGER.info("Closing Connection for permit {}", permit); + this.throttlingService.releasePermit(permit); + } + } + + private void releasePermitWithDelay(final List permits, final long delay) { + final Timer timer = new Timer(); + final TimerTask task = + new TimerTask() { + @Override + public void run() { + LocalThrottlingServiceImplTest.this.releasePermit(permits); + } + }; // creating timer task + timer.schedule(task, delay); // scheduling the task after the delay + } + + private void assertPermitsInMemory(final Integer nrOfPermitsInMemory) { + final ConcurrentHashMap permitsInMemory = + (ConcurrentHashMap) + ReflectionTestUtils.getField(this.throttlingService, "permitsByRequestId"); + assert permitsInMemory != null; + assertThat(permitsInMemory).hasSize(nrOfPermitsInMemory); + } + + private void assertAvailablePermits(final Integer availablePermits) { + final Semaphore openConnectionsSemaphoreInMemory = + (Semaphore) + ReflectionTestUtils.getField(this.throttlingService, "openConnectionsSemaphore"); + assert openConnectionsSemaphoreInMemory != null; + assertThat(openConnectionsSemaphoreInMemory.availablePermits()).isEqualTo(availablePermits); + } + + private void assertAvailableNewConnections(final Integer availablePermits) { + final Semaphore newConnectionRequestsSemaphoreInMemory = + (Semaphore) + ReflectionTestUtils.getField(this.throttlingService, "newConnectionRequestsSemaphore"); + assert newConnectionRequestsSemaphoreInMemory != null; + assertThat(newConnectionRequestsSemaphoreInMemory.availablePermits()) + .isEqualTo(availablePermits); + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/application/throttling/SharedThrottlingServiceImplTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/application/throttling/SharedThrottlingServiceImplTest.java new file mode 100644 index 00000000000..2d5d69af1fd --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/application/throttling/SharedThrottlingServiceImplTest.java @@ -0,0 +1,57 @@ +/* + * SPDX-FileCopyrightText: Copyright Contributors to the GXF project + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.opensmartgridplatform.adapter.protocol.dlms.application.throttling; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.opensmartgridplatform.adapter.protocol.dlms.application.config.ThrottlingClientConfig; +import org.opensmartgridplatform.throttling.ThrottlingClient; +import org.opensmartgridplatform.throttling.api.Permit; + +@ExtendWith(MockitoExtension.class) +class SharedThrottlingServiceImplTest { + private final Integer BTS_ID = 2; + private final Integer CELL_ID = 3; + private final Integer PRIORITY = 4; + + @Mock private ThrottlingClientConfig throttlingClientConfig; + @Mock private ThrottlingClient throttlingClient; + + @InjectMocks SharedThrottlingServiceImpl throttlingService; + + @Test + void testOpenConnection() { + final Permit permit = mock(Permit.class); + when(this.throttlingClientConfig.throttlingClient()).thenReturn(this.throttlingClient); + when(this.throttlingClient.requestPermitUsingNetworkSegmentIfIdsAreAvailable( + this.BTS_ID, this.CELL_ID, this.PRIORITY)) + .thenReturn(permit); + + final Permit result = + this.throttlingService.requestPermit(this.BTS_ID, this.CELL_ID, this.PRIORITY); + + assertThat(result).isEqualTo(permit); + } + + @Test + void testCloseConnection() { + final Permit permit = mock(Permit.class); + when(this.throttlingClientConfig.throttlingClient()).thenReturn(this.throttlingClient); + + this.throttlingService.releasePermit(permit); + + verify(this.throttlingClient).releasePermit(permit); + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/AlarmHelperServiceTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/AlarmHelperServiceTest.java index efe69448b09..53e01f56966 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/AlarmHelperServiceTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/AlarmHelperServiceTest.java @@ -9,7 +9,7 @@ import java.util.HashSet; import java.util.Set; import org.junit.jupiter.api.Test; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectType; +import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; import org.opensmartgridplatform.dto.valueobjects.smartmetering.AlarmTypeDto; class AlarmHelperServiceTest { diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/ClearAlarmRegisterCommandExecutorTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/ClearAlarmRegisterCommandExecutorTest.java index b10075d35c1..32866116c8d 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/ClearAlarmRegisterCommandExecutorTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/ClearAlarmRegisterCommandExecutorTest.java @@ -5,36 +5,34 @@ package org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.alarm; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.ThrowableAssert.catchThrowable; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.io.IOException; import java.util.Optional; +import org.assertj.core.api.ThrowableAssert; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; +import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; import org.openmuc.jdlms.AccessResultCode; import org.openmuc.jdlms.AttributeAddress; import org.openmuc.jdlms.DlmsConnection; +import org.openmuc.jdlms.ObisCode; import org.openmuc.jdlms.SetParameter; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectConfigService; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectType; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.ObjectConfigServiceHelper; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDevice; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.Protocol; import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionManager; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ConnectionException; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; import org.opensmartgridplatform.adapter.protocol.dlms.infra.messaging.DlmsMessageListener; import org.opensmartgridplatform.adapter.protocol.dlms.infra.messaging.LoggingDlmsMessageListener; -import org.opensmartgridplatform.dlms.interfaceclass.InterfaceClass; -import org.opensmartgridplatform.dlms.interfaceclass.attribute.DataAttribute; +import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ActionResponseDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ClearAlarmRegisterRequestDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.OsgpResultTypeDto; @@ -51,7 +49,7 @@ class ClearAlarmRegisterCommandExecutorTest { private static final Long ALARM_CODE = 0L; - @Mock private DlmsObjectConfigService dlmsObjectConfigService; + @Mock private ObjectConfigServiceHelper objectConfigServiceHelper; @Mock private DlmsConnectionManager connectionManager; @@ -69,7 +67,7 @@ class ClearAlarmRegisterCommandExecutorTest { @BeforeEach void setup() { - this.executor = new ClearAlarmRegisterCommandExecutor(this.dlmsObjectConfigService); + this.executor = new ClearAlarmRegisterCommandExecutor(this.objectConfigServiceHelper); this.dlmsMessageListener = new LoggingDlmsMessageListener(null, null); } @@ -82,7 +80,8 @@ void testAsBundleResponse() throws ProtocolAdapterException { @Test void testAsBundleResponseOtherReason() { final Throwable actual = - catchThrowable(() -> this.executor.asBundleResponse(AccessResultCode.OTHER_REASON)); + ThrowableAssert.catchThrowable( + () -> this.executor.asBundleResponse(AccessResultCode.OTHER_REASON)); assertThat(actual).isInstanceOf(ProtocolAdapterException.class); } @@ -112,14 +111,14 @@ void shouldExecuteForProtocolSmr55() throws ProtocolAdapterException, IOExceptio } @Test - void connectionProblemAlarmRegister1() throws ProtocolAdapterException, IOException { + void connectionProblemAlarmRegister1() throws IOException, ProtocolAdapterException { when(this.dlmsConnection.set(this.setParameterArgumentCaptor.capture())) .thenThrow(new IOException()); final DlmsDevice dlmsDevice = new DlmsDevice("SMR 5.2 device"); this.setupAlarmRegister1(dlmsDevice); final Throwable actual = - catchThrowable( + ThrowableAssert.catchThrowable( () -> this.executor.execute( this.connectionManager, dlmsDevice, this.dto, this.messageMetadata)); @@ -127,13 +126,13 @@ void connectionProblemAlarmRegister1() throws ProtocolAdapterException, IOExcept } @Test - void nullResultAlarmRegister1() throws ProtocolAdapterException, IOException { + void nullResultAlarmRegister1() throws IOException, ProtocolAdapterException { when(this.dlmsConnection.set(this.setParameterArgumentCaptor.capture())).thenReturn(null); final DlmsDevice dlmsDevice = new DlmsDevice("SMR 5.2 device"); this.setupAlarmRegister1(dlmsDevice); final Throwable actual = - catchThrowable( + ThrowableAssert.catchThrowable( () -> this.executor.execute( this.connectionManager, dlmsDevice, this.dto, this.messageMetadata)); @@ -141,7 +140,7 @@ void nullResultAlarmRegister1() throws ProtocolAdapterException, IOException { } @Test - void connectionProblemAlarmRegister2() throws ProtocolAdapterException, IOException { + void connectionProblemAlarmRegister2() throws IOException, ProtocolAdapterException { when(this.dlmsConnection.set(any(SetParameter.class))) .thenReturn(AccessResultCode.SUCCESS) .thenThrow(new IOException()); @@ -149,7 +148,7 @@ void connectionProblemAlarmRegister2() throws ProtocolAdapterException, IOExcept final DlmsDevice dlmsDevice = new DlmsDevice("SMR 5.2 device"); this.setupAlarmRegister2(dlmsDevice); final Throwable actual = - catchThrowable( + ThrowableAssert.catchThrowable( () -> this.executor.execute( this.connectionManager, dlmsDevice, this.dto, this.messageMetadata)); @@ -157,7 +156,7 @@ void connectionProblemAlarmRegister2() throws ProtocolAdapterException, IOExcept } @Test - void nullResultAlarmRegister2() throws ProtocolAdapterException, IOException { + void nullResultAlarmRegister2() throws IOException, ProtocolAdapterException { when(this.dlmsConnection.set(this.setParameterArgumentCaptor.capture())) .thenReturn(AccessResultCode.SUCCESS) .thenReturn(null); @@ -165,7 +164,7 @@ void nullResultAlarmRegister2() throws ProtocolAdapterException, IOException { final DlmsDevice dlmsDevice = new DlmsDevice("SMR 5.2 device"); this.setupAlarmRegister2(dlmsDevice); final Throwable actual = - catchThrowable( + ThrowableAssert.catchThrowable( () -> this.executor.execute( this.connectionManager, dlmsDevice, this.dto, this.messageMetadata)); @@ -183,8 +182,6 @@ void failureRegister1AndResultAlarmRegister2() throws ProtocolAdapterException, final AccessResultCode accessResultCode = this.executor.execute(this.connectionManager, dlmsDevice, this.dto, this.messageMetadata); assertThat(accessResultCode).isEqualTo(AccessResultCode.OTHER_REASON); - verify(this.dlmsObjectConfigService, times(1)) - .findAttributeAddress(eq(dlmsDevice), any(), any()); } @Test @@ -214,7 +211,7 @@ void resultAlarmRegister2() throws ProtocolAdapterException, IOException { } @Test - void connectionProblemAlarmRegister3() throws ProtocolAdapterException, IOException { + void connectionProblemAlarmRegister3() throws IOException, ProtocolAdapterException { when(this.dlmsConnection.set(any(SetParameter.class))) .thenReturn(AccessResultCode.SUCCESS) .thenReturn(AccessResultCode.SUCCESS) @@ -223,7 +220,7 @@ void connectionProblemAlarmRegister3() throws ProtocolAdapterException, IOExcept final DlmsDevice dlmsDevice = new DlmsDevice("SMR 5.5 device"); this.setupAlarmRegister3(dlmsDevice); final Throwable actual = - catchThrowable( + ThrowableAssert.catchThrowable( () -> this.executor.execute( this.connectionManager, dlmsDevice, this.dto, this.messageMetadata)); @@ -231,7 +228,7 @@ void connectionProblemAlarmRegister3() throws ProtocolAdapterException, IOExcept } @Test - void nullResultAlarmRegister3() throws ProtocolAdapterException, IOException { + void nullResultAlarmRegister3() throws IOException, ProtocolAdapterException { when(this.dlmsConnection.set(this.setParameterArgumentCaptor.capture())) .thenReturn(AccessResultCode.SUCCESS) .thenReturn(AccessResultCode.SUCCESS) @@ -240,7 +237,7 @@ void nullResultAlarmRegister3() throws ProtocolAdapterException, IOException { final DlmsDevice dlmsDevice = new DlmsDevice("SMR 5.5 device"); this.setupAlarmRegister3(dlmsDevice); final Throwable actual = - catchThrowable( + ThrowableAssert.catchThrowable( () -> this.executor.execute( this.connectionManager, dlmsDevice, this.dto, this.messageMetadata)); @@ -259,8 +256,6 @@ void failureRegister2AndResultAlarmRegister3() throws ProtocolAdapterException, final AccessResultCode accessResultCode = this.executor.execute(this.connectionManager, dlmsDevice, this.dto, this.messageMetadata); assertThat(accessResultCode).isEqualTo(AccessResultCode.OTHER_REASON); - verify(this.dlmsObjectConfigService, times(2)) - .findAttributeAddress(eq(dlmsDevice), any(), any()); } @Test @@ -291,80 +286,56 @@ void resultAlarmRegister3() throws ProtocolAdapterException, IOException { assertThat(accessResultCode).isEqualTo(AccessResultCode.SUCCESS); } - void setupAlarmRegister1(final DlmsDevice dlmsDevice) - throws ProtocolAdapterException, IOException { - - dlmsDevice.setProtocol("SMR", "5.2"); + void setupAlarmRegister1(final DlmsDevice dlmsDevice) throws ProtocolAdapterException { - when(this.dlmsObjectConfigService.findAttributeAddress( - dlmsDevice, DlmsObjectType.ALARM_REGISTER_1, null)) - .thenReturn( - Optional.of( - new AttributeAddress( - InterfaceClass.DATA.id(), - OBIS_CODE_ALARM_REGISTER_1, - DataAttribute.VALUE.attributeId()))); + this.mockAlarmCosemObject( + dlmsDevice, OBIS_CODE_ALARM_REGISTER_1, DlmsObjectType.ALARM_REGISTER_1.name()); when(this.connectionManager.getDlmsMessageListener()).thenReturn(this.dlmsMessageListener); when(this.connectionManager.getConnection()).thenReturn(this.dlmsConnection); } - void setupAlarmRegister2(final DlmsDevice dlmsDevice) - throws ProtocolAdapterException, IOException { - dlmsDevice.setProtocol("SMR", "5.2"); - - when(this.dlmsObjectConfigService.findAttributeAddress( - dlmsDevice, DlmsObjectType.ALARM_REGISTER_1, null)) - .thenReturn( - Optional.of( - new AttributeAddress( - InterfaceClass.DATA.id(), - OBIS_CODE_ALARM_REGISTER_1, - DataAttribute.VALUE.attributeId()))); - - when(this.dlmsObjectConfigService.findAttributeAddress( - dlmsDevice, DlmsObjectType.ALARM_REGISTER_2, null)) - .thenReturn( - Optional.of( - new AttributeAddress( - InterfaceClass.DATA.id(), - OBIS_CODE_ALARM_REGISTER_2, - DataAttribute.VALUE.attributeId()))); + void setupAlarmRegister2(final DlmsDevice dlmsDevice) throws ProtocolAdapterException { + + this.mockAlarmCosemObject( + dlmsDevice, OBIS_CODE_ALARM_REGISTER_1, DlmsObjectType.ALARM_REGISTER_1.name()); + this.mockAlarmCosemObject( + dlmsDevice, OBIS_CODE_ALARM_REGISTER_2, DlmsObjectType.ALARM_REGISTER_2.name()); when(this.connectionManager.getDlmsMessageListener()).thenReturn(this.dlmsMessageListener); when(this.connectionManager.getConnection()).thenReturn(this.dlmsConnection); } - void setupAlarmRegister3(final DlmsDevice dlmsDevice) - throws ProtocolAdapterException, IOException { + private void mockAlarmCosemObject( + final DlmsDevice dlmsDevice, final String obisCode, final String dlmsObjectTypeName) { + + final ObisCode newObisCode = new ObisCode(obisCode); + + final AttributeAddress attributeAddress = Mockito.mock(AttributeAddress.class); + when(attributeAddress.getClassId()).thenReturn(1); + when(attributeAddress.getId()).thenReturn(2); + when(attributeAddress.getInstanceId()).thenReturn(newObisCode); + + when(this.objectConfigServiceHelper.findOptionalDefaultAttributeAddress( + Protocol.forDevice(dlmsDevice), DlmsObjectType.valueOf(dlmsObjectTypeName))) + .thenReturn(Optional.of(attributeAddress)); + } + + void setupAlarmRegister3(final DlmsDevice dlmsDevice) throws ProtocolAdapterException { dlmsDevice.setProtocol("SMR", "5.5"); - when(this.dlmsObjectConfigService.findAttributeAddress( - dlmsDevice, DlmsObjectType.ALARM_REGISTER_1, null)) - .thenReturn( - Optional.of( - new AttributeAddress( - InterfaceClass.DATA.id(), - OBIS_CODE_ALARM_REGISTER_1, - DataAttribute.VALUE.attributeId()))); - - when(this.dlmsObjectConfigService.findAttributeAddress( - dlmsDevice, DlmsObjectType.ALARM_REGISTER_2, null)) - .thenReturn( - Optional.of( - new AttributeAddress( - InterfaceClass.DATA.id(), - OBIS_CODE_ALARM_REGISTER_2, - DataAttribute.VALUE.attributeId()))); - - when(this.dlmsObjectConfigService.findAttributeAddress( - dlmsDevice, DlmsObjectType.ALARM_REGISTER_3, null)) - .thenReturn( - Optional.of( - new AttributeAddress( - InterfaceClass.DATA.id(), - OBIS_CODE_ALARM_REGISTER_3, - DataAttribute.VALUE.attributeId()))); + this.mockAlarmCosemObject( + dlmsDevice, + OBIS_CODE_ALARM_REGISTER_1, + org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.ALARM_REGISTER_1.name()); + this.mockAlarmCosemObject( + dlmsDevice, + OBIS_CODE_ALARM_REGISTER_2, + org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.ALARM_REGISTER_2.name()); + this.mockAlarmCosemObject( + dlmsDevice, + OBIS_CODE_ALARM_REGISTER_3, + org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.ALARM_REGISTER_3.name()); when(this.connectionManager.getDlmsMessageListener()).thenReturn(this.dlmsMessageListener); when(this.connectionManager.getConnection()).thenReturn(this.dlmsConnection); @@ -375,14 +346,8 @@ void assertForOneRegister(final String protocol, final String protocolVersion) final DlmsDevice dlmsDevice = new DlmsDevice(protocol + " " + protocolVersion + " device"); dlmsDevice.setProtocol(protocol, protocolVersion); - when(this.dlmsObjectConfigService.findAttributeAddress( - dlmsDevice, DlmsObjectType.ALARM_REGISTER_1, null)) - .thenReturn( - Optional.of( - new AttributeAddress( - InterfaceClass.DATA.id(), - OBIS_CODE_ALARM_REGISTER_1, - DataAttribute.VALUE.attributeId()))); + this.mockAlarmCosemObject( + dlmsDevice, OBIS_CODE_ALARM_REGISTER_1, DlmsObjectType.ALARM_REGISTER_1.name()); when(this.connectionManager.getDlmsMessageListener()).thenReturn(this.dlmsMessageListener); when(this.connectionManager.getConnection()).thenReturn(this.dlmsConnection); @@ -405,23 +370,11 @@ void assertForTwoRegisters(final String protocol, final String protocolVersion) final DlmsDevice dlmsDevice = new DlmsDevice(protocol + " " + protocolVersion + " device"); dlmsDevice.setProtocol(protocol, protocolVersion); - when(this.dlmsObjectConfigService.findAttributeAddress( - dlmsDevice, DlmsObjectType.ALARM_REGISTER_1, null)) - .thenReturn( - Optional.of( - new AttributeAddress( - InterfaceClass.DATA.id(), - OBIS_CODE_ALARM_REGISTER_1, - DataAttribute.VALUE.attributeId()))); - - when(this.dlmsObjectConfigService.findAttributeAddress( - dlmsDevice, DlmsObjectType.ALARM_REGISTER_2, null)) - .thenReturn( - Optional.of( - new AttributeAddress( - InterfaceClass.DATA.id(), - OBIS_CODE_ALARM_REGISTER_2, - DataAttribute.VALUE.attributeId()))); + this.mockAlarmCosemObject( + dlmsDevice, OBIS_CODE_ALARM_REGISTER_1, DlmsObjectType.ALARM_REGISTER_1.name()); + + this.mockAlarmCosemObject( + dlmsDevice, OBIS_CODE_ALARM_REGISTER_2, DlmsObjectType.ALARM_REGISTER_2.name()); when(this.connectionManager.getDlmsMessageListener()).thenReturn(this.dlmsMessageListener); when(this.connectionManager.getConnection()).thenReturn(this.dlmsConnection); @@ -451,32 +404,14 @@ void assertForThreeRegisters(final String protocol, final String protocolVersion final DlmsDevice dlmsDevice = new DlmsDevice(protocol + " " + protocolVersion + " device"); dlmsDevice.setProtocol(protocol, protocolVersion); - when(this.dlmsObjectConfigService.findAttributeAddress( - dlmsDevice, DlmsObjectType.ALARM_REGISTER_1, null)) - .thenReturn( - Optional.of( - new AttributeAddress( - InterfaceClass.DATA.id(), - OBIS_CODE_ALARM_REGISTER_1, - DataAttribute.VALUE.attributeId()))); - - when(this.dlmsObjectConfigService.findAttributeAddress( - dlmsDevice, DlmsObjectType.ALARM_REGISTER_2, null)) - .thenReturn( - Optional.of( - new AttributeAddress( - InterfaceClass.DATA.id(), - OBIS_CODE_ALARM_REGISTER_2, - DataAttribute.VALUE.attributeId()))); - - when(this.dlmsObjectConfigService.findAttributeAddress( - dlmsDevice, DlmsObjectType.ALARM_REGISTER_3, null)) - .thenReturn( - Optional.of( - new AttributeAddress( - InterfaceClass.DATA.id(), - OBIS_CODE_ALARM_REGISTER_3, - DataAttribute.VALUE.attributeId()))); + this.mockAlarmCosemObject( + dlmsDevice, OBIS_CODE_ALARM_REGISTER_1, DlmsObjectType.ALARM_REGISTER_1.name()); + + this.mockAlarmCosemObject( + dlmsDevice, OBIS_CODE_ALARM_REGISTER_2, DlmsObjectType.ALARM_REGISTER_2.name()); + + this.mockAlarmCosemObject( + dlmsDevice, OBIS_CODE_ALARM_REGISTER_3, DlmsObjectType.ALARM_REGISTER_3.name()); when(this.connectionManager.getDlmsMessageListener()).thenReturn(this.dlmsMessageListener); when(this.connectionManager.getConnection()).thenReturn(this.dlmsConnection); diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/ClearMBusStatusOnAllChannelsCommandExecutorTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/ClearMBusStatusOnAllChannelsCommandExecutorTest.java index 7da02b9b66b..432356ed1e5 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/ClearMBusStatusOnAllChannelsCommandExecutorTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/ClearMBusStatusOnAllChannelsCommandExecutorTest.java @@ -29,9 +29,9 @@ import org.openmuc.jdlms.MethodResultCode; import org.openmuc.jdlms.SetParameter; import org.openmuc.jdlms.datatypes.DataObject; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectConfigService; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectType; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.ObjectConfigServiceHelper; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDevice; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.Protocol; import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionManager; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; import org.opensmartgridplatform.adapter.protocol.dlms.infra.messaging.DlmsMessageListener; @@ -39,24 +39,25 @@ import org.opensmartgridplatform.dlms.interfaceclass.InterfaceClass; import org.opensmartgridplatform.dlms.interfaceclass.attribute.DataAttribute; import org.opensmartgridplatform.dlms.interfaceclass.attribute.ExtendedRegisterAttribute; +import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ClearMBusStatusOnAllChannelsRequestDto; import org.opensmartgridplatform.shared.infra.jms.MessageMetadata; @ExtendWith(MockitoExtension.class) class ClearMBusStatusOnAllChannelsCommandExecutorTest { - private static final String OBIS_CODE_TEMPLATE_READ_STATUS = "0..24.2.6.255"; + private static final String OBIS_CODE_TEMPLATE_READ_STATUS = "0.x.24.2.6.255"; private static final int CLASS_ID_READ_STATUS = 4; - private static final String OBIS_CODE_TEMPLATE_CLEAR_STATUS = "0..94.31.10.255"; + private static final String OBIS_CODE_TEMPLATE_CLEAR_STATUS = "0.x.94.31.10.255"; private static final int CLASS_ID_CLEAR_STATUS = 1; - private static final String OBIS_CODE_TEMPLATE_MBUS_CLIENT_SETUP = "0..24.1.0.255"; + private static final String OBIS_CODE_TEMPLATE_MBUS_CLIENT_SETUP = "0.x.24.1.0.255"; private static final int CLASS_ID_MBUS_CLIENT = 72; private static final Long STATUS_MASK = 123456L; - @Mock private DlmsObjectConfigService dlmsObjectConfigService; + @Mock private ObjectConfigServiceHelper objectConfigServiceHelper; @Mock private DlmsConnectionManager connectionManager; @@ -82,13 +83,13 @@ class ClearMBusStatusOnAllChannelsCommandExecutorTest { @BeforeEach void setup() { - this.executor = new ClearMBusStatusOnAllChannelsCommandExecutor(this.dlmsObjectConfigService); + this.executor = new ClearMBusStatusOnAllChannelsCommandExecutor(this.objectConfigServiceHelper); this.dlmsMessageListener = new LoggingDlmsMessageListener(null, null); } @Test void testExecuteObjectNotFound() throws ProtocolAdapterException { - when(this.dlmsObjectConfigService.getAttributeAddress(any(), any(), any())) + when(this.objectConfigServiceHelper.findDefaultAttributeAddress(any(), any(), any(), any())) .thenThrow(new ProtocolAdapterException("Object not found")); final DlmsDevice dlmsDevice = new DlmsDevice(); @@ -96,40 +97,40 @@ void testExecuteObjectNotFound() throws ProtocolAdapterException { assertThatExceptionOfType(ProtocolAdapterException.class) .isThrownBy( - () -> { - this.executor.execute( - this.connectionManager, dlmsDevice, this.dto, this.messageMetadata); - }); + () -> + this.executor.execute( + this.connectionManager, dlmsDevice, this.dto, this.messageMetadata)); } @Test void shouldSkipIfStatusIsZero() throws ProtocolAdapterException, IOException { final DlmsDevice dlmsDevice_5_1 = new DlmsDevice("SMR 5.1 device"); dlmsDevice_5_1.setProtocol("SMR", "5.1"); + final Protocol protocol = Protocol.forDevice(dlmsDevice_5_1); for (int channel = 1; channel <= 4; channel++) { - when(this.dlmsObjectConfigService.getAttributeAddress( - dlmsDevice_5_1, DlmsObjectType.READ_MBUS_STATUS, channel)) + when(this.objectConfigServiceHelper.findDefaultAttributeAddress( + dlmsDevice_5_1, protocol, DlmsObjectType.READ_MBUS_STATUS, channel)) .thenReturn( new AttributeAddress( InterfaceClass.EXTENDED_REGISTER.id(), - OBIS_CODE_TEMPLATE_READ_STATUS.replaceAll("", Integer.toString(channel)), + OBIS_CODE_TEMPLATE_READ_STATUS.replaceAll("x", Integer.toString(channel)), ExtendedRegisterAttribute.VALUE.attributeId())); - when(this.dlmsObjectConfigService.getAttributeAddress( - dlmsDevice_5_1, DlmsObjectType.CLEAR_MBUS_STATUS, channel)) + when(this.objectConfigServiceHelper.findDefaultAttributeAddress( + dlmsDevice_5_1, protocol, DlmsObjectType.CLEAR_MBUS_STATUS, channel)) .thenReturn( new AttributeAddress( InterfaceClass.DATA.id(), - OBIS_CODE_TEMPLATE_CLEAR_STATUS.replaceAll("", Integer.toString(channel)), + OBIS_CODE_TEMPLATE_CLEAR_STATUS.replaceAll("x", Integer.toString(channel)), DataAttribute.VALUE.attributeId())); - when(this.dlmsObjectConfigService.getAttributeAddress( - dlmsDevice_5_1, DlmsObjectType.CLIENT_SETUP_MBUS, channel)) + when(this.objectConfigServiceHelper.findDefaultAttributeAddress( + dlmsDevice_5_1, protocol, DlmsObjectType.MBUS_CLIENT_SETUP, channel)) .thenReturn( new AttributeAddress( InterfaceClass.MBUS_CLIENT.id(), - OBIS_CODE_TEMPLATE_MBUS_CLIENT_SETUP.replaceAll("", Integer.toString(channel)), + OBIS_CODE_TEMPLATE_MBUS_CLIENT_SETUP.replaceAll("x", Integer.toString(channel)), DataAttribute.VALUE.attributeId())); } @@ -150,30 +151,31 @@ void shouldSkipIfStatusIsZero() throws ProtocolAdapterException, IOException { void shouldExecuteForProtocol_SMR_5_1() throws ProtocolAdapterException, IOException { final DlmsDevice dlmsDevice_5_1 = new DlmsDevice("SMR 5.1 device"); dlmsDevice_5_1.setProtocol("SMR", "5.1"); + final Protocol protocol = Protocol.forDevice(dlmsDevice_5_1); for (int channel = 1; channel <= 4; channel++) { - when(this.dlmsObjectConfigService.getAttributeAddress( - dlmsDevice_5_1, DlmsObjectType.READ_MBUS_STATUS, channel)) + when(this.objectConfigServiceHelper.findDefaultAttributeAddress( + dlmsDevice_5_1, protocol, DlmsObjectType.READ_MBUS_STATUS, channel)) .thenReturn( new AttributeAddress( InterfaceClass.EXTENDED_REGISTER.id(), - OBIS_CODE_TEMPLATE_READ_STATUS.replaceAll("", Integer.toString(channel)), + OBIS_CODE_TEMPLATE_READ_STATUS.replaceAll("x", Integer.toString(channel)), ExtendedRegisterAttribute.VALUE.attributeId())); - when(this.dlmsObjectConfigService.getAttributeAddress( - dlmsDevice_5_1, DlmsObjectType.CLEAR_MBUS_STATUS, channel)) + when(this.objectConfigServiceHelper.findDefaultAttributeAddress( + dlmsDevice_5_1, protocol, DlmsObjectType.CLEAR_MBUS_STATUS, channel)) .thenReturn( new AttributeAddress( InterfaceClass.DATA.id(), - OBIS_CODE_TEMPLATE_CLEAR_STATUS.replaceAll("", Integer.toString(channel)), + OBIS_CODE_TEMPLATE_CLEAR_STATUS.replaceAll("x", Integer.toString(channel)), DataAttribute.VALUE.attributeId())); - when(this.dlmsObjectConfigService.getAttributeAddress( - dlmsDevice_5_1, DlmsObjectType.CLIENT_SETUP_MBUS, channel)) + when(this.objectConfigServiceHelper.findDefaultAttributeAddress( + dlmsDevice_5_1, protocol, DlmsObjectType.MBUS_CLIENT_SETUP, channel)) .thenReturn( new AttributeAddress( InterfaceClass.MBUS_CLIENT.id(), - OBIS_CODE_TEMPLATE_MBUS_CLIENT_SETUP.replaceAll("", Integer.toString(channel)), + OBIS_CODE_TEMPLATE_MBUS_CLIENT_SETUP.replaceAll("x", Integer.toString(channel)), DataAttribute.VALUE.attributeId())); } @@ -198,10 +200,10 @@ void shouldExecuteForProtocol_SMR_5_1() throws ProtocolAdapterException, IOExcep private void assertMethodResetAlarm(final List allMethods) { for (int i = 1; i <= 4; i++) { final MethodParameter methodParameter = allMethods.get(i - 1); - assertThat(((Number) methodParameter.getParameter().getValue()).longValue()).isEqualTo(0L); + assertThat(((Number) methodParameter.getParameter().getValue()).longValue()).isZero(); assertThat(methodParameter.getInstanceId().asDecimalString()) - .isEqualTo(OBIS_CODE_TEMPLATE_MBUS_CLIENT_SETUP.replaceAll("", String.valueOf(i))); + .isEqualTo(OBIS_CODE_TEMPLATE_MBUS_CLIENT_SETUP.replaceAll("x", String.valueOf(i))); assertThat(methodParameter.getClassId()).isEqualTo(CLASS_ID_MBUS_CLIENT); } } @@ -213,7 +215,7 @@ private void assertClearStatus(final List setParameters) { final AttributeAddress attributeAddress = setParameter.getAttributeAddress(); assertThat(attributeAddress.getInstanceId().asDecimalString()) - .isEqualTo(OBIS_CODE_TEMPLATE_CLEAR_STATUS.replaceAll("", String.valueOf(i))); + .isEqualTo(OBIS_CODE_TEMPLATE_CLEAR_STATUS.replaceAll("x", String.valueOf(i))); assertThat(attributeAddress.getClassId()).isEqualTo(CLASS_ID_CLEAR_STATUS); } } @@ -222,7 +224,7 @@ private void assertCurrentStatusAttributeAddresses(final List for (int i = 1; i <= 4; i++) { final AttributeAddress attributeAddress = attributes.get(i - 1); assertThat(attributeAddress.getInstanceId().asDecimalString()) - .isEqualTo(OBIS_CODE_TEMPLATE_READ_STATUS.replaceAll("", String.valueOf(i))); + .isEqualTo(OBIS_CODE_TEMPLATE_READ_STATUS.replaceAll("x", String.valueOf(i))); assertThat(attributeAddress.getClassId()).isEqualTo(CLASS_ID_READ_STATUS); } } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/ReadAlarmRegisterCommandExecutorTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/ReadAlarmRegisterCommandExecutorTest.java new file mode 100644 index 00000000000..aac80d12d1b --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/ReadAlarmRegisterCommandExecutorTest.java @@ -0,0 +1,297 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.alarm; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import org.assertj.core.api.ThrowableAssert; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.openmuc.jdlms.AccessResultCode; +import org.openmuc.jdlms.AttributeAddress; +import org.openmuc.jdlms.DlmsConnection; +import org.openmuc.jdlms.GetResult; +import org.openmuc.jdlms.MethodParameter; +import org.openmuc.jdlms.ObisCode; +import org.openmuc.jdlms.SetParameter; +import org.openmuc.jdlms.datatypes.DataObject; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.ObjectConfigServiceHelper; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDevice; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.Protocol; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionManager; +import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ConnectionException; +import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; +import org.opensmartgridplatform.adapter.protocol.dlms.infra.messaging.DlmsMessageListener; +import org.opensmartgridplatform.adapter.protocol.dlms.infra.messaging.LoggingDlmsMessageListener; +import org.opensmartgridplatform.dlms.interfaceclass.InterfaceClass; +import org.opensmartgridplatform.dlms.interfaceclass.attribute.RegisterAttribute; +import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; +import org.opensmartgridplatform.dto.valueobjects.smartmetering.AlarmTypeDto; +import org.opensmartgridplatform.dto.valueobjects.smartmetering.ReadAlarmRegisterRequestDto; +import org.opensmartgridplatform.shared.infra.jms.MessageMetadata; +import org.springframework.test.util.ReflectionTestUtils; + +@ExtendWith(MockitoExtension.class) +class ReadAlarmRegisterCommandExecutorTest { + + private static final String OBIS_CODE_ALARM_REGISTER_1 = "0.0.97.98.0.255"; + private static final String OBIS_CODE_ALARM_REGISTER_2 = "0.0.97.98.1.255"; + private static final int CLASS_ID_READ_ALARM_REGISTER = InterfaceClass.REGISTER.id(); + + @Mock private ObjectConfigServiceHelper objectConfigServiceHelper; + + @Mock private DlmsConnectionManager connectionManager; + + @Mock private DlmsConnection dlmsConnection; + + private DlmsMessageListener dlmsMessageListener; + + @Mock private ReadAlarmRegisterRequestDto dto; + + @Mock private MessageMetadata messageMetadata; + + @Captor private ArgumentCaptor attributeAddressArgumentCaptor; + @Mock private GetResult getResult; + @Mock private AlarmHelperService alarmHelperService; + @InjectMocks private ReadAlarmRegisterCommandExecutor executor; + + @BeforeEach + void setup() { + ReflectionTestUtils.setField(this.executor, "alarmHelperService", this.alarmHelperService); + this.dlmsMessageListener = new LoggingDlmsMessageListener(null, null); + } + + @Test + void shouldExecuteForProtocolDsmr422() throws ProtocolAdapterException, IOException { + this.assertForOneRegister("DSMR", "4.2.2"); + } + + @Test + void shouldExecuteForProtocolSmr500() throws ProtocolAdapterException, IOException { + this.assertForOneRegister("SMR", "5.0.0"); + } + + @Test + void shouldExecuteForProtocolSmr51() throws ProtocolAdapterException, IOException { + this.assertForOneRegister("SMR", "5.1"); + } + + @Test + void shouldExecuteForProtocolSmr52() throws ProtocolAdapterException, IOException { + this.assertForTwoRegisters("SMR", "5.2"); + } + + @Test + void shouldExecuteForProtocolSmr55() throws ProtocolAdapterException, IOException { + this.assertForTwoRegisters("SMR", "5.5"); + } + + @Test + void connectionProblemThrowsConnectionException() throws ProtocolAdapterException { + when(this.connectionManager.getConnection()).thenThrow(new ConnectionException("error")); + + final DlmsDevice dlmsDevice = this.getDlmsDevice("SMR", " 5.2"); + this.mockAlarmCosemObject( + dlmsDevice, OBIS_CODE_ALARM_REGISTER_1, DlmsObjectType.ALARM_REGISTER_1.name()); + + when(this.connectionManager.getDlmsMessageListener()).thenReturn(this.dlmsMessageListener); + final Throwable actual = + ThrowableAssert.catchThrowable( + () -> + this.executor.execute( + this.connectionManager, dlmsDevice, this.dto, this.messageMetadata)); + assertThat(actual).isInstanceOf(ConnectionException.class); + } + + @Test + void nullResultAlarmRegisterThrowsProtocolAdapterException() throws ProtocolAdapterException { + final DlmsDevice dlmsDevice = this.getDlmsDevice("SMR", " 5.2"); + this.setupAlarmRegister1(dlmsDevice); + final Throwable actual = + ThrowableAssert.catchThrowable( + () -> + this.executor.execute( + this.connectionManager, dlmsDevice, this.dto, this.messageMetadata)); + assertThat(actual).isInstanceOf(ProtocolAdapterException.class); + } + + @Test + void accessResultCodeIsNotSuccessThrowsProtocolAdapterException() + throws ProtocolAdapterException, IOException { + final DlmsDevice dlmsDevice = this.getDlmsDevice("SMR", " 5.0"); + + this.mockAlarmCosemObject( + dlmsDevice, OBIS_CODE_ALARM_REGISTER_1, DlmsObjectType.ALARM_REGISTER_1.name()); + + when(this.connectionManager.getDlmsMessageListener()).thenReturn(this.dlmsMessageListener); + when(this.connectionManager.getConnection()).thenReturn(this.dlmsConnection); + + when(this.dlmsConnection.get(this.attributeAddressArgumentCaptor.capture())) + .thenReturn(this.getResult); + when(this.getResult.getResultCode()).thenReturn(AccessResultCode.TEMPORARY_FAILURE); + + final Throwable actual = + ThrowableAssert.catchThrowable( + () -> + this.executor.execute( + this.connectionManager, dlmsDevice, this.dto, this.messageMetadata)); + assertThat(actual).isInstanceOf(ProtocolAdapterException.class); + } + + @Test + void noResultThrowsProtocolAdapterException() throws ProtocolAdapterException, IOException { + final DlmsDevice dlmsDevice = this.getDlmsDevice("SMR", " 5.0"); + this.mockAlarmCosemObject( + dlmsDevice, OBIS_CODE_ALARM_REGISTER_1, DlmsObjectType.ALARM_REGISTER_1.name()); + + when(this.connectionManager.getDlmsMessageListener()).thenReturn(this.dlmsMessageListener); + when(this.connectionManager.getConnection()).thenReturn(this.dlmsConnection); + + when(this.dlmsConnection.get(this.attributeAddressArgumentCaptor.capture())) + .thenReturn(this.getResult); + when(this.getResult.getResultData()).thenReturn(null); + when(this.getResult.getResultCode()).thenReturn(AccessResultCode.SUCCESS); + + final Throwable actual = + ThrowableAssert.catchThrowable( + () -> + this.executor.execute( + this.connectionManager, dlmsDevice, this.dto, this.messageMetadata)); + assertThat(actual).isInstanceOf(ProtocolAdapterException.class); + } + + void setupAlarmRegister1(final DlmsDevice dlmsDevice) throws ProtocolAdapterException { + + this.mockAlarmCosemObject( + dlmsDevice, OBIS_CODE_ALARM_REGISTER_1, DlmsObjectType.ALARM_REGISTER_1.name()); + + when(this.connectionManager.getDlmsMessageListener()).thenReturn(this.dlmsMessageListener); + when(this.connectionManager.getConnection()).thenReturn(this.dlmsConnection); + } + + private void mockAlarmCosemObject( + final DlmsDevice dlmsDevice, final String obisCode, final String dlmsObjectTypeName) { + + final AttributeAddress attributeAddress = + new AttributeAddress( + InterfaceClass.REGISTER.id(), + new ObisCode(obisCode), + RegisterAttribute.VALUE.attributeId()); + + when(this.objectConfigServiceHelper.findOptionalDefaultAttributeAddress( + Protocol.forDevice(dlmsDevice), DlmsObjectType.valueOf(dlmsObjectTypeName))) + .thenReturn(Optional.of(attributeAddress)); + } + + void assertForOneRegister(final String protocol, final String protocolVersion) + throws ProtocolAdapterException, IOException { + final DlmsDevice dlmsDevice = new DlmsDevice(protocol + " " + protocolVersion + " device"); + dlmsDevice.setProtocol(protocol, protocolVersion); + + this.mockAlarmCosemObject( + dlmsDevice, OBIS_CODE_ALARM_REGISTER_1, DlmsObjectType.ALARM_REGISTER_1.name()); + + when(this.connectionManager.getDlmsMessageListener()).thenReturn(this.dlmsMessageListener); + when(this.connectionManager.getConnection()).thenReturn(this.dlmsConnection); + + when(this.dlmsConnection.get(this.attributeAddressArgumentCaptor.capture())) + .thenReturn(this.getResult); + when(this.getResult.getResultData()).thenReturn(DataObject.newUInteger32Data(0L)); + when(this.getResult.getResultCode()).thenReturn(AccessResultCode.SUCCESS); + when(this.alarmHelperService.toAlarmTypes(DlmsObjectType.ALARM_REGISTER_1, 0L)) + .thenReturn(this.getAlarmRegister1()); + + this.executor.execute(this.connectionManager, dlmsDevice, this.dto, this.messageMetadata); + + this.assertValuesAttributeAddresses(this.attributeAddressArgumentCaptor.getAllValues()); + verify(this.dlmsConnection, never()).set(any(SetParameter.class)); + verify(this.dlmsConnection, never()).action(any(MethodParameter.class)); + } + + void assertForTwoRegisters(final String protocol, final String protocolVersion) + throws ProtocolAdapterException, IOException { + final DlmsDevice dlmsDevice = new DlmsDevice(protocol + " " + protocolVersion + " device"); + dlmsDevice.setProtocol(protocol, protocolVersion); + + this.mockAlarmCosemObject( + dlmsDevice, OBIS_CODE_ALARM_REGISTER_1, DlmsObjectType.ALARM_REGISTER_1.name()); + + this.mockAlarmCosemObject( + dlmsDevice, OBIS_CODE_ALARM_REGISTER_2, DlmsObjectType.ALARM_REGISTER_2.name()); + + when(this.connectionManager.getDlmsMessageListener()).thenReturn(this.dlmsMessageListener); + when(this.connectionManager.getConnection()).thenReturn(this.dlmsConnection); + + when(this.dlmsConnection.get(this.attributeAddressArgumentCaptor.capture())) + .thenReturn(this.getResult); + when(this.getResult.getResultData()).thenReturn(DataObject.newUInteger32Data(0L)); + when(this.getResult.getResultCode()).thenReturn(AccessResultCode.SUCCESS); + when(this.alarmHelperService.toAlarmTypes(DlmsObjectType.ALARM_REGISTER_1, 0L)) + .thenReturn(this.getAlarmRegister1()); + when(this.alarmHelperService.toAlarmTypes(DlmsObjectType.ALARM_REGISTER_2, 0L)) + .thenReturn(this.getAlarmRegister2()); + + this.executor.execute(this.connectionManager, dlmsDevice, this.dto, this.messageMetadata); + + this.assertValuesAttributeAddresses(this.attributeAddressArgumentCaptor.getAllValues()); + verify(this.dlmsConnection, never()).set(any(SetParameter.class)); + verify(this.dlmsConnection, never()).action(any(MethodParameter.class)); + } + + private void assertValuesAttributeAddresses(final List attributes) { + final List obisCodeAlarmRegisterList = new ArrayList<>(); + obisCodeAlarmRegisterList.add(OBIS_CODE_ALARM_REGISTER_1); + obisCodeAlarmRegisterList.add(OBIS_CODE_ALARM_REGISTER_2); + for (int i = 0; i < attributes.size(); i++) { + final AttributeAddress attributeAddress = attributes.get(i); + assertThat(attributeAddress.getInstanceId().asDecimalString()) + .isEqualTo(obisCodeAlarmRegisterList.get(i)); + assertThat(attributeAddress.getClassId()).isEqualTo(CLASS_ID_READ_ALARM_REGISTER); + } + } + + private Set getAlarmRegister1() { + final Set alarmTypesRegister1 = new HashSet<>(); + alarmTypesRegister1.add(AlarmTypeDto.CLOCK_INVALID); + alarmTypesRegister1.add(AlarmTypeDto.PROGRAM_MEMORY_ERROR); + alarmTypesRegister1.add(AlarmTypeDto.WATCHDOG_ERROR); + alarmTypesRegister1.add(AlarmTypeDto.COMMUNICATION_ERROR_M_BUS_CHANNEL_1); + alarmTypesRegister1.add(AlarmTypeDto.FRAUD_ATTEMPT_M_BUS_CHANNEL_1); + alarmTypesRegister1.add(AlarmTypeDto.NEW_M_BUS_DEVICE_DISCOVERED_CHANNEL_1); + alarmTypesRegister1.add(AlarmTypeDto.PHASE_OUTAGE_TEST_INDICATION); + return alarmTypesRegister1; + } + + private Set getAlarmRegister2() { + final Set alarmTypesRegister2 = new HashSet<>(); + alarmTypesRegister2.add(AlarmTypeDto.VOLTAGE_SAG_IN_PHASE_DETECTED_L1); + alarmTypesRegister2.add(AlarmTypeDto.VOLTAGE_SAG_IN_PHASE_DETECTED_L2); + alarmTypesRegister2.add(AlarmTypeDto.VOLTAGE_SAG_IN_PHASE_DETECTED_L3); + alarmTypesRegister2.add(AlarmTypeDto.VOLTAGE_SWELL_IN_PHASE_DETECTED_L1); + alarmTypesRegister2.add(AlarmTypeDto.VOLTAGE_SWELL_IN_PHASE_DETECTED_L2); + alarmTypesRegister2.add(AlarmTypeDto.VOLTAGE_SWELL_IN_PHASE_DETECTED_L3); + return alarmTypesRegister2; + } + + private DlmsDevice getDlmsDevice(final String protocol, final String protocolVersion) { + return new DlmsDevice(protocol + " " + protocolVersion + " device"); + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/SetAlarmNotificationsCommandExecutorRegister3Test.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/SetAlarmNotificationsCommandExecutorRegister3Test.java index 11b199e3746..9319799a132 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/SetAlarmNotificationsCommandExecutorRegister3Test.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/SetAlarmNotificationsCommandExecutorRegister3Test.java @@ -4,37 +4,45 @@ package org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.alarm; -import static java.util.stream.Collectors.toList; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; +import java.util.Optional; import java.util.Set; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; import org.openmuc.jdlms.AccessResultCode; import org.openmuc.jdlms.AttributeAddress; +import org.openmuc.jdlms.ObisCode; import org.openmuc.jdlms.SetParameter; import org.openmuc.jdlms.datatypes.DataObject; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.CommandExecutor; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectConfigConfiguration; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectConfigService; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.stub.DlmsConnectionManagerStub; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.stub.DlmsConnectionStub; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.DlmsHelper; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.ObjectConfigServiceHelper; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDevice; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.Protocol; import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionManager; +import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; +import org.opensmartgridplatform.dlms.interfaceclass.InterfaceClass; +import org.opensmartgridplatform.dlms.interfaceclass.attribute.RegisterAttribute; +import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; import org.opensmartgridplatform.dto.valueobjects.smartmetering.AlarmNotificationDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.AlarmNotificationsDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.AlarmTypeDto; import org.opensmartgridplatform.shared.exceptionhandling.OsgpException; import org.opensmartgridplatform.shared.infra.jms.MessageMetadata; +@ExtendWith(MockitoExtension.class) class SetAlarmNotificationsCommandExecutorRegister3Test { private CommandExecutor executor; private List setParametersReceived; @@ -42,17 +50,18 @@ class SetAlarmNotificationsCommandExecutorRegister3Test { private MessageMetadata messageMetadata; private DlmsConnectionStub conn; + private static final int DEFAULT_ATTRIBUTE_ID = 2; + private static final String OBIS_CODE_ALARM_FILTER_1 = "0.0.97.98.10.255"; + private static final String OBIS_CODE_ALARM_FILTER_2 = "0.0.97.98.11.255"; + private static final String OBIS_CODE_ALARM_FILTER_3 = "0.0.97.98.12.255"; + @Mock private ObjectConfigServiceHelper objectConfigServiceHelper; + @BeforeEach public void setUp() { this.setParametersReceived = new ArrayList<>(); this.messageMetadata = MessageMetadata.newBuilder().withCorrelationUid("123456").build(); - final DlmsObjectConfigConfiguration dlmsObjectConfigConfiguration = - new DlmsObjectConfigConfiguration(); - final DlmsObjectConfigService dlmsObjectConfigService = - new DlmsObjectConfigService( - new DlmsHelper(), dlmsObjectConfigConfiguration.getDlmsObjectConfigs()); - this.executor = new SetAlarmNotificationsCommandExecutor(dlmsObjectConfigService); + this.executor = new SetAlarmNotificationsCommandExecutor(this.objectConfigServiceHelper); this.conn = new DlmsConnectionStub() { @@ -85,12 +94,14 @@ void testSetSettingEnabledRegisterAlarmRegister3( final long expectedValue, final String alarmTypesInput) throws OsgpException { final DlmsDevice device = this.createDevice(Protocol.SMR_5_5); + this.setUpAttributeAddress(device); + // Set the return value for alarm register 3 to 0 (no alarms set): this.conn.addReturnValue( new AttributeAddress(1, "0.0.97.98.12.255", 2), DataObject.newInteger32Data(0)); final List alarmTypes = - Arrays.stream(alarmTypesInput.split(";")).map(AlarmTypeDto::valueOf).collect(toList()); + Arrays.stream(alarmTypesInput.split(";")).map(AlarmTypeDto::valueOf).toList(); final AccessResultCode res = this.execute( device, @@ -98,7 +109,7 @@ void testSetSettingEnabledRegisterAlarmRegister3( .map(alarmType -> new AlarmNotificationDto(alarmType, true)) .toArray(AlarmNotificationDto[]::new)); assertThat(res).isEqualTo(AccessResultCode.SUCCESS); - assertThat(this.setParametersReceived.size()).isEqualTo(1); + assertThat(this.setParametersReceived).hasSize(1); assertThat((long) this.setParametersReceived.get(0).getData().getValue()) .isEqualTo(expectedValue); } @@ -113,12 +124,14 @@ void testSetSettingDisabledRegisterAlarmRegister3( final long expectedValue, final String alarmTypesInput) throws OsgpException { final DlmsDevice device = this.createDevice(Protocol.SMR_5_5); + this.setUpAttributeAddress(device); + // Set the return value for alarm register 3 to 3 (all alarms (LAST_GASP & LAST_GASP_TEST) set) this.conn.addReturnValue( new AttributeAddress(1, "0.0.97.98.12.255", 2), DataObject.newInteger32Data(3)); final List alarmTypes = - Arrays.stream(alarmTypesInput.split(";")).map(AlarmTypeDto::valueOf).collect(toList()); + Arrays.stream(alarmTypesInput.split(";")).map(AlarmTypeDto::valueOf).toList(); final AccessResultCode res = this.execute( device, @@ -126,7 +139,7 @@ void testSetSettingDisabledRegisterAlarmRegister3( .map(alarmType -> new AlarmNotificationDto(alarmType, false)) .toArray(AlarmNotificationDto[]::new)); assertThat(res).isEqualTo(AccessResultCode.SUCCESS); - assertThat(this.setParametersReceived.size()).isEqualTo(1); + assertThat(this.setParametersReceived).hasSize(1); assertThat((long) this.setParametersReceived.get(0).getData().getValue()) .isEqualTo(expectedValue); } @@ -135,6 +148,8 @@ void testSetSettingDisabledRegisterAlarmRegister3( void testSetSettingThatIsAlreadySetInAlarmRegister3() throws OsgpException { final DlmsDevice device = this.createDevice(Protocol.SMR_5_5); + this.setUpAttributeAddress(device); + // Set the return value for alarm register 3 to 3 (all alarms (LAST_GASP & LAST_GASP_TEST) set) this.conn.addReturnValue( new AttributeAddress(1, "0.0.97.98.12.255", 2), DataObject.newInteger32Data(3)); @@ -149,13 +164,15 @@ void testSetSettingThatIsAlreadySetInAlarmRegister3() throws OsgpException { final AccessResultCode res = this.execute(device, alarmNotificationDtos); assertThat(res).isEqualTo(AccessResultCode.SUCCESS); // Since nothing changed, not a single message should have been sent to the meter. - assertThat(this.setParametersReceived.size()).isZero(); + assertThat(this.setParametersReceived).isEmpty(); } @Test void testSetDisabledThatIsAlreadySetDisabledInAlarmRegister3() throws OsgpException { final DlmsDevice device = this.createDevice(Protocol.SMR_5_5); + this.setUpAttributeAddress(device); + // Set the return value for alarm register 3 to 0 (no alarms set): this.conn.addReturnValue( new AttributeAddress(1, "0.0.97.98.12.255", 2), DataObject.newInteger32Data(0)); @@ -170,7 +187,7 @@ void testSetDisabledThatIsAlreadySetDisabledInAlarmRegister3() throws OsgpExcept final AccessResultCode res = this.execute(device, alarmNotificationDtos); assertThat(res).isEqualTo(AccessResultCode.SUCCESS); // Since nothing changed, not a single message should have been sent to the meter. - assertThat(this.setParametersReceived.size()).isZero(); + assertThat(this.setParametersReceived).isEmpty(); } private AccessResultCode execute( @@ -189,4 +206,31 @@ private DlmsDevice createDevice(final Protocol protocol) { return device; } + + private void setUpAttributeAddress(final DlmsDevice dlmsDevice) throws ProtocolAdapterException { + + when(this.objectConfigServiceHelper.findAttributeAddress( + dlmsDevice, + Protocol.forDevice(dlmsDevice), + DlmsObjectType.valueOf(DlmsObjectType.ALARM_FILTER_1.name()), + null, + DEFAULT_ATTRIBUTE_ID)) + .thenReturn(this.getAttributeAddress(OBIS_CODE_ALARM_FILTER_1)); + + when(this.objectConfigServiceHelper.findOptionalDefaultAttributeAddress( + Protocol.forDevice(dlmsDevice), + DlmsObjectType.valueOf(DlmsObjectType.ALARM_FILTER_2.name()))) + .thenReturn(Optional.of(this.getAttributeAddress(OBIS_CODE_ALARM_FILTER_2))); + + when(this.objectConfigServiceHelper.findOptionalDefaultAttributeAddress( + Protocol.forDevice(dlmsDevice), DlmsObjectType.ALARM_FILTER_3)) + .thenReturn(Optional.of(this.getAttributeAddress(OBIS_CODE_ALARM_FILTER_3))); + } + + private AttributeAddress getAttributeAddress(final String obisCode) { + return new AttributeAddress( + InterfaceClass.REGISTER.id(), + new ObisCode(obisCode), + RegisterAttribute.VALUE.attributeId()); + } } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/SetAlarmNotificationsCommandExecutorTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/SetAlarmNotificationsCommandExecutorTest.java index 0a3db560332..631d3d212a5 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/SetAlarmNotificationsCommandExecutorTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/SetAlarmNotificationsCommandExecutorTest.java @@ -4,37 +4,45 @@ package org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.alarm; -import static java.util.stream.Collectors.toList; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; +import java.util.Optional; import java.util.Set; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; import org.openmuc.jdlms.AccessResultCode; import org.openmuc.jdlms.AttributeAddress; +import org.openmuc.jdlms.ObisCode; import org.openmuc.jdlms.SetParameter; import org.openmuc.jdlms.datatypes.DataObject; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.CommandExecutor; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectConfigConfiguration; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectConfigService; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.stub.DlmsConnectionManagerStub; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.stub.DlmsConnectionStub; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.DlmsHelper; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.ObjectConfigServiceHelper; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDevice; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.Protocol; import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionManager; +import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; +import org.opensmartgridplatform.dlms.interfaceclass.InterfaceClass; +import org.opensmartgridplatform.dlms.interfaceclass.attribute.RegisterAttribute; +import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; import org.opensmartgridplatform.dto.valueobjects.smartmetering.AlarmNotificationDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.AlarmNotificationsDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.AlarmTypeDto; import org.opensmartgridplatform.shared.exceptionhandling.OsgpException; import org.opensmartgridplatform.shared.infra.jms.MessageMetadata; +@ExtendWith(MockitoExtension.class) class SetAlarmNotificationsCommandExecutorTest { private CommandExecutor executor; private List setParametersReceived; @@ -42,17 +50,18 @@ class SetAlarmNotificationsCommandExecutorTest { private MessageMetadata messageMetadata; private DlmsConnectionStub conn; + private static final String OBIS_CODE_ALARM_FILTER_1 = "0.0.97.98.10.255"; + private static final String OBIS_CODE_ALARM_FILTER_2 = "0.0.97.98.11.255"; + private static final int DEFAULT_ATTRIBUTE_ID = 2; + + @Mock private ObjectConfigServiceHelper objectConfigServiceHelper; + @BeforeEach public void setUp() { this.setParametersReceived = new ArrayList<>(); this.messageMetadata = MessageMetadata.newBuilder().withCorrelationUid("123456").build(); - final DlmsObjectConfigConfiguration dlmsObjectConfigConfiguration = - new DlmsObjectConfigConfiguration(); - final DlmsObjectConfigService dlmsObjectConfigService = - new DlmsObjectConfigService( - new DlmsHelper(), dlmsObjectConfigConfiguration.getDlmsObjectConfigs()); - this.executor = new SetAlarmNotificationsCommandExecutor(dlmsObjectConfigService); + this.executor = new SetAlarmNotificationsCommandExecutor(this.objectConfigServiceHelper); this.conn = new DlmsConnectionStub() { @@ -74,6 +83,13 @@ public AccessResultCode set(final SetParameter setParameter) { @Test void testSetSettingThatIsAlreadySet() throws OsgpException { final DlmsDevice device = this.createDevice(Protocol.SMR_5_0_0); + when(this.objectConfigServiceHelper.findAttributeAddress( + device, + Protocol.forDevice(device), + DlmsObjectType.valueOf(DlmsObjectType.ALARM_FILTER_1.name()), + null, + DEFAULT_ATTRIBUTE_ID)) + .thenReturn(this.getAttributeAddress(OBIS_CODE_ALARM_FILTER_1)); // Setting notifications that are not different from what is on the meter already, // should always be successful. @@ -81,18 +97,25 @@ void testSetSettingThatIsAlreadySet() throws OsgpException { this.execute(device, new AlarmNotificationDto(AlarmTypeDto.REPLACE_BATTERY, true)); assertThat(res).isEqualTo(AccessResultCode.SUCCESS); // Since nothing changed, not a single message should have been sent to the meter. - assertThat(this.setParametersReceived.size()).isZero(); + assertThat(this.setParametersReceived).isEmpty(); } @Test void testSetSettingEnabled() throws OsgpException { final DlmsDevice device = this.createDevice(Protocol.SMR_5_0_0); + when(this.objectConfigServiceHelper.findAttributeAddress( + device, + Protocol.forDevice(device), + DlmsObjectType.valueOf(DlmsObjectType.ALARM_FILTER_1.name()), + null, + DEFAULT_ATTRIBUTE_ID)) + .thenReturn(this.getAttributeAddress(OBIS_CODE_ALARM_FILTER_1)); // Now we enable something: CLOCK_INVALID to enabled. final AccessResultCode res = this.execute(device, new AlarmNotificationDto(AlarmTypeDto.CLOCK_INVALID, true)); assertThat(res).isEqualTo(AccessResultCode.SUCCESS); - assertThat(this.setParametersReceived.size()).isEqualTo(1); + assertThat(this.setParametersReceived).hasSize(1); // Expecting 11 (0b1011). assertThat((long) this.setParametersReceived.get(0).getData().getValue()).isEqualTo(11); } @@ -111,13 +134,14 @@ void testSetSettingEnabled() throws OsgpException { void testSetSettingEnabledRegisterAlarmRegister2( final long expectedValue, final String alarmTypesInput) throws OsgpException { final DlmsDevice device = this.createDevice(Protocol.SMR_5_2); + this.setUpAttributeAddress(device); // Set the return value for alarm register 2 to 0 (no alarms set): this.conn.addReturnValue( new AttributeAddress(1, "0.0.97.98.11.255", 2), DataObject.newInteger32Data(0)); final List alarmTypes = - Arrays.stream(alarmTypesInput.split(";")).map(AlarmTypeDto::valueOf).collect(toList()); + Arrays.stream(alarmTypesInput.split(";")).map(AlarmTypeDto::valueOf).toList(); final AccessResultCode res = this.execute( device, @@ -125,7 +149,7 @@ void testSetSettingEnabledRegisterAlarmRegister2( .map(alarmType -> new AlarmNotificationDto(alarmType, true)) .toArray(AlarmNotificationDto[]::new)); assertThat(res).isEqualTo(AccessResultCode.SUCCESS); - assertThat(this.setParametersReceived.size()).isEqualTo(1); + assertThat(this.setParametersReceived).hasSize(1); assertThat((long) this.setParametersReceived.get(0).getData().getValue()) .isEqualTo(expectedValue); } @@ -144,13 +168,14 @@ void testSetSettingEnabledRegisterAlarmRegister2( void testSetSettingDisabledRegisterAlarmRegister2( final long expectedValue, final String alarmTypesInput) throws OsgpException { final DlmsDevice device = this.createDevice(Protocol.SMR_5_2); + this.setUpAttributeAddress(device); // Set the return value for alarm register 2 to 3F (all alarms set): this.conn.addReturnValue( new AttributeAddress(1, "0.0.97.98.11.255", 2), DataObject.newInteger32Data(0x3F)); final List alarmTypes = - Arrays.stream(alarmTypesInput.split(";")).map(AlarmTypeDto::valueOf).collect(toList()); + Arrays.stream(alarmTypesInput.split(";")).map(AlarmTypeDto::valueOf).toList(); final AccessResultCode res = this.execute( device, @@ -158,7 +183,7 @@ void testSetSettingDisabledRegisterAlarmRegister2( .map(alarmType -> new AlarmNotificationDto(alarmType, false)) .toArray(AlarmNotificationDto[]::new)); assertThat(res).isEqualTo(AccessResultCode.SUCCESS); - assertThat(this.setParametersReceived.size()).isEqualTo(1); + assertThat(this.setParametersReceived).hasSize(1); assertThat((long) this.setParametersReceived.get(0).getData().getValue()) .isEqualTo(expectedValue); } @@ -166,6 +191,7 @@ void testSetSettingDisabledRegisterAlarmRegister2( @Test void testSetSettingThatIsAlreadySetInAlarmRegister2() throws OsgpException { final DlmsDevice device = this.createDevice(Protocol.SMR_5_2); + this.setUpAttributeAddress(device); // Set the return value for alarm register 2 to 3F (all alarms set): this.conn.addReturnValue( @@ -179,12 +205,19 @@ void testSetSettingThatIsAlreadySetInAlarmRegister2() throws OsgpException { new AlarmNotificationDto(AlarmTypeDto.VOLTAGE_SWELL_IN_PHASE_DETECTED_L3, true)); assertThat(res).isEqualTo(AccessResultCode.SUCCESS); // Since nothing changed, not a single message should have been sent to the meter. - assertThat(this.setParametersReceived.size()).isZero(); + assertThat(this.setParametersReceived).isEmpty(); } @Test void testSetSettingEnabledAndDisabled() throws OsgpException { final DlmsDevice device = this.createDevice(Protocol.SMR_5_0_0); + when(this.objectConfigServiceHelper.findAttributeAddress( + device, + Protocol.forDevice(device), + DlmsObjectType.valueOf(DlmsObjectType.ALARM_FILTER_1.name()), + null, + DEFAULT_ATTRIBUTE_ID)) + .thenReturn(this.getAttributeAddress(OBIS_CODE_ALARM_FILTER_1)); // Both enable and disable in one call: // CLOCK_INVALID to enabled and REPLACE_BATTERY to disabled. @@ -194,7 +227,7 @@ void testSetSettingEnabledAndDisabled() throws OsgpException { new AlarmNotificationDto(AlarmTypeDto.CLOCK_INVALID, true), new AlarmNotificationDto(AlarmTypeDto.REPLACE_BATTERY, false)); assertThat(res).isEqualTo(AccessResultCode.SUCCESS); - assertThat(this.setParametersReceived.size()).isEqualTo(1); + assertThat(this.setParametersReceived).hasSize(1); // Expecting 9 (0b1001). assertThat((long) this.setParametersReceived.get(0).getData().getValue()).isEqualTo(9); } @@ -206,9 +239,34 @@ private AccessResultCode execute( new HashSet<>(Arrays.asList(alarmNotificationDtos)); final AlarmNotificationsDto alarmNotificationsDto = new AlarmNotificationsDto(alarmNotificationDtoSet); + return this.executor.execute(this.connMgr, device, alarmNotificationsDto, this.messageMetadata); } + private void setUpAttributeAddress(final DlmsDevice dlmsDevice) throws ProtocolAdapterException { + + when(this.objectConfigServiceHelper.findAttributeAddress( + dlmsDevice, + Protocol.forDevice(dlmsDevice), + DlmsObjectType.valueOf(DlmsObjectType.ALARM_FILTER_1.name()), + null, + DEFAULT_ATTRIBUTE_ID)) + .thenReturn(this.getAttributeAddress(OBIS_CODE_ALARM_FILTER_1)); + + when(this.objectConfigServiceHelper.findOptionalDefaultAttributeAddress( + Protocol.forDevice(dlmsDevice), + DlmsObjectType.valueOf(DlmsObjectType.ALARM_FILTER_2.name()))) + .thenReturn(Optional.of(this.getAttributeAddress(OBIS_CODE_ALARM_FILTER_2))); + } + + private AttributeAddress getAttributeAddress(final String obisCode) { + + return new AttributeAddress( + InterfaceClass.REGISTER.id(), + new ObisCode(obisCode), + RegisterAttribute.VALUE.attributeId()); + } + private DlmsDevice createDevice(final Protocol protocol) { final DlmsDevice device = new DlmsDevice(); device.setProtocol(protocol); diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/TestAlarmSchedulerCommandExecutorTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/TestAlarmSchedulerCommandExecutorTest.java index 7fb51d669e5..e48278d74fd 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/TestAlarmSchedulerCommandExecutorTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/alarm/TestAlarmSchedulerCommandExecutorTest.java @@ -32,14 +32,16 @@ import org.openmuc.jdlms.datatypes.CosemDate; import org.openmuc.jdlms.datatypes.CosemTime; import org.openmuc.jdlms.datatypes.DataObject; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectConfigService; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.model.DlmsObject; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.stub.DlmsConnectionManagerStub; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.stub.DlmsConnectionStub; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.DateTimeParserUtil; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.ObjectConfigServiceHelper; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDevice; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.Protocol; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; +import org.opensmartgridplatform.dlms.interfaceclass.InterfaceClass; import org.opensmartgridplatform.dlms.interfaceclass.attribute.SingleActionScheduleAttribute; +import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; import org.opensmartgridplatform.dto.valueobjects.smartmetering.TestAlarmSchedulerRequestDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.TestAlarmTypeDto; import org.opensmartgridplatform.shared.infra.jms.MessageMetadata; @@ -59,11 +61,7 @@ class TestAlarmSchedulerCommandExecutorTest { @Mock private MessageMetadata messageMetadata; - @Mock private DlmsObjectConfigService dlmsObjectConfigService; - - @Mock private DlmsObject dlmsObject; - - @Mock private ObisCode obisCode; + @Mock private ObjectConfigServiceHelper objectConfigServiceHelper; private DlmsConnectionManagerStub connectionManagerStub; private DlmsConnectionStub connectionStub; @@ -189,14 +187,24 @@ private void setupAlarmSchedulerRequest(final String alarmType, final Date date) private void setupConfigService(final String alarmType, final String obisCodeString) throws ProtocolAdapterException { - when(this.dlmsObjectConfigService.getDlmsObject( + final AttributeAddress attributeAddress = + new AttributeAddress( + InterfaceClass.SINGLE_ACTION_SCHEDULE.id(), + new ObisCode(obisCodeString), + SingleActionScheduleAttribute.EXECUTION_TIME.attributeId()); + + when(this.objectConfigServiceHelper.findAttributeAddress( this.device, - TestAlarmSchedulerCommandExecutor.toAlarmObjectType( - TestAlarmTypeDto.valueOf(alarmType)))) - .thenReturn(this.dlmsObject); + Protocol.OTHER_PROTOCOL, + toAlarmObjectType(TestAlarmTypeDto.valueOf(alarmType)), + null, + SingleActionScheduleAttribute.EXECUTION_TIME.attributeId())) + .thenReturn(attributeAddress); + } - when(this.obisCode.toString()).thenReturn(obisCodeString); - when(this.dlmsObject.getClassId()).thenReturn(SINGLE_ACTION_CLASS_ID); - when(this.dlmsObject.getObisCode()).thenReturn(this.obisCode); + protected static DlmsObjectType toAlarmObjectType(final TestAlarmTypeDto alarmTypeDto) { + return TestAlarmTypeDto.PARTIAL_POWER_OUTAGE.equals(alarmTypeDto) + ? DlmsObjectType.PHASE_OUTAGE_TEST + : DlmsObjectType.LAST_GASP_TEST; } } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/GetConfigurationObjectCommandExecutorTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/GetConfigurationObjectCommandExecutorTest.java index d4d3e08fdbd..19563f7aed8 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/GetConfigurationObjectCommandExecutorTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/GetConfigurationObjectCommandExecutorTest.java @@ -7,8 +7,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.when; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; @@ -22,7 +23,7 @@ import org.opensmartgridplatform.shared.infra.jms.MessageMetadata; @ExtendWith(MockitoExtension.class) -public class GetConfigurationObjectCommandExecutorTest { +class GetConfigurationObjectCommandExecutorTest { @InjectMocks private GetConfigurationObjectCommandExecutor instance; @Mock private ProtocolServiceLookup protocolServiceLookup; @@ -30,18 +31,19 @@ public class GetConfigurationObjectCommandExecutorTest { @Mock private ConfigurationObjectDto configurationObjectDto; @Mock private GetConfigurationObjectService getService; - @Test - public void execute() throws ProtocolAdapterException { + @ParameterizedTest + @EnumSource(value = Protocol.class) + void execute(final Protocol protocol) throws ProtocolAdapterException { // SETUP final DlmsDevice device = new DlmsDevice(); - final Protocol protocol = Protocol.DSMR_4_2_2; final MessageMetadata messageMetadata = MessageMetadata.newBuilder().withCorrelationUid("123456").build(); device.setProtocol(protocol); when(this.protocolServiceLookup.lookupGetService(protocol)).thenReturn(this.getService); - when(this.getService.getConfigurationObject(this.conn)).thenReturn(this.configurationObjectDto); + when(this.getService.getConfigurationObject(this.conn, protocol)) + .thenReturn(this.configurationObjectDto); // CALL final ConfigurationObjectDto result = diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/SetConfigurationObjectCommandExecutorDsmr4IT.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/SetConfigurationObjectCommandExecutorDsmr4IT.java index b4aeb233a67..5c7c81e2c5d 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/SetConfigurationObjectCommandExecutorDsmr4IT.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/SetConfigurationObjectCommandExecutorDsmr4IT.java @@ -13,6 +13,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.openmuc.jdlms.AccessResultCode; import org.openmuc.jdlms.SetParameter; @@ -23,6 +24,7 @@ import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.configuration.service.SetConfigurationObjectService; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.configuration.service.SetConfigurationObjectServiceDsmr4; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.DlmsHelper; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.ObjectConfigServiceHelper; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDevice; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.Protocol; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; @@ -31,24 +33,26 @@ import org.opensmartgridplatform.dto.valueobjects.smartmetering.GprsOperationModeTypeDto; @ExtendWith(MockitoExtension.class) -public class SetConfigurationObjectCommandExecutorDsmr4IT +class SetConfigurationObjectCommandExecutorDsmr4IT extends SetConfigurationObjectCommandExecutorITBase { private static final int INDEX_OF_GPRS_OPERATION_MODE = 0; private static final int INDEX_OF_CONFIGURATION_FLAGS = 1; + @Mock private ObjectConfigServiceHelper objectConfigServiceHelper; + @BeforeEach - public void setUp() throws IOException { + void setUp() throws IOException { final DlmsHelper dlmsHelper = new DlmsHelper(); final GetConfigurationObjectService getService = - new GetConfigurationObjectServiceDsmr4(dlmsHelper); + new GetConfigurationObjectServiceDsmr4(dlmsHelper, this.objectConfigServiceHelper); final SetConfigurationObjectService setService = - new SetConfigurationObjectServiceDsmr4(dlmsHelper); + new SetConfigurationObjectServiceDsmr4(dlmsHelper, this.objectConfigServiceHelper); super.setUp(getService, setService); } @Test - public void execute() throws IOException, ProtocolAdapterException { + void execute() throws IOException, ProtocolAdapterException { // SETUP // configurationToSet: 0111-----1------ @@ -60,15 +64,15 @@ public void execute() throws IOException, ProtocolAdapterException { this.createFlagDto(ConfigurationFlagTypeDto.DISCOVER_ON_POWER_ON, true), this.createFlagDto(ConfigurationFlagTypeDto.DYNAMIC_MBUS_ADDRESS, true), this.createFlagDto(ConfigurationFlagTypeDto.PO_ENABLE, true), - this.createFlagDto(ConfigurationFlagTypeDto.HLS_5_ON_PO_ENABLE, true)); + this.createFlagDto(ConfigurationFlagTypeDto.HLS_5_ON_P0_ENABLE, true)); // flagsOnDevice: 1000101010000000 final byte[] flagsOnDevice = this.createFlagBytes( ConfigurationFlagTypeDto.DISCOVER_ON_OPEN_COVER, - ConfigurationFlagTypeDto.HLS_3_ON_P_3_ENABLE, - ConfigurationFlagTypeDto.HLS_5_ON_P_3_ENABLE, - ConfigurationFlagTypeDto.HLS_4_ON_PO_ENABLE); + ConfigurationFlagTypeDto.HLS_3_ON_P3_ENABLE, + ConfigurationFlagTypeDto.HLS_5_ON_P3_ENABLE, + ConfigurationFlagTypeDto.HLS_4_ON_P0_ENABLE); // result of merging configurationToSet and flagsOnDevice final byte firstExpectedByte = this.asByte("01111010"); diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/SetConfigurationObjectCommandExecutorSmr5IT.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/SetConfigurationObjectCommandExecutorSmr5IT.java index 336c1498b57..ed29e517c53 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/SetConfigurationObjectCommandExecutorSmr5IT.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/SetConfigurationObjectCommandExecutorSmr5IT.java @@ -12,6 +12,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.openmuc.jdlms.AccessResultCode; import org.openmuc.jdlms.SetParameter; @@ -22,6 +23,7 @@ import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.configuration.service.SetConfigurationObjectService; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.configuration.service.SetConfigurationObjectServiceSmr5; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.DlmsHelper; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.ObjectConfigServiceHelper; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDevice; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.Protocol; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; @@ -30,21 +32,23 @@ import org.opensmartgridplatform.dto.valueobjects.smartmetering.GprsOperationModeTypeDto; @ExtendWith(MockitoExtension.class) -public class SetConfigurationObjectCommandExecutorSmr5IT +class SetConfigurationObjectCommandExecutorSmr5IT extends SetConfigurationObjectCommandExecutorITBase { + @Mock private ObjectConfigServiceHelper objectConfigServiceHelper; + @BeforeEach - public void setUp() throws IOException { + void setUp() throws IOException { final DlmsHelper dlmsHelper = new DlmsHelper(); final GetConfigurationObjectService getService = - new GetConfigurationObjectServiceSmr5(dlmsHelper); + new GetConfigurationObjectServiceSmr5(dlmsHelper, this.objectConfigServiceHelper); final SetConfigurationObjectService setService = - new SetConfigurationObjectServiceSmr5(dlmsHelper); + new SetConfigurationObjectServiceSmr5(dlmsHelper, this.objectConfigServiceHelper); super.setUp(getService, setService); } @Test - public void execute() throws IOException, ProtocolAdapterException { + void execute() throws IOException, ProtocolAdapterException { // SETUP // configurationToSet: ------1---10101- @@ -53,7 +57,7 @@ public void execute() throws IOException, ProtocolAdapterException { final ConfigurationObjectDto configurationToSet = this.createConfigurationObjectDto( gprsMode, - this.createFlagDto(ConfigurationFlagTypeDto.HLS_5_ON_P_3_ENABLE, true), + this.createFlagDto(ConfigurationFlagTypeDto.HLS_5_ON_P3_ENABLE, true), this.createFlagDto(ConfigurationFlagTypeDto.DIRECT_ATTACH_AT_POWER_ON, true), this.createFlagDto(ConfigurationFlagTypeDto.HLS_6_ON_P3_ENABLE, false), this.createFlagDto(ConfigurationFlagTypeDto.HLS_7_ON_P3_ENABLE, true), @@ -63,7 +67,7 @@ public void execute() throws IOException, ProtocolAdapterException { // flagsOnDevice: 0000000001110100 final byte[] flagsOnDevice = this.createFlagBytes( - ConfigurationFlagTypeDto.HLS_5_ON_PO_ENABLE, + ConfigurationFlagTypeDto.HLS_5_ON_P0_ENABLE, ConfigurationFlagTypeDto.DIRECT_ATTACH_AT_POWER_ON, ConfigurationFlagTypeDto.HLS_6_ON_P3_ENABLE, ConfigurationFlagTypeDto.HLS_6_ON_P0_ENABLE); diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/SetConfigurationObjectCommandExecutorTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/SetConfigurationObjectCommandExecutorTest.java index 00f6a256397..bc929e8a39b 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/SetConfigurationObjectCommandExecutorTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/SetConfigurationObjectCommandExecutorTest.java @@ -7,8 +7,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.when; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; @@ -24,7 +25,7 @@ import org.opensmartgridplatform.shared.infra.jms.MessageMetadata; @ExtendWith(MockitoExtension.class) -public class SetConfigurationObjectCommandExecutorTest { +class SetConfigurationObjectCommandExecutorTest { @InjectMocks private SetConfigurationObjectCommandExecutor instance; @Mock private ProtocolServiceLookup protocolServiceLookup; @@ -35,23 +36,26 @@ public class SetConfigurationObjectCommandExecutorTest { @Mock private ConfigurationObjectDto configurationToSet; - @Test - public void execute() throws ProtocolAdapterException { + @ParameterizedTest + @EnumSource( + value = Protocol.class, + names = {"DSMR_4_2_2", "SMR_5_0_0"}) + void execute(final Protocol protocol) throws ProtocolAdapterException { // SETUP final DlmsDevice device = new DlmsDevice(); - final Protocol protocol = Protocol.DSMR_4_2_2; final MessageMetadata messageMetadata = MessageMetadata.newBuilder().withCorrelationUid("123456").build(); device.setProtocol(protocol); when(this.protocolServiceLookup.lookupGetService(protocol)).thenReturn(this.getService); - when(this.getService.getConfigurationObject(this.conn)).thenReturn(this.configurationOnDevice); + when(this.getService.getConfigurationObject(this.conn, protocol)) + .thenReturn(this.configurationOnDevice); when(this.protocolServiceLookup.lookupSetService(protocol)).thenReturn(this.setService); final AccessResultCode accessResultCode = AccessResultCode.SUCCESS; when(this.setService.setConfigurationObject( - this.conn, this.configurationToSet, this.configurationOnDevice)) + this.conn, this.configurationToSet, this.configurationOnDevice, protocol)) .thenReturn(accessResultCode); // CALL diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/SetRandomisationSettingsCommandExecutorTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/SetRandomisationSettingsCommandExecutorTest.java index 3047034b986..672af7ab72a 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/SetRandomisationSettingsCommandExecutorTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/SetRandomisationSettingsCommandExecutorTest.java @@ -7,15 +7,17 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; import java.io.IOException; import java.util.Arrays; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; @@ -29,12 +31,12 @@ import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.configuration.service.GetConfigurationObjectService; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.configuration.service.ProtocolServiceLookup; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.configuration.service.SetConfigurationObjectService; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectConfigService; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectType; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.ObjectConfigServiceHelper; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDevice; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.Protocol; import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionManager; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; +import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ConfigurationFlagDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ConfigurationFlagTypeDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ConfigurationFlagsDto; @@ -44,9 +46,7 @@ @ExtendWith(MockitoExtension.class) @MockitoSettings(strictness = Strictness.LENIENT) -public class SetRandomisationSettingsCommandExecutorTest { - - @Mock private DlmsObjectConfigService dlmsObjectConfigService; +class SetRandomisationSettingsCommandExecutorTest { @Mock private ProtocolServiceLookup protocolServiceLookup; @@ -54,6 +54,8 @@ public class SetRandomisationSettingsCommandExecutorTest { @Mock private SetConfigurationObjectService setConfigurationObjectService; + @Mock private ObjectConfigServiceHelper objectConfigServiceHelper; + @InjectMocks private SetRandomisationSettingsCommandExecutor executor; @Mock private DlmsConnection dlmsConnection; @@ -64,17 +66,12 @@ public class SetRandomisationSettingsCommandExecutorTest { private DlmsDevice device; private MessageMetadata messageMetadata; - @BeforeEach - public void init() throws ProtocolAdapterException, IOException { + public void init(final Protocol protocol) throws ProtocolAdapterException, IOException { - // SETUP - final Protocol smr51 = Protocol.SMR_5_1; - this.device = this.createDlmsDevice(smr51); + this.device = this.createDlmsDevice(protocol); this.messageMetadata = MessageMetadata.newBuilder().withCorrelationUid("123456").build(); - final AttributeAddress address = new AttributeAddress(1, new ObisCode("0.1.94.31.12.255"), 1); - this.dataDto = new SetRandomisationSettingsRequestDataDto(0, 1, 1, 1); final ConfigurationFlagsDto currentConfigurationFlagsDto = @@ -82,28 +79,35 @@ public void init() throws ProtocolAdapterException, IOException { final ConfigurationObjectDto currentConfigurationObjectDto = new ConfigurationObjectDto(currentConfigurationFlagsDto); - when(this.protocolServiceLookup.lookupGetService(smr51)) + when(this.protocolServiceLookup.lookupGetService(protocol)) .thenReturn(this.getConfigurationObjectService); - when(this.protocolServiceLookup.lookupSetService(smr51)) + when(this.protocolServiceLookup.lookupSetService(protocol)) .thenReturn(this.setConfigurationObjectService); - when(this.getConfigurationObjectService.getConfigurationObject(this.dlmsConnectionManager)) + when(this.getConfigurationObjectService.getConfigurationObject( + this.dlmsConnectionManager, protocol)) .thenReturn(currentConfigurationObjectDto); when(this.setConfigurationObjectService.setConfigurationObject( any(DlmsConnectionManager.class), any(ConfigurationObjectDto.class), - any(ConfigurationObjectDto.class))) + any(ConfigurationObjectDto.class), + eq(protocol))) .thenReturn(AccessResultCode.SUCCESS); - when(this.dlmsObjectConfigService.getAttributeAddress( - this.device, DlmsObjectType.RANDOMISATION_SETTINGS, null)) - .thenReturn(address); + + when(this.objectConfigServiceHelper.findOptionalDefaultAttributeAddress( + protocol, DlmsObjectType.RANDOMISATION_SETTINGS)) + .thenReturn(Optional.of(new AttributeAddress(-1, (ObisCode) null, -1))); when(this.dlmsConnectionManager.getConnection()).thenReturn(this.dlmsConnection); when(this.dlmsConnection.set(any(SetParameter.class))).thenReturn(AccessResultCode.SUCCESS); } - @Test - public void testExecuteSuccess() throws ProtocolAdapterException { + @ParameterizedTest + @EnumSource( + value = Protocol.class, + names = {"DSMR_4_2_2", "SMR_5_0_0"}) + void testExecuteSuccess(final Protocol protocol) throws ProtocolAdapterException, IOException { + this.init(protocol); // CALL final AccessResultCode resultCode = this.executor.execute( @@ -113,13 +117,20 @@ public void testExecuteSuccess() throws ProtocolAdapterException { assertThat(resultCode).isEqualTo(AccessResultCode.SUCCESS); } - @Test - public void testExecuteFailConfiguration() throws ProtocolAdapterException { + @ParameterizedTest + @EnumSource( + value = Protocol.class, + names = {"DSMR_4_2_2", "SMR_5_0_0"}) + void testExecuteFailConfiguration(final Protocol protocol) + throws ProtocolAdapterException, IOException { // SETUP + this.init(protocol); + when(this.setConfigurationObjectService.setConfigurationObject( any(DlmsConnectionManager.class), any(ConfigurationObjectDto.class), - any(ConfigurationObjectDto.class))) + any(ConfigurationObjectDto.class), + eq(protocol))) .thenReturn(AccessResultCode.OTHER_REASON); assertThatExceptionOfType(ProtocolAdapterException.class) @@ -131,11 +142,16 @@ public void testExecuteFailConfiguration() throws ProtocolAdapterException { }); } - @Test - public void testExecuteFailSetRandomisationSettings() + @ParameterizedTest + @EnumSource( + value = Protocol.class, + names = {"DSMR_4_2_2", "SMR_5_0_0"}) + void testExecuteFailSetRandomisationSettings(final Protocol protocol) throws ProtocolAdapterException, IOException { // SETUP + this.init(protocol); + when(this.dlmsConnection.set(any(SetParameter.class))) .thenReturn(AccessResultCode.OTHER_REASON); @@ -148,13 +164,18 @@ public void testExecuteFailSetRandomisationSettings() }); } - @Test - public void testUnknownAttribute() throws ProtocolAdapterException { + @ParameterizedTest + @EnumSource( + value = Protocol.class, + names = {"DSMR_4_2_2", "SMR_5_0_0"}) + void testUnknownAttribute(final Protocol protocol) throws ProtocolAdapterException, IOException { // SETUP - when(this.dlmsObjectConfigService.getAttributeAddress( - this.device, DlmsObjectType.RANDOMISATION_SETTINGS, null)) - .thenThrow(new ProtocolAdapterException("unknown")); + this.init(protocol); + + when(this.objectConfigServiceHelper.findOptionalDefaultAttributeAddress( + protocol, DlmsObjectType.RANDOMISATION_SETTINGS)) + .thenReturn(Optional.empty()); assertThatExceptionOfType(ProtocolAdapterException.class) .isThrownBy( diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/GetConfigurationObjectServiceDsmr43Test.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/GetConfigurationObjectServiceDsmr43Test.java new file mode 100644 index 00000000000..6baeb6971fc --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/GetConfigurationObjectServiceDsmr43Test.java @@ -0,0 +1,59 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.configuration.service; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.NullSource; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.DlmsHelper; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.ObjectConfigServiceHelper; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.Protocol; +import org.opensmartgridplatform.dto.valueobjects.smartmetering.ConfigurationFlagTypeDto; + +@ExtendWith(MockitoExtension.class) +class GetConfigurationObjectServiceDsmr43Test { + + private GetConfigurationObjectServiceDsmr43 instance; + + // @Mock private GetResult getResult; + @Mock private DlmsHelper dlmsHelper; + + @Mock private ObjectConfigServiceHelper objectConfigServiceHelper; + + @BeforeEach + void setUp() { + this.instance = + new GetConfigurationObjectServiceDsmr43(this.dlmsHelper, this.objectConfigServiceHelper); + } + + @ParameterizedTest + @EnumSource(Protocol.class) + @NullSource + void handles(final Protocol protocol) { + assertThat(this.instance.handles(protocol)).isEqualTo(protocol != null && protocol.isDsmr43()); + } + + @Test + void getFlagType() { + for (final ConfigurationFlagTypeDto flagTypeDto : ConfigurationFlagTypeDto.values()) { + flagTypeDto + .getBitPositionDsmr43() + .ifPresent( + bitPosition -> + assertThat( + this.instance + .getFlagType(bitPosition) + .orElseThrow(IllegalArgumentException::new)) + .isEqualTo(flagTypeDto)); + } + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/GetConfigurationObjectServiceDsmr4Test.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/GetConfigurationObjectServiceDsmr4Test.java index 56a0dac34e1..64eaeca2d02 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/GetConfigurationObjectServiceDsmr4Test.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/GetConfigurationObjectServiceDsmr4Test.java @@ -14,39 +14,44 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.NullSource; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.openmuc.jdlms.GetResult; import org.openmuc.jdlms.datatypes.DataObject; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.DlmsHelper; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.ObjectConfigServiceHelper; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.Protocol; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ConfigurationFlagTypeDto; @ExtendWith(MockitoExtension.class) -public class GetConfigurationObjectServiceDsmr4Test { +class GetConfigurationObjectServiceDsmr4Test { private GetConfigurationObjectServiceDsmr4 instance; @Mock private GetResult getResult; @Mock private DlmsHelper dlmsHelper; + @Mock private ObjectConfigServiceHelper objectConfigServiceHelper; + @BeforeEach - public void setUp() { - this.instance = new GetConfigurationObjectServiceDsmr4(this.dlmsHelper); + void setUp() { + this.instance = + new GetConfigurationObjectServiceDsmr4(this.dlmsHelper, this.objectConfigServiceHelper); } - @Test - public void handles() { - assertThat(this.instance.handles(Protocol.SMR_5_0_0)).isFalse(); - assertThat(this.instance.handles(Protocol.SMR_5_1)).isFalse(); - assertThat(this.instance.handles(Protocol.DSMR_4_2_2)).isTrue(); - assertThat(this.instance.handles(Protocol.OTHER_PROTOCOL)).isFalse(); - assertThat(this.instance.handles(null)).isFalse(); + @ParameterizedTest + @EnumSource(Protocol.class) + @NullSource + void handles(final Protocol protocol) { + assertThat(this.instance.handles(protocol)).isEqualTo(protocol != null && protocol.isDsmr42()); } @Test - public void getFlagType() { + void getFlagType() { for (final ConfigurationFlagTypeDto flagTypeDto : ConfigurationFlagTypeDto.values()) { flagTypeDto .getBitPositionDsmr4() @@ -61,7 +66,7 @@ public void getFlagType() { } @Test - public void getConfigurationObjectResultDataNull() throws ProtocolAdapterException { + void getConfigurationObjectResultDataNull() throws ProtocolAdapterException { // SETUP when(this.getResult.getResultData()).thenReturn(null); @@ -74,7 +79,7 @@ public void getConfigurationObjectResultDataNull() throws ProtocolAdapterExcepti } @Test - public void getConfigurationObjectResultDataNotComplex() throws ProtocolAdapterException { + void getConfigurationObjectResultDataNotComplex() throws ProtocolAdapterException { // SETUP final DataObject nonComplex = mock(DataObject.class); @@ -90,7 +95,7 @@ public void getConfigurationObjectResultDataNotComplex() throws ProtocolAdapterE } @Test - public void getConfigurationObjectElementsNull() throws ProtocolAdapterException { + void getConfigurationObjectElementsNull() throws ProtocolAdapterException { // SETUP final DataObject structure = mock(DataObject.class); @@ -108,7 +113,7 @@ public void getConfigurationObjectElementsNull() throws ProtocolAdapterException } @Test - public void getConfigurationObjectElementsSizeNotTwo() throws ProtocolAdapterException { + void getConfigurationObjectElementsSizeNotTwo() throws ProtocolAdapterException { // SETUP final DataObject structure = mock(DataObject.class); @@ -127,7 +132,7 @@ public void getConfigurationObjectElementsSizeNotTwo() throws ProtocolAdapterExc } @Test - public void getConfigurationObjectGprsModeNull() throws ProtocolAdapterException { + void getConfigurationObjectGprsModeNull() throws ProtocolAdapterException { // SETUP final DataObject structure = mock(DataObject.class); @@ -148,7 +153,7 @@ public void getConfigurationObjectGprsModeNull() throws ProtocolAdapterException } @Test - public void getConfigurationObjectGprsModeNotNumber() throws ProtocolAdapterException { + void getConfigurationObjectGprsModeNotNumber() throws ProtocolAdapterException { // SETUP final DataObject structure = mock(DataObject.class); @@ -171,7 +176,7 @@ public void getConfigurationObjectGprsModeNotNumber() throws ProtocolAdapterExce } @Test - public void getConfigurationObjectFlagsNull() throws ProtocolAdapterException { + void getConfigurationObjectFlagsNull() throws ProtocolAdapterException { // SETUP final DataObject structure = mock(DataObject.class); @@ -195,7 +200,7 @@ public void getConfigurationObjectFlagsNull() throws ProtocolAdapterException { } @Test - public void getConfigurationObjectFlagsNotBitString() throws ProtocolAdapterException { + void getConfigurationObjectFlagsNotBitString() throws ProtocolAdapterException { // SETUP final DataObject structure = mock(DataObject.class); diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/GetConfigurationObjectServiceSmr5Test.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/GetConfigurationObjectServiceSmr5Test.java index 29290b95693..5bc12651ad0 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/GetConfigurationObjectServiceSmr5Test.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/GetConfigurationObjectServiceSmr5Test.java @@ -11,6 +11,9 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.NullSource; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoSettings; @@ -23,7 +26,7 @@ @ExtendWith(MockitoExtension.class) @MockitoSettings(strictness = Strictness.LENIENT) -public class GetConfigurationObjectServiceSmr5Test { +class GetConfigurationObjectServiceSmr5Test { private GetConfigurationObjectServiceSmr5 instance; @@ -31,23 +34,20 @@ public class GetConfigurationObjectServiceSmr5Test { @Mock private DataObject nonBitString; @BeforeEach - public void setUp() { - this.instance = new GetConfigurationObjectServiceSmr5(null); + void setUp() { + this.instance = new GetConfigurationObjectServiceSmr5(null, null); when(this.nonBitString.isBitString()).thenReturn(false); } - @Test - public void handles() { - assertThat(this.instance.handles(Protocol.SMR_5_0_0)).isTrue(); - assertThat(this.instance.handles(Protocol.SMR_5_1)).isTrue(); - assertThat(this.instance.handles(Protocol.SMR_5_2)).isTrue(); - assertThat(this.instance.handles(Protocol.DSMR_4_2_2)).isFalse(); - assertThat(this.instance.handles(Protocol.OTHER_PROTOCOL)).isFalse(); - assertThat(this.instance.handles(null)).isFalse(); + @ParameterizedTest + @EnumSource(Protocol.class) + @NullSource + void handles(final Protocol protocol) { + assertThat(this.instance.handles(protocol)).isEqualTo(protocol != null && protocol.isSmr5()); } @Test - public void getFlagType() { + void getFlagType() { for (final ConfigurationFlagTypeDto flagTypeDto : ConfigurationFlagTypeDto.values()) { flagTypeDto .getBitPositionSmr5() @@ -62,7 +62,7 @@ public void getFlagType() { } @Test - public void getConfigurationObjectResultDataNull() throws ProtocolAdapterException { + void getConfigurationObjectResultDataNull() throws ProtocolAdapterException { // SETUP when(this.getResult.getResultData()).thenReturn(null); @@ -75,7 +75,7 @@ public void getConfigurationObjectResultDataNull() throws ProtocolAdapterExcepti } @Test - public void getConfigurationObjectResultDataNotBitString() throws ProtocolAdapterException { + void getConfigurationObjectResultDataNotBitString() throws ProtocolAdapterException { // SETUP when(this.getResult.getResultData()).thenReturn(this.nonBitString); diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/GetConfigurationObjectServiceTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/GetConfigurationObjectServiceTest.java index 025b340d770..0cdc55933c8 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/GetConfigurationObjectServiceTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/GetConfigurationObjectServiceTest.java @@ -19,6 +19,8 @@ import org.openmuc.jdlms.AttributeAddress; import org.openmuc.jdlms.DlmsConnection; import org.openmuc.jdlms.GetResult; +import org.openmuc.jdlms.ObisCode; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.ObjectConfigServiceHelper; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.Protocol; import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionManager; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ConnectionException; @@ -28,10 +30,16 @@ import org.opensmartgridplatform.dto.valueobjects.smartmetering.ConfigurationObjectDto; @ExtendWith(MockitoExtension.class) -public class GetConfigurationObjectServiceTest { +class GetConfigurationObjectServiceTest { private final GetConfigurationObjectService instance = new GetConfigurationObjectService() { + + @Override + AttributeAddress getAttributeAddress(final Protocol protocol) { + return new AttributeAddress(-1, (ObisCode) null, -1); + } + @Override ConfigurationObjectDto getConfigurationObject(final GetResult result) { return null; @@ -48,19 +56,22 @@ public boolean handles(final Protocol protocol) { } }; + @Mock private ObjectConfigServiceHelper objectConfigServiceHelper; @Mock private DlmsConnectionManager conn; @Mock private DlmsMessageListener dlmsMessageListener; @Mock private DlmsConnection dlmsConnection; @Mock private GetResult getResult; + @Mock Protocol protocol; + @BeforeEach - public void setUp() { + void setUp() { when(this.conn.getDlmsMessageListener()).thenReturn(this.dlmsMessageListener); when(this.conn.getConnection()).thenReturn(this.dlmsConnection); } @Test - public void getConfigurationObjectIOException() throws Exception { + void getConfigurationObjectIOException() throws Exception { // SETUP when(this.dlmsConnection.get(any(AttributeAddress.class))).thenThrow(new IOException()); @@ -69,12 +80,12 @@ public void getConfigurationObjectIOException() throws Exception { assertThatExceptionOfType(ConnectionException.class) .isThrownBy( () -> { - this.instance.getConfigurationObject(this.conn); + this.instance.getConfigurationObject(this.conn, this.protocol); }); } @Test - public void getConfigurationObjectGetResultNull() throws Exception { + void getConfigurationObjectGetResultNull() throws Exception { // SETUP when(this.dlmsConnection.get(any(AttributeAddress.class))).thenReturn(null); @@ -83,12 +94,12 @@ public void getConfigurationObjectGetResultNull() throws Exception { assertThatExceptionOfType(ProtocolAdapterException.class) .isThrownBy( () -> { - this.instance.getConfigurationObject(this.conn); + this.instance.getConfigurationObject(this.conn, this.protocol); }); } @Test - public void getConfigurationObjectGetResultUnsuccessful() throws Exception { + void getConfigurationObjectGetResultUnsuccessful() throws Exception { // SETUP when(this.getResult.getResultCode()).thenReturn(AccessResultCode.READ_WRITE_DENIED); @@ -98,7 +109,7 @@ public void getConfigurationObjectGetResultUnsuccessful() throws Exception { assertThatExceptionOfType(ProtocolAdapterException.class) .isThrownBy( () -> { - this.instance.getConfigurationObject(this.conn); + this.instance.getConfigurationObject(this.conn, this.protocol); }); } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/ProtocolServiceLookupTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/ProtocolServiceLookupTest.java index 222b75b5131..44ed2ed737f 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/ProtocolServiceLookupTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/ProtocolServiceLookupTest.java @@ -10,43 +10,58 @@ import java.util.ArrayList; import java.util.List; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.NullSource; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.Protocol; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; public class ProtocolServiceLookupTest { private ProtocolServiceLookup instance; - private GetConfigurationObjectServiceDsmr4 getService; + private GetConfigurationObjectServiceDsmr4 getDsmr4Service; + private GetConfigurationObjectServiceDsmr43 getDsmr43Service; + private GetConfigurationObjectServiceSmr5 getSmr5Service; @BeforeEach - public void setUp() { - this.getService = new GetConfigurationObjectServiceDsmr4(null); + void setUp() { + this.getDsmr4Service = new GetConfigurationObjectServiceDsmr4(null, null); + this.getDsmr43Service = new GetConfigurationObjectServiceDsmr43(null, null); + this.getSmr5Service = new GetConfigurationObjectServiceSmr5(null, null); final List services = new ArrayList<>(); - services.add(this.getService); + services.add(this.getDsmr4Service); + services.add(this.getDsmr43Service); + services.add(this.getSmr5Service); this.instance = new ProtocolServiceLookup(services); } - @Test - public void lookupGetService() throws ProtocolAdapterException { + @ParameterizedTest + @EnumSource(Protocol.class) + @NullSource + void lookupGetService(final Protocol protocol) throws ProtocolAdapterException { - // SETUP - final Protocol protocol = Protocol.DSMR_4_2_2; + if (protocol == null || (!protocol.isDsmr4() && !protocol.isSmr5())) { + this.assertGetServiceNotFound(protocol); + } else { + this.assertGetServiceFound(protocol); + } + } + + private void assertGetServiceFound(final Protocol protocol) throws ProtocolAdapterException { - // CALL final GetConfigurationObjectService result = this.instance.lookupGetService(protocol); - // VERIFY - assertThat(result).isSameAs(this.getService); + if (protocol.isDsmr43()) { + assertThat(result).isSameAs(this.getDsmr43Service); + } else if (protocol.isDsmr42()) { + assertThat(result).isSameAs(this.getDsmr4Service); + } else if (protocol.isSmr5()) { + assertThat(result).isSameAs(this.getSmr5Service); + } } - @Test - public void lookupGetServiceNotFound() { - - // SETUP - final Protocol protocol = Protocol.OTHER_PROTOCOL; + private void assertGetServiceNotFound(final Protocol protocol) { - // CALL assertThatExceptionOfType(ProtocolAdapterException.class) .isThrownBy(() -> this.instance.lookupSetService(protocol)); } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/SetConfigurationObjectServiceDsmr43Test.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/SetConfigurationObjectServiceDsmr43Test.java new file mode 100644 index 00000000000..3dc352cf077 --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/SetConfigurationObjectServiceDsmr43Test.java @@ -0,0 +1,64 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.configuration.service; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.NullSource; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; +import org.openmuc.jdlms.GetResult; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.Protocol; +import org.opensmartgridplatform.dto.valueobjects.smartmetering.ConfigurationFlagTypeDto; +import org.opensmartgridplatform.dto.valueobjects.smartmetering.ConfigurationObjectDto; +import org.opensmartgridplatform.dto.valueobjects.smartmetering.GprsOperationModeTypeDto; + +@ExtendWith(MockitoExtension.class) +@MockitoSettings(strictness = Strictness.LENIENT) +class SetConfigurationObjectServiceDsmr43Test { + + private static final GprsOperationModeTypeDto GPRS_OPERATION_MODE = + GprsOperationModeTypeDto.ALWAYS_ON; + + private SetConfigurationObjectServiceDsmr43 instance; + + @Mock private GetResult getResult; + @Mock ConfigurationObjectDto configurationToSet; + @Mock ConfigurationObjectDto configurationOnDevice; + + @BeforeEach + void setUp() { + this.instance = new SetConfigurationObjectServiceDsmr43(null, null); + } + + @ParameterizedTest + @EnumSource(Protocol.class) + @NullSource + void handles(final Protocol protocol) { + assertThat(this.instance.handles(protocol)).isEqualTo(protocol != null && protocol.isDsmr43()); + } + + @Test + void getBitPosition() { + for (final ConfigurationFlagTypeDto flagTypeDto : ConfigurationFlagTypeDto.values()) { + flagTypeDto + .getBitPositionDsmr43() + .ifPresent( + bitPosition -> + assertThat( + this.instance + .getBitPosition(flagTypeDto) + .orElseThrow(IllegalArgumentException::new)) + .isEqualTo(bitPosition)); + } + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/SetConfigurationObjectServiceDsmr4Test.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/SetConfigurationObjectServiceDsmr4Test.java index 63afd0e503c..d0857fa36fb 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/SetConfigurationObjectServiceDsmr4Test.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/SetConfigurationObjectServiceDsmr4Test.java @@ -12,6 +12,9 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.NullSource; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoSettings; @@ -27,7 +30,7 @@ @ExtendWith(MockitoExtension.class) @MockitoSettings(strictness = Strictness.LENIENT) -public class SetConfigurationObjectServiceDsmr4Test { +class SetConfigurationObjectServiceDsmr4Test { private static final GprsOperationModeTypeDto GPRS_OPERATION_MODE = GprsOperationModeTypeDto.ALWAYS_ON; @@ -39,24 +42,21 @@ public class SetConfigurationObjectServiceDsmr4Test { @Mock ConfigurationObjectDto configurationOnDevice; @BeforeEach - public void setUp() { - this.instance = new SetConfigurationObjectServiceDsmr4(null); + void setUp() { + this.instance = new SetConfigurationObjectServiceDsmr4(null, null); when(this.configurationToSet.getConfigurationFlags()).thenReturn(this.emptyFlags()); when(this.configurationOnDevice.getConfigurationFlags()).thenReturn(this.emptyFlags()); } - @Test - public void handles() { - assertThat(this.instance.handles(Protocol.SMR_5_0_0)).isFalse(); - assertThat(this.instance.handles(Protocol.SMR_5_1)).isFalse(); - assertThat(this.instance.handles(Protocol.SMR_5_2)).isFalse(); - assertThat(this.instance.handles(Protocol.DSMR_4_2_2)).isTrue(); - assertThat(this.instance.handles(Protocol.OTHER_PROTOCOL)).isFalse(); - assertThat(this.instance.handles(null)).isFalse(); + @ParameterizedTest + @EnumSource(Protocol.class) + @NullSource + void handles(final Protocol protocol) { + assertThat(this.instance.handles(protocol)).isEqualTo(protocol != null && protocol.isDsmr42()); } @Test - public void getBitPosition() { + void getBitPosition() { for (final ConfigurationFlagTypeDto flagTypeDto : ConfigurationFlagTypeDto.values()) { flagTypeDto .getBitPositionDsmr4() @@ -71,7 +71,7 @@ public void getBitPosition() { } @Test - public void buildSetParameterDataGprsModeToSet() throws ProtocolAdapterException { + void buildSetParameterDataGprsModeToSet() throws ProtocolAdapterException { // SETUP when(this.configurationToSet.getGprsOperationMode()).thenReturn(GPRS_OPERATION_MODE); @@ -88,7 +88,7 @@ public void buildSetParameterDataGprsModeToSet() throws ProtocolAdapterException } @Test - public void buildSetParameterDataGprsModeOnDevice() throws ProtocolAdapterException { + void buildSetParameterDataGprsModeOnDevice() throws ProtocolAdapterException { // SETUP when(this.configurationToSet.getGprsOperationMode()).thenReturn(null); diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/SetConfigurationObjectServiceSmr5Test.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/SetConfigurationObjectServiceSmr5Test.java index d864f464829..6a990f2564a 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/SetConfigurationObjectServiceSmr5Test.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/SetConfigurationObjectServiceSmr5Test.java @@ -9,6 +9,9 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.NullSource; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.openmuc.jdlms.GetResult; @@ -16,29 +19,26 @@ import org.opensmartgridplatform.dto.valueobjects.smartmetering.ConfigurationFlagTypeDto; @ExtendWith(MockitoExtension.class) -public class SetConfigurationObjectServiceSmr5Test { +class SetConfigurationObjectServiceSmr5Test { private SetConfigurationObjectServiceSmr5 instance; @Mock private GetResult getResult; @BeforeEach - public void setUp() { - this.instance = new SetConfigurationObjectServiceSmr5(null); + void setUp() { + this.instance = new SetConfigurationObjectServiceSmr5(null, null); } - @Test - public void handles() { - assertThat(this.instance.handles(Protocol.SMR_5_0_0)).isTrue(); - assertThat(this.instance.handles(Protocol.SMR_5_1)).isTrue(); - assertThat(this.instance.handles(Protocol.SMR_5_2)).isTrue(); - assertThat(this.instance.handles(Protocol.DSMR_4_2_2)).isFalse(); - assertThat(this.instance.handles(Protocol.OTHER_PROTOCOL)).isFalse(); - assertThat(this.instance.handles(null)).isFalse(); + @ParameterizedTest + @EnumSource(Protocol.class) + @NullSource + void handles(final Protocol protocol) { + assertThat(this.instance.handles(protocol)).isEqualTo(protocol != null && protocol.isSmr5()); } @Test - public void getBitPosition() { + void getBitPosition() { for (final ConfigurationFlagTypeDto flagTypeDto : ConfigurationFlagTypeDto.values()) { flagTypeDto .getBitPositionSmr5() diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/SetConfigurationObjectServiceTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/SetConfigurationObjectServiceTest.java index c22c072f1ea..169498ce742 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/SetConfigurationObjectServiceTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/configuration/service/SetConfigurationObjectServiceTest.java @@ -19,7 +19,9 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoSettings; import org.mockito.quality.Strictness; +import org.openmuc.jdlms.AttributeAddress; import org.openmuc.jdlms.DlmsConnection; +import org.openmuc.jdlms.ObisCode; import org.openmuc.jdlms.SetParameter; import org.openmuc.jdlms.datatypes.BitString; import org.openmuc.jdlms.datatypes.DataObject; @@ -55,6 +57,11 @@ void setUp() { this.instance = new SetConfigurationObjectService(this.dlmsHelper) { + @Override + AttributeAddress getAttributeAddress(final Protocol protocol) { + return new AttributeAddress(-1, (ObisCode) null, -1); + } + @Override public boolean handles(final Protocol protocol) { return false; @@ -84,7 +91,7 @@ void setConfigurationObjectIOException() throws Exception { .isThrownBy( () -> { // CALL - this.instance.setConfigurationObject(this.conn, null, null); + this.instance.setConfigurationObject(this.conn, null, null, null); }); } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/datetime/SetActivityCalendarCommandActivationExecutorTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/datetime/SetActivityCalendarCommandActivationExecutorTest.java index 3039f17d4ea..01bba22e6d5 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/datetime/SetActivityCalendarCommandActivationExecutorTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/datetime/SetActivityCalendarCommandActivationExecutorTest.java @@ -13,10 +13,12 @@ import java.io.IOException; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; import org.mockito.ArgumentCaptor; import org.mockito.Captor; +import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.openmuc.jdlms.DlmsConnection; @@ -29,16 +31,20 @@ import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionManager; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; import org.opensmartgridplatform.adapter.protocol.dlms.infra.messaging.DlmsMessageListener; +import org.opensmartgridplatform.dlms.exceptions.ObjectConfigException; +import org.opensmartgridplatform.dlms.services.ObjectConfigService; +import org.opensmartgridplatform.dlms.services.Protocol; import org.opensmartgridplatform.shared.infra.jms.MessageMetadata; +import org.springframework.test.util.ReflectionTestUtils; @ExtendWith(MockitoExtension.class) class SetActivityCalendarCommandActivationExecutorTest { private static final int CLASS_ID = 20; - private static final ObisCode OBIS_CODE = new ObisCode("0.0.13.0.0.255"); - private static final int METHOD_ID_ACTIVATE_PASSIVE_CALENDAR = 1; - private final DlmsDevice DLMS_DEVICE = new DlmsDevice(); + private static final String OBIS = "0.0.13.0.0.255"; + private static final ObisCode OBIS_CODE = new ObisCode(OBIS); + private static final int METHOD_ID_ACTIVATE_PASSIVE_CALENDAR = 1; @Captor ArgumentCaptor actionParameterArgumentCaptor; @@ -52,25 +58,34 @@ class SetActivityCalendarCommandActivationExecutorTest { @Mock private MethodResult methodResult; - private SetActivityCalendarCommandActivationExecutor executor; + @Mock private DlmsDevice dlmsDevice; + + @InjectMocks private SetActivityCalendarCommandActivationExecutor executor; @BeforeEach - public void setUp() throws IOException { - this.executor = new SetActivityCalendarCommandActivationExecutor(); + public void setUp() throws IOException, ObjectConfigException { + final ObjectConfigService objectConfigService = new ObjectConfigService(); + ReflectionTestUtils.setField(this.executor, "objectConfigService", objectConfigService); + when(this.conn.getDlmsMessageListener()).thenReturn(this.dlmsMessageListener); when(this.conn.getConnection()).thenReturn(this.dlmsConnection); when(this.dlmsConnection.action(any(MethodParameter.class))).thenReturn(this.methodResult); } - @Test - void testActivationWithSuccess() throws ProtocolAdapterException, IOException { + @ParameterizedTest + @EnumSource(Protocol.class) + void testActivationWithSuccess(final org.opensmartgridplatform.dlms.services.Protocol protocol) + throws ProtocolAdapterException, IOException { + + when(this.dlmsDevice.getProtocolName()).thenReturn(protocol.getName()); + when(this.dlmsDevice.getProtocolVersion()).thenReturn(protocol.getVersion()); // SETUP when(this.methodResult.getResultCode()).thenReturn(MethodResultCode.SUCCESS); // CALL final MethodResultCode resultCode = - this.executor.execute(this.conn, this.DLMS_DEVICE, null, this.messageMetadata); + this.executor.execute(this.conn, this.dlmsDevice, null, this.messageMetadata); // VERIFY assertThat(resultCode).isEqualTo(MethodResultCode.SUCCESS); @@ -84,18 +99,19 @@ void testActivationWithSuccess() throws ProtocolAdapterException, IOException { assertThat((byte) methodParameter.getParameter().getValue()).isZero(); } - @Test - void testActivationWithFailure() throws IOException { + @ParameterizedTest + @EnumSource(Protocol.class) + void testActivationWithFailure(final Protocol protocol) throws IOException { // SETUP + when(this.dlmsDevice.getProtocolName()).thenReturn(protocol.getName()); + when(this.dlmsDevice.getProtocolVersion()).thenReturn(protocol.getVersion()); when(this.methodResult.getResultCode()).thenReturn(MethodResultCode.OTHER_REASON); // CALL assertThrows( ProtocolAdapterException.class, - () -> { - this.executor.execute(this.conn, this.DLMS_DEVICE, null, this.messageMetadata); - }); + () -> this.executor.execute(this.conn, this.dlmsDevice, null, this.messageMetadata)); // VERIFY verify(this.dlmsConnection, times(1)).action(this.actionParameterArgumentCaptor.capture()); diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/datetime/SetActivityCalendarCommandExecutorTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/datetime/SetActivityCalendarCommandExecutorTest.java index e9d19f9302c..add0da86fde 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/datetime/SetActivityCalendarCommandExecutorTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/datetime/SetActivityCalendarCommandExecutorTest.java @@ -26,8 +26,11 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; import org.mockito.ArgumentCaptor; import org.mockito.Captor; +import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockedStatic; import org.mockito.junit.jupiter.MockitoExtension; @@ -46,6 +49,9 @@ import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionManager; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; import org.opensmartgridplatform.adapter.protocol.dlms.infra.messaging.DlmsMessageListener; +import org.opensmartgridplatform.dlms.exceptions.ObjectConfigException; +import org.opensmartgridplatform.dlms.services.ObjectConfigService; +import org.opensmartgridplatform.dlms.services.Protocol; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ActivityCalendarDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ClockStatusDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.CosemDateDto; @@ -59,13 +65,15 @@ import org.opensmartgridplatform.shared.exceptionhandling.FunctionalException; import org.opensmartgridplatform.shared.exceptionhandling.FunctionalExceptionType; import org.opensmartgridplatform.shared.infra.jms.MessageMetadata; +import org.springframework.test.util.ReflectionTestUtils; @ExtendWith(MockitoExtension.class) class SetActivityCalendarCommandExecutorTest { protected static final int CLASS_ID = 20; - private static final ObisCode OBIS_CODE = new ObisCode("0.0.13.0.0.255"); + private static final String OBIS = "0.0.13.0.0.255"; + private static final ObisCode OBIS_CODE = new ObisCode(OBIS); private static final ObisCode OBIS_CODE_SCRIPT = new ObisCode("0.0.10.0.100.255"); private static final int ATTRIBUTE_ID_CALENDAR_NAME_PASSIVE = 6; @@ -73,8 +81,6 @@ class SetActivityCalendarCommandExecutorTest { private static final int ATTRIBUTE_ID_WEEK_PROFILE_TABLE_PASSIVE = 8; private static final int ATTRIBUTE_ID_DAY_PROFILE_TABLE_PASSIVE = 9; - private final DlmsDevice DLMS_DEVICE = new DlmsDevice(); - private static final String CALENDAR_NAME = "Calendar"; private static final CosemDateTimeDto ACTIVATE_PASSIVE_CALENDAR_TIME = @@ -82,6 +88,8 @@ class SetActivityCalendarCommandExecutorTest { @Captor ArgumentCaptor setParameterArgumentCaptor; + @Mock private DlmsDevice dlmsDevice; + @Mock private DlmsConnectionManager conn; @Mock private DlmsMessageListener dlmsMessageListener; @@ -92,33 +100,39 @@ class SetActivityCalendarCommandExecutorTest { @Mock private SetActivityCalendarCommandActivationExecutor activationExecutor; - private SetActivityCalendarCommandExecutor executor; + @InjectMocks private SetActivityCalendarCommandExecutor executor; private MockedStatic activityCalendarValidator; @BeforeEach - public void setUp() { - this.executor = - new SetActivityCalendarCommandExecutor( - new DlmsHelper(), this.activationExecutor, new ConfigurationMapper()); + public void setUp() throws IOException, ObjectConfigException { + final ObjectConfigService objectConfigService = new ObjectConfigService(); + + ReflectionTestUtils.setField(this.executor, "configurationMapper", new ConfigurationMapper()); + ReflectionTestUtils.setField(this.executor, "dlmsHelper", new DlmsHelper()); + ReflectionTestUtils.setField(this.executor, "objectConfigService", objectConfigService); this.activityCalendarValidator = mockStatic(ActivityCalendarValidator.class); } @AfterEach - public void tearDown() throws Exception { + public void tearDown() { this.activityCalendarValidator.close(); } - @Test - void testSetActivityCalendarEmpty() + @ParameterizedTest + @EnumSource(Protocol.class) + void testSetActivityCalendarEmpty(final Protocol protocol) throws ProtocolAdapterException, IOException, FunctionalException { + when(this.dlmsDevice.getProtocolName()).thenReturn(protocol.getName()); + when(this.dlmsDevice.getProtocolVersion()).thenReturn(protocol.getVersion()); + // SETUP when(this.conn.getDlmsMessageListener()).thenReturn(this.dlmsMessageListener); when(this.conn.getConnection()).thenReturn(this.dlmsConnection); when(this.dlmsConnection.set(any(SetParameter.class))).thenReturn(AccessResultCode.SUCCESS); - when(this.activationExecutor.execute(this.conn, this.DLMS_DEVICE, null, this.messageMetadata)) + when(this.activationExecutor.execute(this.conn, this.dlmsDevice, null, this.messageMetadata)) .thenReturn(MethodResultCode.SUCCESS); final ActivityCalendarDto activityCalendar = @@ -127,7 +141,7 @@ void testSetActivityCalendarEmpty() // CALL final AccessResultCode resultCode = - this.executor.execute(this.conn, this.DLMS_DEVICE, activityCalendar, this.messageMetadata); + this.executor.execute(this.conn, this.dlmsDevice, activityCalendar, this.messageMetadata); // VERIFY assertThat(resultCode).isEqualTo(AccessResultCode.SUCCESS); @@ -145,14 +159,18 @@ void testSetActivityCalendarEmpty() Collections.emptyList()); } - @Test - void testSetActivityCalendarWithSingleSeason() + @ParameterizedTest + @EnumSource(Protocol.class) + void testSetActivityCalendarWithSingleSeason(final Protocol protocol) throws ProtocolAdapterException, IOException, FunctionalException { // SETUP + when(this.dlmsDevice.getProtocolName()).thenReturn(protocol.getName()); + when(this.dlmsDevice.getProtocolVersion()).thenReturn(protocol.getVersion()); + when(this.conn.getDlmsMessageListener()).thenReturn(this.dlmsMessageListener); when(this.conn.getConnection()).thenReturn(this.dlmsConnection); when(this.dlmsConnection.set(any(SetParameter.class))).thenReturn(AccessResultCode.SUCCESS); - when(this.activationExecutor.execute(this.conn, this.DLMS_DEVICE, null, this.messageMetadata)) + when(this.activationExecutor.execute(this.conn, this.dlmsDevice, null, this.messageMetadata)) .thenReturn(MethodResultCode.SUCCESS); final List dayIds = Collections.singletonList((short) 1); @@ -168,7 +186,7 @@ void testSetActivityCalendarWithSingleSeason() // CALL final AccessResultCode resultCode = - this.executor.execute(this.conn, this.DLMS_DEVICE, activityCalendar, this.messageMetadata); + this.executor.execute(this.conn, this.dlmsDevice, activityCalendar, this.messageMetadata); // VERIFY assertThat(resultCode).isEqualTo(AccessResultCode.SUCCESS); @@ -181,14 +199,18 @@ void testSetActivityCalendarWithSingleSeason() setParameters, dayIds, actionStartTimes, weekNames, seasonNames, seasonStarts); } - @Test - void testSetActivityCalendarWithMultipleSeasons() + @ParameterizedTest + @EnumSource(Protocol.class) + void testSetActivityCalendarWithMultipleSeasons(final Protocol protocol) throws ProtocolAdapterException, IOException, FunctionalException { // SETUP + when(this.dlmsDevice.getProtocolName()).thenReturn(protocol.getName()); + when(this.dlmsDevice.getProtocolVersion()).thenReturn(protocol.getVersion()); + when(this.conn.getDlmsMessageListener()).thenReturn(this.dlmsMessageListener); when(this.conn.getConnection()).thenReturn(this.dlmsConnection); when(this.dlmsConnection.set(any(SetParameter.class))).thenReturn(AccessResultCode.SUCCESS); - when(this.activationExecutor.execute(this.conn, this.DLMS_DEVICE, null, this.messageMetadata)) + when(this.activationExecutor.execute(this.conn, this.dlmsDevice, null, this.messageMetadata)) .thenReturn(MethodResultCode.SUCCESS); final List dayIds = Collections.singletonList((short) 1); @@ -204,7 +226,7 @@ void testSetActivityCalendarWithMultipleSeasons() // CALL final AccessResultCode resultCode = - this.executor.execute(this.conn, this.DLMS_DEVICE, activityCalendar, this.messageMetadata); + this.executor.execute(this.conn, this.dlmsDevice, activityCalendar, this.messageMetadata); // VERIFY assertThat(resultCode).isEqualTo(AccessResultCode.SUCCESS); @@ -217,14 +239,18 @@ void testSetActivityCalendarWithMultipleSeasons() setParameters, dayIds, actionStartTimes, weekNames, seasonNames, seasonStarts); } - @Test - void testSetActivityCalendarWithMultipleSeasonsWeeksDaysAndActions() + @ParameterizedTest + @EnumSource(Protocol.class) + void testSetActivityCalendarWithMultipleSeasonsWeeksDaysAndActions(final Protocol protocol) throws ProtocolAdapterException, IOException, FunctionalException { // SETUP + when(this.dlmsDevice.getProtocolName()).thenReturn(protocol.getName()); + when(this.dlmsDevice.getProtocolVersion()).thenReturn(protocol.getVersion()); + when(this.conn.getDlmsMessageListener()).thenReturn(this.dlmsMessageListener); when(this.conn.getConnection()).thenReturn(this.dlmsConnection); when(this.dlmsConnection.set(any(SetParameter.class))).thenReturn(AccessResultCode.SUCCESS); - when(this.activationExecutor.execute(this.conn, this.DLMS_DEVICE, null, this.messageMetadata)) + when(this.activationExecutor.execute(this.conn, this.dlmsDevice, null, this.messageMetadata)) .thenReturn(MethodResultCode.SUCCESS); final List dayIds = Arrays.asList((short) 1, (short) 2, (short) 3); @@ -243,7 +269,7 @@ void testSetActivityCalendarWithMultipleSeasonsWeeksDaysAndActions() // CALL final AccessResultCode resultCode = - this.executor.execute(this.conn, this.DLMS_DEVICE, activityCalendar, this.messageMetadata); + this.executor.execute(this.conn, this.dlmsDevice, activityCalendar, this.messageMetadata); // VERIFY assertThat(resultCode).isEqualTo(AccessResultCode.SUCCESS); @@ -257,8 +283,9 @@ void testSetActivityCalendarWithMultipleSeasonsWeeksDaysAndActions() } @Test - void testSetActivityCalendarWithValidationFailure() throws IOException { + void testSetActivityCalendarWithValidationFailure() { // SETUP + this.activityCalendarValidator .when(() -> ActivityCalendarValidator.validate(any())) .thenThrow( @@ -271,15 +298,20 @@ void testSetActivityCalendarWithValidationFailure() throws IOException { catchThrowable( () -> this.executor.execute( - this.conn, this.DLMS_DEVICE, activityCalendar, this.messageMetadata)); + this.conn, this.dlmsDevice, activityCalendar, this.messageMetadata)); // VERIFY assertThat(thrown).isInstanceOf(FunctionalException.class); } - @Test - void testSetActivityCalendarWithOneOfTheSetRequestsFailing() throws IOException { + @ParameterizedTest + @EnumSource(Protocol.class) + void testSetActivityCalendarWithOneOfTheSetRequestsFailing(final Protocol protocol) + throws IOException { // SETUP + when(this.dlmsDevice.getProtocolName()).thenReturn(protocol.getName()); + when(this.dlmsDevice.getProtocolVersion()).thenReturn(protocol.getVersion()); + when(this.conn.getDlmsMessageListener()).thenReturn(this.dlmsMessageListener); when(this.conn.getConnection()).thenReturn(this.dlmsConnection); when(this.dlmsConnection.set(any(SetParameter.class))) @@ -295,7 +327,7 @@ void testSetActivityCalendarWithOneOfTheSetRequestsFailing() throws IOException catchThrowable( () -> this.executor.execute( - this.conn, this.DLMS_DEVICE, activityCalendar, this.messageMetadata)); + this.conn, this.dlmsDevice, activityCalendar, this.messageMetadata)); // VERIFY assertThat(thrown) @@ -305,14 +337,19 @@ void testSetActivityCalendarWithOneOfTheSetRequestsFailing() throws IOException () -> ActivityCalendarValidator.validate(activityCalendar), times(1)); } - @Test - void testSetActivityCalendarWithActivationFailure() throws ProtocolAdapterException, IOException { + @ParameterizedTest + @EnumSource(Protocol.class) + void testSetActivityCalendarWithActivationFailure(final Protocol protocol) + throws ProtocolAdapterException, IOException { // SETUP + when(this.dlmsDevice.getProtocolName()).thenReturn(protocol.getName()); + when(this.dlmsDevice.getProtocolVersion()).thenReturn(protocol.getVersion()); + final String errorMessage = "Activation failure"; when(this.conn.getDlmsMessageListener()).thenReturn(this.dlmsMessageListener); when(this.conn.getConnection()).thenReturn(this.dlmsConnection); when(this.dlmsConnection.set(any(SetParameter.class))).thenReturn(AccessResultCode.SUCCESS); - when(this.activationExecutor.execute(this.conn, this.DLMS_DEVICE, null, this.messageMetadata)) + when(this.activationExecutor.execute(this.conn, this.dlmsDevice, null, this.messageMetadata)) .thenThrow(new ProtocolAdapterException(errorMessage)); final ActivityCalendarDto activityCalendar = this.createDefaultActivityCalendar(); @@ -322,7 +359,7 @@ void testSetActivityCalendarWithActivationFailure() throws ProtocolAdapterExcept catchThrowable( () -> this.executor.execute( - this.conn, this.DLMS_DEVICE, activityCalendar, this.messageMetadata)); + this.conn, this.dlmsDevice, activityCalendar, this.messageMetadata)); // VERIFY assertThat(thrown) diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/dlmsobjectconfig/DlmsObjectConfigServiceTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/dlmsobjectconfig/DlmsObjectConfigServiceTest.java index e5950f49bc0..1ed2ed775ab 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/dlmsobjectconfig/DlmsObjectConfigServiceTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/dlmsobjectconfig/DlmsObjectConfigServiceTest.java @@ -18,6 +18,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoSettings; @@ -261,7 +263,8 @@ void testProfileWithOneMedium() { channel, this.from, this.to, - filterMedium); + filterMedium, + true); // VERIFY assertThat(attributeAddressForProfile).isPresent(); @@ -271,25 +274,30 @@ void testProfileWithOneMedium() { .isEqualTo(this.captureObjectsE); } - @Test - void testProfileWithMediumCombinedAndFilterMedium() { + @ParameterizedTest + @ValueSource(booleans = {true, false}) + void testProfileWithMediumCombinedAndFilterMedium(final boolean selectedValuesSupported) { // SETUP final Integer channel = null; final Medium filterMedium = Medium.ELECTRICITY; final List expectedSelectedObjects = - this.captureObjectsCombined.stream() - .filter( - c -> - !(c.getRelatedObject() instanceof DlmsRegister) - || ((DlmsRegister) c.getRelatedObject()).getMedium() == filterMedium) - .collect(Collectors.toList()); + selectedValuesSupported + ? this.captureObjectsCombined.stream() + .filter( + c -> + !(c.getRelatedObject() instanceof DlmsRegister) + || ((DlmsRegister) c.getRelatedObject()).getMedium() == filterMedium) + .collect(Collectors.toList()) + : this.captureObjectsCombined; final DataObject selectedValues = - DataObject.newArrayData( - expectedSelectedObjects.stream() - .map(o -> this.getDataObject(o.getRelatedObject())) - .collect(Collectors.toList())); + selectedValuesSupported + ? DataObject.newArrayData( + expectedSelectedObjects.stream() + .map(o -> this.getDataObject(o.getRelatedObject())) + .collect(Collectors.toList())) + : DataObject.newArrayData(List.of()); final DataObject accessParams = this.getAccessParams(selectedValues); @@ -310,7 +318,8 @@ void testProfileWithMediumCombinedAndFilterMedium() { channel, this.from, this.to, - filterMedium); + filterMedium, + selectedValuesSupported); // VERIFY assertThat(attributeAddressForProfile).isPresent(); @@ -347,7 +356,8 @@ void testProfileWithMediumCombinedAndNoFilterMedium() { channel, this.from, this.to, - filterMedium); + filterMedium, + true); // VERIFY assertThat(attributeAddressForProfile).isPresent(); diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/firmware/UpdateFirmwareCommandExecutorIntegrationTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/firmware/UpdateFirmwareCommandExecutorIntegrationTest.java index 1a8dc366439..b2c6d7e0c49 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/firmware/UpdateFirmwareCommandExecutorIntegrationTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/firmware/UpdateFirmwareCommandExecutorIntegrationTest.java @@ -12,13 +12,14 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import java.nio.charset.StandardCharsets; import java.util.Collections; import org.apache.commons.lang3.RandomStringUtils; import org.bouncycastle.util.encoders.Hex; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.openmuc.jdlms.AttributeAddress; @@ -26,7 +27,6 @@ import org.openmuc.jdlms.MethodResultCode; import org.openmuc.jdlms.ObisCode; import org.openmuc.jdlms.datatypes.DataObject; -import org.opensmartgridplatform.adapter.protocol.dlms.application.config.UpdateFirmwareConfig; import org.opensmartgridplatform.adapter.protocol.dlms.application.services.MacGenerationService; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.firmware.ImageTransfer.ImageTransferProperties; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.stub.DlmsConnectionManagerStub; @@ -50,94 +50,175 @@ class UpdateFirmwareCommandExecutorIntegrationTest { @Mock private FirmwareFileCachingRepository firmwareFileCachingRepository; @Mock private FirmwareImageIdentifierCachingRepository firmwareImageIdentifierCachingRepository; @Mock private MacGenerationService macGenerationService; - @Mock private UpdateFirmwareConfig updateFirmwareConfig; private DlmsConnectionManagerStub connectionManagerStub; private DlmsConnectionStub connectionStub; private MessageMetadata messageMetadata; - private final int verificationStatusCheckInterval = 1; - private final int verificationStatusCheckTimeout = 2; - private final int initiationStatusCheckInterval = 3; - private final int initiationStatusCheckTimeout = 4; + final byte[] firmwareFileNotMbus = + org.bouncycastle.util.encoders.Hex.decode( + "0000000000230011004000310000001000020801e91effffffff500303000000000000831c9d5aa5b4f" + + "fbfd057035a8a7896a4abe7afa36687fbc48944bcee0343eed3a75aab882ec1cf57820adfd4394e262d" + + "5fa821c678e71c05c47e1c69c4bfffe1fd"); + + final String fwFileHashNotMBus = + "6e55dcd3ec19ea23b1ac2512dc9df827a4f8788cba4a76f49a91f158c4a5c4b3"; + final String fwFileHash = "951948459d2b7b59883cfc75c2bc2b7e4a0232ae7973a0d99526afd9458b0c86"; + final byte[] firmwareFileMbus = + org.bouncycastle.util.encoders.Hex.decode( + "534d523500230011004000310000001000020801e91effffffff500303000000000000831c9d5aa5b4f" + + "fbfd057035a8a7896a4abe7afa36687fbc48944bcee0343eed3a75aab882ec1cf57820adfd4394e262d" + + "5fa821c678e71c05c47e1c69c4bfffe1fd"); @BeforeEach void setUp() { + + this.messageMetadata = MessageMetadata.newBuilder().withCorrelationUid("123456").build(); + + final ImageTransferProperties imageTransferProperties = + new ImageTransfer.ImageTransferProperties(); + imageTransferProperties.setVerificationStatusCheckInterval(1); + imageTransferProperties.setVerificationStatusCheckTimeout(2); + imageTransferProperties.setInitiationStatusCheckInterval(3); + imageTransferProperties.setInitiationStatusCheckTimeout(4); + + this.commandExecutor = + new UpdateFirmwareCommandExecutor( + this.dlmsDeviceRepository, + this.firmwareFileCachingRepository, + this.firmwareImageIdentifierCachingRepository, + this.macGenerationService, + imageTransferProperties); + } + + private void initConnectionStubForTransfer( + final int firstTransferState, final int firstNotTransferredBlockNumber) { + this.connectionStub = new DlmsConnectionStub(); this.connectionManagerStub = new DlmsConnectionManagerStub(this.connectionStub); this.connectionStub.setDefaultReturnValue(DataObject.newArrayData(Collections.emptyList())); + if (firstTransferState > -1) { + this.connectionStub.addReturnValue( + this.createAttributeAddressForImageTransfer(ImageTransferAttribute.IMAGE_TRANSFER_STATUS), + DataObject.newInteger32Data(firstTransferState)); + } + this.connectionStub.addReturnValue( this.createAttributeAddressForImageTransfer(ImageTransferAttribute.IMAGE_TRANSFER_ENABLED), DataObject.newBoolData(true)); this.connectionStub.addReturnValue( this.createAttributeAddressForImageTransfer(ImageTransferAttribute.IMAGE_TRANSFER_STATUS), DataObject.newInteger32Data(1), - 5); - this.connectionStub.addReturnValue( - this.createAttributeAddressForImageTransfer(ImageTransferAttribute.IMAGE_TRANSFER_STATUS), - DataObject.newInteger32Data(6)); + 4); + + // configure the connection stub to follow either FromFirstBlock or ResumeOnBlocks flow + // If IMAGE_FIRST_NOT_TRANSFERRED_BLOCK_NUMBER is not the total number of blocks (10) + // then the flow goes ResumeOnBlocks this.connectionStub.addReturnValue( this.createAttributeAddressForImageTransfer(ImageTransferAttribute.IMAGE_BLOCK_SIZE), - DataObject.newUInteger32Data(100)); + DataObject.newUInteger32Data(10)); this.connectionStub.addReturnValue( this.createAttributeAddressForImageTransfer( ImageTransferAttribute.IMAGE_FIRST_NOT_TRANSFERRED_BLOCK_NUMBER), - DataObject.newUInteger32Data(100)); + DataObject.newUInteger32Data(firstNotTransferredBlockNumber)); - this.messageMetadata = MessageMetadata.newBuilder().withCorrelationUid("123456").build(); + // NO MissingImageBlocks after all blocks transferred + this.connectionStub.addReturnValue( + this.createAttributeAddressForImageTransfer( + ImageTransferAttribute.IMAGE_FIRST_NOT_TRANSFERRED_BLOCK_NUMBER), + DataObject.newUInteger32Data(10)); + + // Transfer state after all blocks transferred: VERIFICATION_INITIATED(2) + this.connectionStub.addReturnValue( + this.createAttributeAddressForImageTransfer(ImageTransferAttribute.IMAGE_TRANSFER_STATUS), + DataObject.newInteger32Data(2), + 4); + + // Transfer state after image verification: VERIFICATION_SUCCESSFUL(3) + this.connectionStub.addReturnValue( + this.createAttributeAddressForImageTransfer(ImageTransferAttribute.IMAGE_TRANSFER_STATUS), + DataObject.newInteger32Data(3)); final MethodResult methodResult = mock(MethodResult.class); when(methodResult.getResultCode()).thenReturn(MethodResultCode.SUCCESS); - final ImageTransferProperties imageTransferProperties = - new ImageTransfer.ImageTransferProperties(); - imageTransferProperties.setVerificationStatusCheckInterval( - this.verificationStatusCheckInterval); - imageTransferProperties.setVerificationStatusCheckTimeout(this.verificationStatusCheckTimeout); - imageTransferProperties.setInitiationStatusCheckInterval(this.initiationStatusCheckInterval); - imageTransferProperties.setInitiationStatusCheckTimeout(this.initiationStatusCheckTimeout); - this.connectionStub.setDefaultMethodResult(methodResult); + } - this.commandExecutor = - new UpdateFirmwareCommandExecutor( - this.dlmsDeviceRepository, - this.firmwareFileCachingRepository, - this.firmwareImageIdentifierCachingRepository, - this.macGenerationService, - imageTransferProperties); + @ParameterizedTest + @CsvSource({"true, false", "false, false"}) + void testExecuteFirmwareFileNotMBus(final boolean hasFwHash, final boolean fwHashIsEqual) + throws Exception { + + final DlmsDevice device = new DlmsDevice(); + final String firmwareIdentification = RandomStringUtils.randomAlphabetic(10); + final String deviceIdentification = RandomStringUtils.randomAlphabetic(10); + + device.setDeviceIdentification(deviceIdentification); + device.setFirmwareHash("hash_of_different_firmware"); + + final byte[] firmwareImageIdentifier = Hex.decode("496d6167654964656e746966696572"); + + when(this.firmwareFileCachingRepository.retrieve(firmwareIdentification)) + .thenReturn(this.firmwareFileNotMbus); + when(this.firmwareImageIdentifierCachingRepository.retrieve(firmwareIdentification)) + .thenReturn(firmwareImageIdentifier); + + // For some reason the first call to ImageTransfer.isInitiated() does not result in a + // call to the connectionStub to get value for attribute IMAGE_TRANSFER_STATUS + // with value -1 for firstTransState no returnValue for this call is defined + this.initConnectionStubForTransfer(-1, 10); + + final UpdateFirmwareRequestDto updateFirmwareRequestDto = + new UpdateFirmwareRequestDto(firmwareIdentification, deviceIdentification); + this.commandExecutor.execute( + this.connectionManagerStub, device, updateFirmwareRequestDto, this.messageMetadata); + + verify(this.dlmsDeviceRepository, never()).findByDeviceIdentification(deviceIdentification); + verify(this.dlmsDeviceRepository, times(1)).storeFirmwareHash(deviceIdentification, null); + verify(this.dlmsDeviceRepository, times(1)) + .storeFirmwareHash(deviceIdentification, this.fwFileHashNotMBus); + verify(this.macGenerationService, never()).calculateMac(any(), any(), any()); + verify(this.firmwareFileCachingRepository, times(1)).retrieve(firmwareIdentification); + verify(this.firmwareImageIdentifierCachingRepository, times(1)) + .retrieve(firmwareIdentification); + + this.assertImageTransferRelatedInteractionWithConnection(1, 10, 1); } @Test - void testExecute() throws Exception { + void testExecuteResumeOnBlocks() throws Exception { final DlmsDevice device = new DlmsDevice(); final String firmwareIdentification = RandomStringUtils.randomAlphabetic(10); final String deviceIdentification = RandomStringUtils.randomAlphabetic(10); - final byte[] firmwareFile = - RandomStringUtils.randomAlphabetic(100).getBytes(StandardCharsets.UTF_8); + device.setDeviceIdentification(deviceIdentification); + device.setFirmwareHash(this.fwFileHashNotMBus); final byte[] firmwareImageIdentifier = Hex.decode("496d6167654964656e746966696572"); when(this.firmwareFileCachingRepository.retrieve(firmwareIdentification)) - .thenReturn(firmwareFile); + .thenReturn(this.firmwareFileNotMbus); when(this.firmwareImageIdentifierCachingRepository.retrieve(firmwareIdentification)) .thenReturn(firmwareImageIdentifier); + this.initConnectionStubForTransfer(1, 3); + final UpdateFirmwareRequestDto updateFirmwareRequestDto = new UpdateFirmwareRequestDto(firmwareIdentification, deviceIdentification); this.commandExecutor.execute( this.connectionManagerStub, device, updateFirmwareRequestDto, this.messageMetadata); verify(this.dlmsDeviceRepository, never()).findByDeviceIdentification(deviceIdentification); + verify(this.dlmsDeviceRepository, times(1)).storeFirmwareHash(deviceIdentification, null); verify(this.macGenerationService, never()).calculateMac(any(), any(), any()); verify(this.firmwareFileCachingRepository, times(1)).retrieve(firmwareIdentification); verify(this.firmwareImageIdentifierCachingRepository, times(1)) .retrieve(firmwareIdentification); - this.assertImageTransferRelatedInteractionWithConnection(); + this.assertImageTransferRelatedInteractionWithConnection(0, 7, 1); } @Test @@ -148,39 +229,77 @@ void testExecuteMbusFirmware() throws Exception { final String deviceIdentification = RandomStringUtils.randomAlphabetic(10); device.setDeviceIdentification(deviceIdentification); - final byte[] firmwareFile = - org.bouncycastle.util.encoders.Hex.decode( - "534d523500230011004000310000001000020801e91effffffff500303000000000000831c9d5aa5b4f" - + "fbfd057035a8a7896a4abe7afa36687fbc48944bcee0343eed3a75aab882ec1cf57820adfd4394e262d" - + "5fa821c678e71c05c47e1c69c4bfffe1fd"); + when(this.dlmsDeviceRepository.findByDeviceIdentification(deviceIdentification)) + .thenReturn(device); + when(this.firmwareFileCachingRepository.retrieve(firmwareIdentification)) + .thenReturn(this.firmwareFileMbus); + when(this.macGenerationService.calculateMac(any(), any(), any())).thenReturn(new byte[16]); + + this.initConnectionStubForTransfer(-1, 10); + + final UpdateFirmwareRequestDto updateFirmwareRequestDto = + new UpdateFirmwareRequestDto(firmwareIdentification, deviceIdentification); + this.commandExecutor.execute( + this.connectionManagerStub, device, updateFirmwareRequestDto, this.messageMetadata); + + verify(this.dlmsDeviceRepository, times(1)).findByDeviceIdentification(deviceIdentification); + verify(this.dlmsDeviceRepository, times(1)).storeFirmwareHash(deviceIdentification, null); + verify(this.dlmsDeviceRepository, times(1)) + .storeFirmwareHash(deviceIdentification, this.fwFileHash); + verify(this.macGenerationService, times(1)).calculateMac(any(), any(), any()); + verify(this.firmwareFileCachingRepository, times(1)).retrieve(firmwareIdentification); + verify(this.firmwareImageIdentifierCachingRepository, never()).retrieve(firmwareIdentification); + + // this.assertImageTransferRelatedInteractionWithConnection(); + this.assertImageTransferRelatedInteractionWithConnection(1, 10, 0); + } + + @Test + void testExecuteMbusFirmwareResumeOnBlocks() throws Exception { + final DlmsDevice device = new DlmsDevice(); + device.setMbusIdentificationNumber("00000001"); + final String firmwareIdentification = RandomStringUtils.randomAlphabetic(10); + final String deviceIdentification = RandomStringUtils.randomAlphabetic(10); + device.setDeviceIdentification(deviceIdentification); + device.setFirmwareHash(this.fwFileHash); when(this.dlmsDeviceRepository.findByDeviceIdentification(deviceIdentification)) .thenReturn(device); when(this.firmwareFileCachingRepository.retrieve(firmwareIdentification)) - .thenReturn(firmwareFile); + .thenReturn(this.firmwareFileMbus); when(this.macGenerationService.calculateMac(any(), any(), any())).thenReturn(new byte[16]); + this.initConnectionStubForTransfer(1, 3); + final UpdateFirmwareRequestDto updateFirmwareRequestDto = new UpdateFirmwareRequestDto(firmwareIdentification, deviceIdentification); this.commandExecutor.execute( this.connectionManagerStub, device, updateFirmwareRequestDto, this.messageMetadata); verify(this.dlmsDeviceRepository, times(1)).findByDeviceIdentification(deviceIdentification); + verify(this.dlmsDeviceRepository, times(1)).storeFirmwareHash(deviceIdentification, null); verify(this.macGenerationService, times(1)).calculateMac(any(), any(), any()); verify(this.firmwareFileCachingRepository, times(1)).retrieve(firmwareIdentification); verify(this.firmwareImageIdentifierCachingRepository, never()).retrieve(firmwareIdentification); - this.assertImageTransferRelatedInteractionWithConnection(); + this.assertImageTransferRelatedInteractionWithConnection(0, 7, 0); } - private void assertImageTransferRelatedInteractionWithConnection() { + private void assertImageTransferRelatedInteractionWithConnection( + final long initiate, final long transfer, final long verify) { + final long activate = 1; assertThat( - this.connectionStub.hasMethodBeenInvoked(ImageTransferMethod.IMAGE_TRANSFER_INITIATE)) - .isTrue(); - assertThat(this.connectionStub.hasMethodBeenInvoked(ImageTransferMethod.IMAGE_BLOCK_TRANSFER)) - .isTrue(); - assertThat(this.connectionStub.hasMethodBeenInvoked(ImageTransferMethod.IMAGE_ACTIVATE)) - .isTrue(); + this.connectionStub.getMethodInvocationCount( + ImageTransferMethod.IMAGE_TRANSFER_INITIATE)) + .isEqualTo(initiate); + assertThat( + this.connectionStub.getMethodInvocationCount(ImageTransferMethod.IMAGE_BLOCK_TRANSFER)) + .isEqualTo(transfer); + + assertThat(this.connectionStub.getMethodInvocationCount(ImageTransferMethod.IMAGE_VERIFY)) + .isEqualTo(verify); + assertThat(this.connectionStub.getMethodInvocationCount(ImageTransferMethod.IMAGE_ACTIVATE)) + .isEqualTo(activate); assertThat(this.connectionStub.getSetParameters(ImageTransferAttribute.IMAGE_TRANSFER_ENABLED)) .isEmpty(); diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/misc/GetActualPowerQualityCommandExecutorTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/misc/GetActualPowerQualityCommandExecutorTest.java index 922a3a5b42c..af355493476 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/misc/GetActualPowerQualityCommandExecutorTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/misc/GetActualPowerQualityCommandExecutorTest.java @@ -15,7 +15,6 @@ import static org.mockito.Mockito.when; import static org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.AVERAGE_CURRENT_L1; import static org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.AVERAGE_REACTIVE_POWER_IMPORT_L1; -import static org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.AVERAGE_REACTIVE_POWER_IMPORT_L2; import static org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.INSTANTANEOUS_VOLTAGE_L1; import static org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.NUMBER_OF_POWER_FAILURES; @@ -26,7 +25,7 @@ import java.util.Collections; import java.util.EnumMap; import java.util.List; -import java.util.stream.Collectors; +import java.util.Map; import org.joda.time.DateTime; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -49,13 +48,17 @@ import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; import org.opensmartgridplatform.adapter.protocol.dlms.infra.messaging.DlmsMessageListener; import org.opensmartgridplatform.dlms.exceptions.ObjectConfigException; +import org.opensmartgridplatform.dlms.interfaceclass.attribute.RegisterAttribute; +import org.opensmartgridplatform.dlms.objectconfig.AccessType; import org.opensmartgridplatform.dlms.objectconfig.Attribute; import org.opensmartgridplatform.dlms.objectconfig.CosemObject; +import org.opensmartgridplatform.dlms.objectconfig.DlmsDataType; import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; import org.opensmartgridplatform.dlms.objectconfig.MeterType; import org.opensmartgridplatform.dlms.objectconfig.ObjectProperty; import org.opensmartgridplatform.dlms.objectconfig.PowerQualityProfile; import org.opensmartgridplatform.dlms.objectconfig.PowerQualityRequest; +import org.opensmartgridplatform.dlms.objectconfig.ValueType; import org.opensmartgridplatform.dlms.services.ObjectConfigService; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ActualPowerQualityRequestDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ActualPowerQualityResponseDto; @@ -75,6 +78,8 @@ class GetActualPowerQualityCommandExecutorTest { private static final MessageMetadata MESSAGE_METADATA = MessageMetadata.newBuilder().withCorrelationUid("123456").build(); + private static final int SCALER_VALUE = -1; + @Spy private DlmsHelper dlmsHelper; @Mock private ObjectConfigService objectConfigService; @@ -161,10 +166,9 @@ void executeAndAssert(final String profileType, final MeterType meterType) allObjectsThatShouldBeRequested.add(this.getClockObject()); allObjectsThatShouldBeRequested.addAll(allPqObjectsForThisMeter); final List allPqObjects = new ArrayList<>(allPqObjectsForThisMeter); - allPqObjects.add(this.getObjectWithWrongMeterType(meterType)); when(this.objectConfigService.getCosemObjectsWithProperties( - PROTOCOL_NAME, PROTOCOL_VERSION, this.getObjectProperties(profileType))) + PROTOCOL_NAME, PROTOCOL_VERSION, this.getObjectProperties(profileType, meterType))) .thenReturn(allPqObjects); this.actualPowerQualityRequestDto = new ActualPowerQualityRequestDto(profileType); @@ -211,6 +215,7 @@ void executeAndAssert(final String profileType, final MeterType meterType) final PowerQualityValueDto powerQualityValue = responseDto.getActualPowerQualityData().getPowerQualityValues().get(i); + this.assertValue(powerQualityValue.getValue(), i, object); } } @@ -234,6 +239,9 @@ private void assertValue(final Serializable value, final int i, final CosemObjec } private byte getScaler(final CosemObject object) { + if (this.readScalerValueFromMeter(object)) { + return SCALER_VALUE; + } final String scalerUnit = object.getAttribute(ATTRIBUTE_ID_SCALER_UNIT).getValue(); return Byte.parseByte(scalerUnit.split(",")[0]); } @@ -260,26 +268,31 @@ private String getExpectedUnit(final CosemObject object) { private CosemObject getClockObject() { - final CosemObject clock = new CosemObject(); - clock.setClassId(8); - clock.setObis("0.0.1.0.0.255"); - clock.setTag(DlmsObjectType.CLOCK.name()); - - return clock; + return this.createCosemObject(DlmsObjectType.CLOCK.name(), 8, "0.0.1.0.0.255"); } private List getObjects(final MeterType meterType) { final CosemObject dataObject = this.createObject( - CLASS_ID_DATA, "1.0.0.0.0.1", NUMBER_OF_POWER_FAILURES.name(), null, meterType); + CLASS_ID_DATA, "1.0.0.0.0.1", NUMBER_OF_POWER_FAILURES.name(), null, null, meterType); final CosemObject registerVoltObject = this.createObject( - CLASS_ID_REGISTER, "3.0.0.0.0.1", INSTANTANEOUS_VOLTAGE_L1.name(), "0, V", meterType); + CLASS_ID_REGISTER, + "3.0.0.0.0.1", + INSTANTANEOUS_VOLTAGE_L1.name(), + "0, V", + ValueType.DYNAMIC, + meterType); final CosemObject registerAmpereObject = this.createObject( - CLASS_ID_REGISTER, "3.0.0.0.0.2", AVERAGE_CURRENT_L1.name(), "-1, A", meterType); + CLASS_ID_REGISTER, + "3.0.0.0.0.2", + AVERAGE_CURRENT_L1.name(), + "-1, A", + ValueType.FIXED_IN_PROFILE, + meterType); final CosemObject registerVarObject = this.createObject( @@ -287,6 +300,7 @@ private List getObjects(final MeterType meterType) { "3.0.0.0.0.3", AVERAGE_REACTIVE_POWER_IMPORT_L1.name(), "2, VAR", + ValueType.FIXED_IN_PROFILE, meterType); return new ArrayList<>( @@ -298,40 +312,23 @@ private CosemObject createObject( final String obis, final String tag, final String scalerUnitValue, + final ValueType valueType, final MeterType meterType) { - final CosemObject object = new CosemObject(); - object.setClassId(classId); - object.setObis(obis); - object.setTag(tag); - if (scalerUnitValue != null) { - object.setAttributes(this.createScalerUnitAttributeList(scalerUnitValue)); - } - object.setMeterTypes(this.getMeterTypes(meterType)); - - return object; + return this.createCosemObject(tag, classId, obis, scalerUnitValue, valueType, meterType); } - private List createScalerUnitAttributeList(final String value) { - final Attribute scalerUnitAttribute = new Attribute(); - scalerUnitAttribute.setId(ATTRIBUTE_ID_SCALER_UNIT); - scalerUnitAttribute.setValue(value); - return Collections.singletonList(scalerUnitAttribute); - } - - private CosemObject getObjectWithWrongMeterType(final MeterType meterType) { - - // This object has the wrong meter type. The value shouldn't be requested by the commandexecutor - final CosemObject objectWithWrongMeterType = new CosemObject(); - objectWithWrongMeterType.setClassId(CLASS_ID_DATA); - objectWithWrongMeterType.setObis("1.0.0.0.0.2"); - objectWithWrongMeterType.setTag(AVERAGE_REACTIVE_POWER_IMPORT_L2.name()); - if (meterType.equals(MeterType.PP)) { - objectWithWrongMeterType.setMeterTypes(Collections.singletonList(MeterType.SP)); - } else { - objectWithWrongMeterType.setMeterTypes(Collections.singletonList(MeterType.PP)); - } - - return objectWithWrongMeterType; + private List createScalerUnitAttributeList( + final String value, final ValueType valueType) { + return List.of( + new Attribute( + ATTRIBUTE_ID_SCALER_UNIT, + "descr", + null, + DlmsDataType.DONT_CARE, + valueType, + value, + null, + AccessType.RW)); } private List getMeterTypes(final MeterType meterType) { @@ -355,27 +352,81 @@ private List generateMockedResult( resultCode)); } else { results.add(new GetResultImpl(DataObject.newInteger64Data(idx++), resultCode)); + if (this.readScalerValueFromMeter(object)) { + + final DataObject scalerValue = + DataObject.newArrayData( + Arrays.asList( + DataObject.newInteger32Data(SCALER_VALUE), DataObject.newInteger32Data(35))); + results.add(new GetResultImpl(scalerValue, resultCode)); + } } } return results; } - private EnumMap> getObjectProperties(final String profile) { + private boolean readScalerValueFromMeter(final CosemObject pqObject) { + if (!pqObject.hasAttribute(RegisterAttribute.SCALER_UNIT.attributeId())) { + return false; + } + final Attribute attribute = pqObject.getAttribute(RegisterAttribute.SCALER_UNIT.attributeId()); + return attribute.getValuetype() != ValueType.FIXED_IN_PROFILE; + } + + private EnumMap> getObjectProperties( + final String profile, final MeterType meterType) { // Create map with the required properties and values for the power quality objects - final EnumMap> pqProperties = new EnumMap<>(ObjectProperty.class); + final EnumMap> pqProperties = new EnumMap<>(ObjectProperty.class); pqProperties.put(ObjectProperty.PQ_PROFILE, Collections.singletonList(profile)); pqProperties.put( ObjectProperty.PQ_REQUEST, - Arrays.asList(PowerQualityRequest.ONDEMAND.name(), PowerQualityRequest.BOTH.name())); + List.of( + meterType == MeterType.SP + ? PowerQualityRequest.ACTUAL_SP.name() + : PowerQualityRequest.ACTUAL_PP.name())); return pqProperties; } private List getAttributeAddresses(final List objects) { - return objects.stream() - .map( - object -> - new AttributeAddress(object.getClassId(), object.getObis(), ATTRIBUTE_ID_VALUE)) - .collect(Collectors.toList()); + final List attributeAddresses = new ArrayList<>(); + for (final CosemObject cosemObject : objects) { + attributeAddresses.add( + new AttributeAddress( + cosemObject.getClassId(), cosemObject.getObis(), ATTRIBUTE_ID_VALUE)); + if (this.readScalerValueFromMeter(cosemObject)) { + attributeAddresses.add( + new AttributeAddress( + cosemObject.getClassId(), cosemObject.getObis(), ATTRIBUTE_ID_SCALER_UNIT)); + } + } + return attributeAddresses; + } + + private CosemObject createCosemObject(final String tag, final int classId, final String obis) { + return new CosemObject( + tag, "descr", classId, 0, obis, "group", null, List.of(), Map.of(), List.of()); + } + + private CosemObject createCosemObject( + final String tag, + final int classId, + final String obis, + final String scalerUnitValue, + final ValueType valueType, + final MeterType meterType) { + return new CosemObject( + tag, + "descr", + classId, + 0, + obis, + "group", + null, + this.getMeterTypes(meterType), + Map.of(), + scalerUnitValue != null + ? this.createScalerUnitAttributeList(scalerUnitValue, valueType) + : List.of()); } } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/misc/GetGsmDiagnosticCommandExecutorIntegrationTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/misc/GetGsmDiagnosticCommandExecutorIntegrationTest.java index 03c0f870c35..29f02eed193 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/misc/GetGsmDiagnosticCommandExecutorIntegrationTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/misc/GetGsmDiagnosticCommandExecutorIntegrationTest.java @@ -30,7 +30,6 @@ import org.opensmartgridplatform.dlms.exceptions.ObjectConfigException; import org.opensmartgridplatform.dlms.services.ObjectConfigService; import org.opensmartgridplatform.dto.valueobjects.smartmetering.AdjacentCellInfoDto; -import org.opensmartgridplatform.dto.valueobjects.smartmetering.BitErrorRateDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.CellInfoDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.CircuitSwitchedStatusDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.GetGsmDiagnosticRequestDto; @@ -53,10 +52,10 @@ class GetGsmDiagnosticCommandExecutorIntegrationTest { @ParameterizedTest @CsvSource({ "DSMR_4_2_2,CDMA,false", - "DSMR_4_2_2,GPRS,true", + "DSMR_4_2_2,GPRS,false", "DSMR_4_2_2,LTE,false", "SMR_4_3,CDMA,true", - "SMR_4_3,GPRS,true", + "SMR_4_3,GPRS,false", "SMR_4_3,LTE,false", "SMR_5_0_0,CDMA,true", "SMR_5_0_0,GPRS,true", @@ -81,7 +80,7 @@ void executeAndValidate( @BeforeEach public void setUp() throws IOException, ObjectConfigException { - this.objectConfigService = new ObjectConfigService(null); + this.objectConfigService = new ObjectConfigService(); final DlmsHelper dlmsHelper = new DlmsHelper(); @@ -170,7 +169,7 @@ private void executeAndValidate( assertThat(cellInfo.getCellId()).isEqualTo(93L); assertThat(cellInfo.getLocationId()).isEqualTo(2232); assertThat(cellInfo.getSignalQuality()).isEqualTo(SignalQualityDto.MINUS_87_DBM); - assertThat(cellInfo.getBitErrorRate()).isEqualTo(BitErrorRateDto.RXQUAL_6); + assertThat(cellInfo.getBitErrorRate()).isEqualTo(6); assertThat(cellInfo.getMobileCountryCode()).isEqualTo(204); assertThat(cellInfo.getMobileNetworkCode()).isEqualTo(66); assertThat(cellInfo.getChannelNumber()).isEqualTo(107); diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/misc/GetGsmDiagnosticCommandExecutorTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/misc/GetGsmDiagnosticCommandExecutorTest.java index c78ed437b6c..9a39f2e08a7 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/misc/GetGsmDiagnosticCommandExecutorTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/misc/GetGsmDiagnosticCommandExecutorTest.java @@ -18,6 +18,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoSettings; @@ -35,7 +37,6 @@ import org.opensmartgridplatform.dlms.exceptions.ObjectConfigException; import org.opensmartgridplatform.dlms.interfaceclass.InterfaceClass; import org.opensmartgridplatform.dlms.services.ObjectConfigService; -import org.opensmartgridplatform.dto.valueobjects.smartmetering.BitErrorRateDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.CircuitSwitchedStatusDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.GetGsmDiagnosticRequestDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.GetGsmDiagnosticResponseDto; @@ -60,13 +61,15 @@ class GetGsmDiagnosticCommandExecutorTest { private final DlmsDevice device = this.createDevice(Protocol.SMR_5_1, CommunicationMethod.CDMA); private final int classId = InterfaceClass.GSM_DIAGNOSTIC.id(); - private final String obisCode = "0.1.25.6.0.255"; + private final String obisCodeGsm = "0.0.25.6.0.255"; + private final String obisCodeCdma = "0.1.25.6.0.255"; + private final String obisCodeLte = "0.2.25.6.0.255"; private final GetGsmDiagnosticRequestDto request = new GetGsmDiagnosticRequestDto(); private MessageMetadata messageMetadata; @BeforeEach public void setUp() throws IOException, ObjectConfigException { - this.objectConfigService = new ObjectConfigService(null); + this.objectConfigService = new ObjectConfigService(); this.executor = new GetGsmDiagnosticCommandExecutor(this.dlmsHelper, this.objectConfigService); this.messageMetadata = MessageMetadata.newBuilder().withCorrelationUid("123456").build(); @@ -91,8 +94,11 @@ void testExecuteObjectNotFound() throws ProtocolAdapterException { } } - @Test - void testHappy() throws Exception { + @ParameterizedTest + @EnumSource(CommunicationMethod.class) + void testHappy(final CommunicationMethod communicationMethod) throws Exception { + + final DlmsDevice testDevice = this.createDevice(Protocol.SMR_5_2, communicationMethod); // SETUP - mock return data objects final GetResult result2 = mock(GetResult.class); @@ -157,25 +163,26 @@ void testHappy() throws Exception { when(adjacentCellSignalQuality.getValue()).thenReturn((short) 7); when(this.dlmsHelper.getAndCheck( - eq(this.connectionManager), eq(this.device), eq("Get GsmDiagnostic"), any())) + eq(this.connectionManager), eq(testDevice), eq("Get GsmDiagnostic"), any())) .thenReturn(Arrays.asList(result2, result3, result4, result5, result6, result7)); // CALL final GetGsmDiagnosticResponseDto result = this.executor.execute( - this.connectionManager, this.device, this.request, this.messageMetadata); + this.connectionManager, testDevice, this.request, this.messageMetadata); // VERIFY calls to mocks + final String obisCode = this.getObisCode(communicationMethod); verify(this.dlmsMessageListener) .setDescription( String.format( "Get GsmDiagnostic, retrieve attributes: %s, %s, %s, %s, %s, %s", - this.createAttributeAddress(2), - this.createAttributeAddress(3), - this.createAttributeAddress(4), - this.createAttributeAddress(5), - this.createAttributeAddress(6), - this.createAttributeAddress(7))); + this.createAttributeAddress(obisCode, 2), + this.createAttributeAddress(obisCode, 3), + this.createAttributeAddress(obisCode, 4), + this.createAttributeAddress(obisCode, 5), + this.createAttributeAddress(obisCode, 6), + this.createAttributeAddress(obisCode, 7))); // VERIFY contents of the return value assertThat(result.getOperator()).isEqualTo("AB"); @@ -189,7 +196,7 @@ void testHappy() throws Exception { assertThat(result.getCellInfo().getLocationId()).isEqualTo(1); assertThat(result.getCellInfo().getSignalQuality()) .isEqualTo(SignalQualityDto.fromIndexValue(2)); - assertThat(result.getCellInfo().getBitErrorRate()).isEqualTo(BitErrorRateDto.fromIndexValue(3)); + assertThat(result.getCellInfo().getBitErrorRate()).isEqualTo(3); assertThat(result.getCellInfo().getMobileCountryCode()).isEqualTo(4); assertThat(result.getCellInfo().getMobileNetworkCode()).isEqualTo(5); assertThat(result.getCellInfo().getChannelNumber()).isEqualTo(6); @@ -199,6 +206,21 @@ void testHappy() throws Exception { .isEqualTo(SignalQualityDto.fromIndexValue(7)); } + private String getObisCode(final CommunicationMethod communicationMethod) { + switch (communicationMethod) { + case LTE -> { + return this.obisCodeLte; + } + case GPRS -> { + return this.obisCodeGsm; + } + case CDMA -> { + return this.obisCodeCdma; + } + } + return null; + } + @Test void testUnhappy() throws Exception { @@ -222,8 +244,8 @@ void testUnhappy() throws Exception { } } - private String createAttributeAddress(final int attributeId) { - return String.format("{%s,%s,%d}", this.classId, this.obisCode, attributeId); + private String createAttributeAddress(final String obisCode, final int attributeId) { + return String.format("{%s,%s,%d}", this.classId, obisCode, attributeId); } private DlmsDevice createDevice(final Protocol protocol, final CommunicationMethod method) { diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/monitoring/GetPowerQualityProfileNoSelectiveAccessHandlerTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/monitoring/GetPowerQualityProfileNoSelectiveAccessHandlerTest.java index 43dacab6d0a..816fba98f4a 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/monitoring/GetPowerQualityProfileNoSelectiveAccessHandlerTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/monitoring/GetPowerQualityProfileNoSelectiveAccessHandlerTest.java @@ -10,6 +10,7 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; import static org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.DEFINABLE_LOAD_PROFILE; +import static org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.INSTANTANEOUS_VOLTAGE_L1; import static org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.POWER_QUALITY_PROFILE_1; import static org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.POWER_QUALITY_PROFILE_2; @@ -18,6 +19,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.Optional; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; @@ -33,6 +35,7 @@ import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionManager; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; import org.opensmartgridplatform.dlms.exceptions.ObjectConfigException; +import org.opensmartgridplatform.dlms.interfaceclass.attribute.RegisterAttribute; import org.opensmartgridplatform.dlms.objectconfig.CosemObject; import org.opensmartgridplatform.dlms.objectconfig.PowerQualityProfile; import org.opensmartgridplatform.dlms.services.ObjectConfigService; @@ -64,6 +67,18 @@ void testHandlePublicOrPrivateProfileWithoutSelectiveAccessWithPartialNonAllowed Date.from(Instant.now().minus(2, ChronoUnit.DAYS)), new Date(), new ArrayList<>()); + + final CosemObject cosemObjectInstVoltage = + allPqObjectsForThisMeter.stream() + .filter(obj -> obj.getTag().equals(INSTANTANEOUS_VOLTAGE_L1.name())) + .findFirst() + .get(); + when(this.dlmsHelper.getScalerUnitValue(this.conn, cosemObjectInstVoltage)) + .thenReturn( + cosemObjectInstVoltage + .getAttribute(RegisterAttribute.SCALER_UNIT.attributeId()) + .getValue()); + when(this.dlmsHelper.readLogicalName(any(DataObject.class), any(String.class))) .thenCallRealMethod(); when(this.dlmsHelper.readObjectDefinition(any(DataObject.class), any(String.class))) @@ -76,15 +91,15 @@ void testHandlePublicOrPrivateProfileWithoutSelectiveAccessWithPartialNonAllowed .thenCallRealMethod(); when(this.dlmsHelper.convertDataObjectToDateTime(any(DataObject.class))).thenCallRealMethod(); when(this.dlmsHelper.fromDateTimeValue(any())).thenCallRealMethod(); - when(this.objectConfigService.getCosemObject( + when(this.objectConfigService.getOptionalCosemObject( PROTOCOL_NAME, PROTOCOL_VERSION, POWER_QUALITY_PROFILE_2)) .thenReturn( this.createProfile(PQ_PROFILE_2, "POWER_QUALITY_PROFILE_2", PQ_PROFILE_2_INTERVAL)); - when(this.objectConfigService.getCosemObject( + when(this.objectConfigService.getOptionalCosemObject( PROTOCOL_NAME, PROTOCOL_VERSION, POWER_QUALITY_PROFILE_1)) .thenReturn( this.createProfile(PQ_DEFINABLE, "DEFINABLE_LOAD_PROFILE", PQ_DEFINABLE_INTERVAL)); - when(this.objectConfigService.getCosemObject( + when(this.objectConfigService.getOptionalCosemObject( PROTOCOL_NAME, PROTOCOL_VERSION, DEFINABLE_LOAD_PROFILE)) .thenReturn( this.createProfile(PQ_PROFILE_1, "POWER_QUALITY_PROFILE_1", PQ_PROFILE_1_INTERVAL)); @@ -135,15 +150,15 @@ void testHandlePublicOrPrivateProfileWithInvalidConfigThrowsException( new ArrayList<>()); when(this.dlmsHelper.readObjectDefinition(any(DataObject.class), any(String.class))) .thenCallRealMethod(); - when(this.objectConfigService.getCosemObject( + when(this.objectConfigService.getOptionalCosemObject( PROTOCOL_NAME, PROTOCOL_VERSION, POWER_QUALITY_PROFILE_2)) .thenReturn( this.createProfile(PQ_PROFILE_2, "POWER_QUALITY_PROFILE_2", PQ_PROFILE_2_INTERVAL)); - when(this.objectConfigService.getCosemObject( + when(this.objectConfigService.getOptionalCosemObject( PROTOCOL_NAME, PROTOCOL_VERSION, POWER_QUALITY_PROFILE_1)) .thenReturn( this.createProfile(PQ_DEFINABLE, "DEFINABLE_LOAD_PROFILE", PQ_DEFINABLE_INTERVAL)); - when(this.objectConfigService.getCosemObject( + when(this.objectConfigService.getOptionalCosemObject( PROTOCOL_NAME, PROTOCOL_VERSION, DEFINABLE_LOAD_PROFILE)) .thenReturn( this.createProfile(PQ_PROFILE_1, "POWER_QUALITY_PROFILE_1", PQ_PROFILE_1_INTERVAL)); @@ -176,7 +191,7 @@ void testInvalidProfileThrowsIllegalArgumentException(final PowerQualityProfile Date.from(Instant.now().minus(2, ChronoUnit.DAYS)), new Date(), new ArrayList<>()); - when(this.objectConfigService.getCosemObject( + when(this.objectConfigService.getOptionalCosemObject( PROTOCOL_NAME, PROTOCOL_VERSION, DEFINABLE_LOAD_PROFILE)) .thenThrow(new IllegalArgumentException("IllegalArgumentException")); @@ -199,7 +214,7 @@ void testInvalidProfileThrowsObjectConfigException(final PowerQualityProfile pro Date.from(Instant.now().minus(2, ChronoUnit.DAYS)), new Date(), new ArrayList<>()); - when(this.objectConfigService.getCosemObject( + when(this.objectConfigService.getOptionalCosemObject( PROTOCOL_NAME, PROTOCOL_VERSION, DEFINABLE_LOAD_PROFILE)) .thenThrow(new ObjectConfigException("exception")); @@ -212,6 +227,35 @@ void testInvalidProfileThrowsObjectConfigException(final PowerQualityProfile pro () -> handler.handle(this.conn, this.dlmsDevice, requestDto)); } + @ParameterizedTest + @EnumSource(PowerQualityProfile.class) + void testSkipIfProfileDoesNotContainObject(final PowerQualityProfile profile) + throws ObjectConfigException, ProtocolAdapterException { + final GetPowerQualityProfileRequestDataDto requestDto = + new GetPowerQualityProfileRequestDataDto( + profile.name(), + Date.from(Instant.now().minus(2, ChronoUnit.DAYS)), + new Date(), + new ArrayList<>()); + when(this.objectConfigService.getOptionalCosemObject( + PROTOCOL_NAME, PROTOCOL_VERSION, DEFINABLE_LOAD_PROFILE)) + .thenReturn(Optional.empty()); + when(this.objectConfigService.getOptionalCosemObject( + PROTOCOL_NAME, PROTOCOL_VERSION, POWER_QUALITY_PROFILE_1)) + .thenReturn(Optional.empty()); + when(this.objectConfigService.getOptionalCosemObject( + PROTOCOL_NAME, PROTOCOL_VERSION, POWER_QUALITY_PROFILE_2)) + .thenReturn(Optional.empty()); + + final GetPowerQualityProfileNoSelectiveAccessHandler handler = + new GetPowerQualityProfileNoSelectiveAccessHandler( + this.dlmsHelper, this.objectConfigService); + + final GetPowerQualityProfileResponseDto responseDto = + handler.handle(this.conn, this.dlmsDevice, requestDto); + assertThat(responseDto.getPowerQualityProfileResponseDatas()).hasSize(0); + } + private List createInvalidCaptureObjects() { final DataObject invalidObject = DataObject.newStructureData( diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/monitoring/GetPowerQualityProfileSelectiveAccessHandlerTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/monitoring/GetPowerQualityProfileSelectiveAccessHandlerTest.java index a227051f28a..2e64502c949 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/monitoring/GetPowerQualityProfileSelectiveAccessHandlerTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/monitoring/GetPowerQualityProfileSelectiveAccessHandlerTest.java @@ -9,6 +9,7 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; import static org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.DEFINABLE_LOAD_PROFILE; +import static org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.INSTANTANEOUS_VOLTAGE_L1; import static org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.POWER_QUALITY_PROFILE_1; import static org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.POWER_QUALITY_PROFILE_2; @@ -17,6 +18,8 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.Optional; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; @@ -29,6 +32,7 @@ import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionManager; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; import org.opensmartgridplatform.dlms.exceptions.ObjectConfigException; +import org.opensmartgridplatform.dlms.interfaceclass.attribute.RegisterAttribute; import org.opensmartgridplatform.dlms.objectconfig.CosemObject; import org.opensmartgridplatform.dlms.objectconfig.PowerQualityProfile; import org.opensmartgridplatform.dlms.services.ObjectConfigService; @@ -42,6 +46,12 @@ class GetPowerQualityProfileSelectiveAccessHandlerTest extends GetPowerQualityPr @Mock private DlmsDevice dlmsDevice; @Mock private ObjectConfigService objectConfigService; + @BeforeEach + public void init() { + when(this.dlmsDevice.getProtocolName()).thenReturn(PROTOCOL_NAME); + when(this.dlmsDevice.getProtocolVersion()).thenReturn(PROTOCOL_VERSION); + } + @ParameterizedTest @EnumSource(PowerQualityProfile.class) void testHandlePublicOrPrivateProfileWithSelectiveAccessWithPartialNonAllowedObjects( @@ -54,8 +64,18 @@ void testHandlePublicOrPrivateProfileWithSelectiveAccessWithPartialNonAllowedObj Date.from(Instant.now().minus(2, ChronoUnit.DAYS)), new Date(), new ArrayList<>()); - when(this.dlmsDevice.getProtocolName()).thenReturn(PROTOCOL_NAME); - when(this.dlmsDevice.getProtocolVersion()).thenReturn(PROTOCOL_VERSION); + + final CosemObject cosemObjectInstVoltage = + allPqObjectsForThisMeter.stream() + .filter(obj -> obj.getTag().equals(INSTANTANEOUS_VOLTAGE_L1.name())) + .findFirst() + .get(); + when(this.dlmsHelper.getScalerUnitValue(this.conn, cosemObjectInstVoltage)) + .thenReturn( + cosemObjectInstVoltage + .getAttribute(RegisterAttribute.SCALER_UNIT.attributeId()) + .getValue()); + when(this.dlmsHelper.readLogicalName(any(DataObject.class), any(String.class))) .thenCallRealMethod(); when(this.dlmsHelper.readObjectDefinition(any(DataObject.class), any(String.class))) @@ -69,15 +89,15 @@ void testHandlePublicOrPrivateProfileWithSelectiveAccessWithPartialNonAllowedObj when(this.dlmsHelper.convertDataObjectToDateTime(any(DataObject.class))).thenCallRealMethod(); when(this.dlmsHelper.fromDateTimeValue(any())).thenCallRealMethod(); - when(this.objectConfigService.getCosemObject( + when(this.objectConfigService.getOptionalCosemObject( PROTOCOL_NAME, PROTOCOL_VERSION, POWER_QUALITY_PROFILE_2)) .thenReturn( this.createProfile(PQ_PROFILE_2, "POWER_QUALITY_PROFILE_2", PQ_PROFILE_2_INTERVAL)); - when(this.objectConfigService.getCosemObject( + when(this.objectConfigService.getOptionalCosemObject( PROTOCOL_NAME, PROTOCOL_VERSION, POWER_QUALITY_PROFILE_1)) .thenReturn( this.createProfile(PQ_PROFILE_1, "POWER_QUALITY_PROFILE_1", PQ_PROFILE_1_INTERVAL)); - when(this.objectConfigService.getCosemObject( + when(this.objectConfigService.getOptionalCosemObject( PROTOCOL_NAME, PROTOCOL_VERSION, DEFINABLE_LOAD_PROFILE)) .thenReturn( this.createProfile(PQ_DEFINABLE, "DEFINABLE_LOAD_PROFILE", PQ_DEFINABLE_INTERVAL)); @@ -111,4 +131,32 @@ void testHandlePublicOrPrivateProfileWithSelectiveAccessWithPartialNonAllowedObj this.verifyResponseData(responseDto, PQ_PROFILE_2, PQ_PROFILE_2_INTERVAL); this.verifyResponseData(responseDto, PQ_DEFINABLE, PQ_DEFINABLE_INTERVAL); } + + @ParameterizedTest + @EnumSource(PowerQualityProfile.class) + void testSkipIfProfileDoesNotContainObject(final PowerQualityProfile profile) + throws ObjectConfigException, ProtocolAdapterException { + final GetPowerQualityProfileRequestDataDto requestDto = + new GetPowerQualityProfileRequestDataDto( + profile.name(), + Date.from(Instant.now().minus(2, ChronoUnit.DAYS)), + new Date(), + new ArrayList<>()); + when(this.objectConfigService.getOptionalCosemObject( + PROTOCOL_NAME, PROTOCOL_VERSION, DEFINABLE_LOAD_PROFILE)) + .thenReturn(Optional.empty()); + when(this.objectConfigService.getOptionalCosemObject( + PROTOCOL_NAME, PROTOCOL_VERSION, POWER_QUALITY_PROFILE_1)) + .thenReturn(Optional.empty()); + when(this.objectConfigService.getOptionalCosemObject( + PROTOCOL_NAME, PROTOCOL_VERSION, POWER_QUALITY_PROFILE_2)) + .thenReturn(Optional.empty()); + + final GetPowerQualityProfileSelectiveAccessHandler handler = + new GetPowerQualityProfileSelectiveAccessHandler(this.dlmsHelper, this.objectConfigService); + + final GetPowerQualityProfileResponseDto responseDto = + handler.handle(this.conn, this.dlmsDevice, requestDto); + assertThat(responseDto.getPowerQualityProfileResponseDatas()).hasSize(0); + } } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/monitoring/GetPowerQualityProfileTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/monitoring/GetPowerQualityProfileTest.java index baf9e3b391d..3bebbabe3b5 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/monitoring/GetPowerQualityProfileTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/monitoring/GetPowerQualityProfileTest.java @@ -10,6 +10,7 @@ import static org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.AVERAGE_REACTIVE_POWER_IMPORT_L1; import static org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.CLOCK; import static org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.INSTANTANEOUS_VOLTAGE_L1; +import static org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.LTE_DIAGNOSTIC; import static org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.NUMBER_OF_VOLTAGE_SAGS_FOR_L1; import static org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.NUMBER_OF_VOLTAGE_SAGS_FOR_L2; @@ -32,6 +33,7 @@ import org.opensmartgridplatform.dlms.objectconfig.CosemObject; import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; import org.opensmartgridplatform.dlms.objectconfig.ObjectProperty; +import org.opensmartgridplatform.dlms.objectconfig.PowerQualityRequest; import org.opensmartgridplatform.dto.valueobjects.smartmetering.CaptureObjectDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.GetPowerQualityProfileResponseDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.PowerQualityProfileDataDto; @@ -51,14 +53,17 @@ public abstract class GetPowerQualityProfileTest { private static final int CLASS_ID_REGISTER = 3; private static final int CLASS_ID_PROFILE = 7; private static final int CLASS_ID_CLOCK = 8; + private static final int CLASS_ID_GSM_DIAGNOSTIC = 47; private static final int PROFILE_CAPTURE_OBJECTS_ATTR_ID = 3; private static final int PROFILE_INTERVAL_ATTR_ID = 4; private static final int SECONDS_PER_MINUTE = 60; private static final String OBIS_INSTANTANEOUS_VOLTAGE_L1 = "1.0.32.7.0.255"; private static final String OBIS_CLOCK = "0.0.1.0.0.255"; + private static final String OBIS_LTE_DIAGNOSTIC = "0.2.25.6.0.255"; private static final String UNIT_VOLT = "V"; private static final String UNIT_UNDEFINED = "UNDEFINED"; private static final int[] VALUES = new int[] {8, 7, 6, 5}; + private static final int[] SIGNAL_STRENGTH_ENUM_VALUES = new int[] {20, 21, 22, 23}; public static CosemObject createObject( final int classId, @@ -68,42 +73,40 @@ public static CosemObject createObject( final boolean polyphase, final String publicOrPrivate) { - final CosemObject object = - ObjectConfigServiceHelper.createObject(classId, obis, tag, scalerUnitValue, polyphase); - final Map properties = new HashMap<>(); properties.put(ObjectProperty.PQ_PROFILE, publicOrPrivate); - object.setProperties(properties); + properties.put( + ObjectProperty.PQ_REQUEST, + List.of(PowerQualityRequest.PERIODIC_SP.name(), PowerQualityRequest.PERIODIC_PP.name())); - return object; + return ObjectConfigServiceHelper.createObject( + classId, obis, tag, scalerUnitValue, polyphase, properties); } - protected CosemObject createProfile( + protected Optional createProfile( final String obis, final String tag, final int intervalInMinutes) { - final CosemObject object = - ObjectConfigServiceHelper.createObject(CLASS_ID_PROFILE, obis, tag, null, true); - final Map properties = new HashMap<>(); final List stringProperties = this.getPropertyObjects().stream() .map(DlmsObjectType::toString) .collect(Collectors.toList()); properties.put(ObjectProperty.SELECTABLE_OBJECTS, stringProperties); - object.setProperties(properties); final List attributeList = new ArrayList<>(); - final Attribute attribute = new Attribute(); - attribute.setId(PROFILE_CAPTURE_OBJECTS_ATTR_ID); - attribute.setValue("1"); + final Attribute attribute = + ObjectConfigServiceHelper.createAttribute(PROFILE_CAPTURE_OBJECTS_ATTR_ID, "1"); attributeList.add(attribute); - final Attribute attributeInterval = new Attribute(); - attributeInterval.setId(PROFILE_INTERVAL_ATTR_ID); - attributeInterval.setValue(String.valueOf(intervalInMinutes * SECONDS_PER_MINUTE)); + final Attribute attributeInterval = + ObjectConfigServiceHelper.createAttribute( + PROFILE_INTERVAL_ATTR_ID, String.valueOf(intervalInMinutes * SECONDS_PER_MINUTE)); attributeList.add(attributeInterval); - object.setAttributes(attributeList); - return object; + final CosemObject object = + ObjectConfigServiceHelper.createObject( + CLASS_ID_PROFILE, obis, tag, true, properties, attributeList); + + return Optional.of(object); } protected List getObjects(final boolean polyphase, final String publicOrPrivate) { @@ -146,9 +149,23 @@ protected List getObjects(final boolean polyphase, final String pub polyphase, publicOrPrivate); + final CosemObject gsmDiagnosticObject = + createObject( + CLASS_ID_GSM_DIAGNOSTIC, + OBIS_LTE_DIAGNOSTIC, + LTE_DIAGNOSTIC.name(), + null, + polyphase, + publicOrPrivate); + return new ArrayList<>( Arrays.asList( - clockObject, dataObject, registerVoltObject, registerAmpereObject, registerVarObject)); + clockObject, + dataObject, + registerVoltObject, + registerAmpereObject, + registerVarObject, + gsmDiagnosticObject)); } protected void verifyResponseData( @@ -161,7 +178,7 @@ protected void verifyResponseData( .findFirst(); assertTrue(profileData.isPresent()); - assertThat(profileData.get().getCaptureObjects()).hasSize(2); + assertThat(profileData.get().getCaptureObjects()).hasSize(3); final CaptureObjectDto captureObjectClock = profileData.get().getCaptureObjects().get(0); assertThat(captureObjectClock.getLogicalName()).isEqualTo(OBIS_CLOCK); @@ -171,6 +188,10 @@ protected void verifyResponseData( assertThat(captureObject.getLogicalName()).isEqualTo(OBIS_INSTANTANEOUS_VOLTAGE_L1); assertThat(captureObject.getUnit()).isEqualTo(UNIT_VOLT); + final CaptureObjectDto captureObjectLte = profileData.get().getCaptureObjects().get(2); + assertThat(captureObjectLte.getLogicalName()).isEqualTo(OBIS_LTE_DIAGNOSTIC); + assertThat(captureObjectLte.getUnit()).isEqualTo(UNIT_UNDEFINED); + final List entries = profileData.get().getProfileEntries(); assertThat(entries).hasSize(4); @@ -182,13 +203,15 @@ protected void verifyResponseData( private void verifyProfileEntry( final ProfileEntryDto entry, final int index, final int intervalInMinutes) { final List values = entry.getProfileEntryValues(); - assertThat(values).hasSize(2); + assertThat(values).hasSize(3); assertThat((Date) values.get(0).getValue()) .isEqualTo( new DateTime(2023, 1, 12, 0, 0, 0, DateTimeZone.forID("Europe/Amsterdam")) .plusMinutes(index * intervalInMinutes) .toDate()); assertThat((BigDecimal) values.get(1).getValue()).isEqualTo(BigDecimal.valueOf(VALUES[index])); + assertThat(values.get(2).getValue()) + .isEqualTo("MINUS_" + (113 - SIGNAL_STRENGTH_ENUM_VALUES[index] * 2) + "_DBM"); } protected List getPropertyObjects() { @@ -220,10 +243,18 @@ protected List createProfileEntries(final boolean selectiveAccess) { (byte) 0x00 }; - final DataObject entry1 = this.createEntry(timestamp, 2335, VALUES[0], 10, selectiveAccess); - final DataObject entry2 = this.createEntry(null, 2336, VALUES[1], 11, selectiveAccess); - final DataObject entry3 = this.createEntry(null, 2337, VALUES[2], 12, selectiveAccess); - final DataObject entry4 = this.createEntry(null, 2338, VALUES[3], 13, selectiveAccess); + final DataObject entry1 = + this.createEntry( + timestamp, 2335, VALUES[0], SIGNAL_STRENGTH_ENUM_VALUES[0], 10, selectiveAccess); + final DataObject entry2 = + this.createEntry( + null, 2336, VALUES[1], SIGNAL_STRENGTH_ENUM_VALUES[1], 11, selectiveAccess); + final DataObject entry3 = + this.createEntry( + null, 2337, VALUES[2], SIGNAL_STRENGTH_ENUM_VALUES[2], 12, selectiveAccess); + final DataObject entry4 = + this.createEntry( + null, 2338, VALUES[3], SIGNAL_STRENGTH_ENUM_VALUES[3], 13, selectiveAccess); final GetResult getResult = new GetResultImpl(DataObject.newArrayData(List.of(entry1, entry2, entry3, entry4))); @@ -236,6 +267,7 @@ private DataObject createEntry( final int value1, final int value2, final int value3, + final int value4, final boolean selectiveAccess) { final List values = new ArrayList<>(); @@ -251,8 +283,10 @@ private DataObject createEntry( values.add(DataObject.newUInteger8Data((short) value2)); + values.add(DataObject.newUInteger16Data(value3)); + if (!selectiveAccess) { - values.add(DataObject.newUInteger16Data(value3)); + values.add(DataObject.newUInteger16Data(value4)); } return DataObject.newStructureData(values); @@ -273,6 +307,13 @@ protected List createPartialNotAllowedCaptureObjects() { DataObject.newInteger32Data(2), DataObject.newUInteger32Data(0)); + final DataObject allowedCaptureObjectGsmDiagnostics = + DataObject.newStructureData( + DataObject.newUInteger32Data(47), + DataObject.newOctetStringData(new byte[] {0, 2, 25, 6, 0, (byte) 255}), + DataObject.newInteger32Data(6), + DataObject.newUInteger32Data(3)); // Data-index 3: Signal strength + final DataObject nonAllowedCaptureObject1 = DataObject.newStructureData( DataObject.newUInteger32Data(1), @@ -293,6 +334,7 @@ protected List createPartialNotAllowedCaptureObjects() { allowedCaptureObjectClock, nonAllowedCaptureObject1, allowedCaptureObjectINSTANTANEOUS_VOLTAGE_L1, + allowedCaptureObjectGsmDiagnostics, nonAllowedCaptureObject2))); return List.of(getResult); diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/periodicmeterreads/GetPeriodicMeterReadsCommandExecutorIntegrationTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/periodicmeterreads/GetPeriodicMeterReadsCommandExecutorIntegrationTest.java index 25310eb5173..787fc689dce 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/periodicmeterreads/GetPeriodicMeterReadsCommandExecutorIntegrationTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/periodicmeterreads/GetPeriodicMeterReadsCommandExecutorIntegrationTest.java @@ -17,8 +17,9 @@ import java.util.stream.Collectors; import org.joda.time.DateTimeZone; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; import org.mockito.junit.jupiter.MockitoExtension; import org.openmuc.jdlms.AttributeAddress; import org.openmuc.jdlms.ObisCode; @@ -69,10 +70,15 @@ class GetPeriodicMeterReadsCommandExecutorIntegrationTest { private final ObisCode OBIS_ACTIVE_ENERGY_IMPORT_RATE_2 = new ObisCode("1.0.1.8.2.255"); private final ObisCode OBIS_ACTIVE_ENERGY_EXPORT_RATE_1 = new ObisCode("1.0.2.8.1.255"); private final ObisCode OBIS_ACTIVE_ENERGY_EXPORT_RATE_2 = new ObisCode("1.0.2.8.2.255"); + private final ObisCode OBIS_MBUS_CHANNEL_1 = new ObisCode("0.1.24.2.1.255"); + private final ObisCode OBIS_MBUS_CHANNEL_2 = new ObisCode("0.2.24.2.1.255"); + private final ObisCode OBIS_MBUS_CHANNEL_3 = new ObisCode("0.3.24.2.1.255"); + private final ObisCode OBIS_MBUS_CHANNEL_4 = new ObisCode("0.4.24.2.1.255"); private final int CLASS_ID_CLOCK = 8; private final int CLASS_ID_DATA = 1; private final int CLASS_ID_REGISTER = 3; + private final int CLASS_ID_EXTENDED_REGISTER = 4; private final int CLASS_ID_PROFILE = 7; private final byte ATTR_ID_VALUE = 2; @@ -198,44 +204,47 @@ public void setUp() { DateTimeZone.setDefault(defaultDateTimeZone); } - @Test - void testExecuteDsmr4() throws Exception { - for (final PeriodTypeDto type : PeriodTypeDto.values()) { - this.testExecute(Protocol.DSMR_4_2_2, type, false); - } + @ParameterizedTest + @EnumSource(PeriodTypeDto.class) + void testExecuteDsmr4NoSelectiveAccess(final PeriodTypeDto type) throws Exception { + this.testExecute(Protocol.DSMR_4_2_2, type, false, false); } - @Test - void testExecuteSmr5_0() throws Exception { - for (final PeriodTypeDto type : PeriodTypeDto.values()) { - this.testExecute(Protocol.SMR_5_0_0, type, false); - } + @ParameterizedTest + @EnumSource(PeriodTypeDto.class) + void testExecuteDsmr4(final PeriodTypeDto type) throws Exception { + this.testExecute(Protocol.DSMR_4_2_2, type, false, true); } - @Test - void testExecuteSmr5_0_WithNullData() throws Exception { - for (final PeriodTypeDto type : PeriodTypeDto.values()) { - this.testExecute(Protocol.SMR_5_0_0, type, true); - } + @ParameterizedTest + @EnumSource(PeriodTypeDto.class) + void testExecuteSmr5_0(final PeriodTypeDto type) throws Exception { + this.testExecute(Protocol.SMR_5_0_0, type, false, true); } - @Test - void testExecuteSmr5_1() throws Exception { + @ParameterizedTest + @EnumSource(PeriodTypeDto.class) + void testExecuteSmr5_0_WithNullData(final PeriodTypeDto type) throws Exception { + this.testExecute(Protocol.SMR_5_0_0, type, true, true); + } - for (final PeriodTypeDto type : PeriodTypeDto.values()) { - this.testExecute(Protocol.SMR_5_1, type, false); - } + @ParameterizedTest + @EnumSource(PeriodTypeDto.class) + void testExecuteSmr5_1(final PeriodTypeDto type) throws Exception { + this.testExecute(Protocol.SMR_5_1, type, false, true); } - @Test - void testExecuteSmr5_1_WithNullData() throws Exception { - for (final PeriodTypeDto type : PeriodTypeDto.values()) { - this.testExecute(Protocol.SMR_5_1, type, true); - } + @ParameterizedTest + @EnumSource(PeriodTypeDto.class) + void testExecuteSmr5_1_WithNullData(final PeriodTypeDto type) throws Exception { + this.testExecute(Protocol.SMR_5_1, type, true, true); } private void testExecute( - final Protocol protocol, final PeriodTypeDto type, final boolean useNullData) + final Protocol protocol, + final PeriodTypeDto type, + final boolean useNullData, + final boolean selectiveAccessPeriodicMeterReadsSupported) throws Exception { // SETUP @@ -246,7 +255,8 @@ private void testExecute( this.connectionStub.clearRequestedAttributeAddresses(); // Create device with requested protocol version - final DlmsDevice device = this.createDlmsDevice(protocol); + final DlmsDevice device = + this.createDlmsDevice(protocol, selectiveAccessPeriodicMeterReadsSupported); // Create request object final PeriodicMeterReadsRequestDto request = @@ -256,7 +266,7 @@ private void testExecute( final AttributeAddress expectedAddressProfile = this.createAttributeAddress(protocol, type, this.timeFrom, this.timeTo, device); final List expectedScalerUnitAddresses = - this.getScalerUnitAttributeAddresses(type); + this.getScalerUnitAttributeAddresses(type, selectiveAccessPeriodicMeterReadsSupported); final int expectedTotalNumberOfAttributeAddresses = expectedScalerUnitAddresses.size() + 1; // Set response in stub @@ -290,7 +300,8 @@ private void testExecute( requestedAttributeAddresses.stream() .filter( a -> - a.getClassId() == this.CLASS_ID_REGISTER + (a.getClassId() == this.CLASS_ID_REGISTER + || a.getClassId() == this.CLASS_ID_EXTENDED_REGISTER) && a.getId() == this.ATTR_ID_SCALER_UNIT) .collect(Collectors.toList()); assertThat(attributeAddressesScalerUnit).hasSize(expectedScalerUnitAddresses.size()); @@ -305,10 +316,13 @@ private void testExecute( this.checkValues(periodicMeterReads, type); } - private DlmsDevice createDlmsDevice(final Protocol protocol) { + private DlmsDevice createDlmsDevice( + final Protocol protocol, final boolean selectiveAccessPeriodicMeterReadsSupported) { final DlmsDevice device = new DlmsDevice(); device.setProtocol(protocol); device.setSelectiveAccessSupported(true); + device.setSelectiveAccessPeriodicMeterReadsSupported( + selectiveAccessPeriodicMeterReadsSupported); return device; } @@ -329,9 +343,11 @@ private AttributeAddress createAttributeAddress( if (protocol == Protocol.DSMR_4_2_2) { if (type == PeriodTypeDto.DAILY) { - return this.createAttributeAddressDsmr4Daily(from, to); + return this.createAttributeAddressDsmr4Daily( + from, to, device.isSelectiveAccessPeriodicMeterReadsSupported()); } else if (type == PeriodTypeDto.MONTHLY) { - return this.createAttributeAddressDsmr4Monthly(from, to); + return this.createAttributeAddressDsmr4Monthly( + from, to, device.isSelectiveAccessPeriodicMeterReadsSupported()); } else if (type == PeriodTypeDto.INTERVAL) { return this.createAttributeAddressDsmr4Interval(from, to); } @@ -352,8 +368,8 @@ private AttributeAddress createAttributeAddress( + protocol.getVersion()); } - private List getScalerUnitAttributeAddresses(final PeriodTypeDto type) - throws Exception { + private List getScalerUnitAttributeAddresses( + final PeriodTypeDto type, final boolean selectedValuesSupported) throws Exception { final List attributeAddresses = new ArrayList<>(); switch (type) { @@ -383,6 +399,32 @@ private List getScalerUnitAttributeAddresses(final PeriodTypeD this.OBIS_ACTIVE_ENERGY_EXPORT_RATE_2, this.ATTR_ID_SCALER_UNIT, null)); + if (!selectedValuesSupported) { + attributeAddresses.add( + new AttributeAddress( + this.CLASS_ID_EXTENDED_REGISTER, + this.OBIS_MBUS_CHANNEL_1, + this.ATTR_ID_SCALER_UNIT, + null)); + attributeAddresses.add( + new AttributeAddress( + this.CLASS_ID_EXTENDED_REGISTER, + this.OBIS_MBUS_CHANNEL_2, + this.ATTR_ID_SCALER_UNIT, + null)); + attributeAddresses.add( + new AttributeAddress( + this.CLASS_ID_EXTENDED_REGISTER, + this.OBIS_MBUS_CHANNEL_3, + this.ATTR_ID_SCALER_UNIT, + null)); + attributeAddresses.add( + new AttributeAddress( + this.CLASS_ID_EXTENDED_REGISTER, + this.OBIS_MBUS_CHANNEL_4, + this.ATTR_ID_SCALER_UNIT, + null)); + } break; case INTERVAL: attributeAddresses.add( @@ -561,25 +603,33 @@ private void checkValues( // DSMR4 private AttributeAddress createAttributeAddressDsmr4Daily( - final DataObject from, final DataObject to) { + final DataObject from, + final DataObject to, + final boolean selectiveAccessPeriodicMeterReadsSupported) { final SelectiveAccessDescription expectedSelectiveAccess = - this.createSelectiveAccessDescriptionDsmr4Daily(from, to); + this.createSelectiveAccessDescriptionDsmr4Daily( + from, to, selectiveAccessPeriodicMeterReadsSupported); return new AttributeAddress( this.CLASS_ID_PROFILE, this.OBIS_DAILY_DSMR4, this.ATTR_ID_BUFFER, expectedSelectiveAccess); } private SelectiveAccessDescription createSelectiveAccessDescriptionDsmr4Daily( - final DataObject from, final DataObject to) { + final DataObject from, + final DataObject to, + final boolean selectiveAccessPeriodicMeterReadsSupported) { - final DataObject selectedValues = - DataObject.newArrayData( - Arrays.asList( + final List dataObjects = + selectiveAccessPeriodicMeterReadsSupported + ? Arrays.asList( this.CLOCK, this.STATUS, this.ACTIVE_ENERGY_IMPORT_RATE_1, this.ACTIVE_ENERGY_IMPORT_RATE_2, this.ACTIVE_ENERGY_EXPORT_RATE_1, - this.ACTIVE_ENERGY_EXPORT_RATE_2)); + this.ACTIVE_ENERGY_EXPORT_RATE_2) + : new ArrayList<>(); + + final DataObject selectedValues = DataObject.newArrayData(dataObjects); final DataObject expectedAccessParam = DataObject.newStructureData(Arrays.asList(this.CLOCK, from, to, selectedValues)); @@ -588,9 +638,12 @@ private SelectiveAccessDescription createSelectiveAccessDescriptionDsmr4Daily( } private AttributeAddress createAttributeAddressDsmr4Monthly( - final DataObject from, final DataObject to) { + final DataObject from, + final DataObject to, + final boolean selectiveAccessPeriodicMeterReadsSupported) { final SelectiveAccessDescription expectedSelectiveAccess = - this.createSelectiveAccessDescriptionDsmr4Monthly(from, to); + this.createSelectiveAccessDescriptionDsmr4Monthly( + from, to, selectiveAccessPeriodicMeterReadsSupported); return new AttributeAddress( this.CLASS_ID_PROFILE, this.OBIS_MONTHLY_DSMR4, @@ -599,16 +652,21 @@ private AttributeAddress createAttributeAddressDsmr4Monthly( } private SelectiveAccessDescription createSelectiveAccessDescriptionDsmr4Monthly( - final DataObject from, final DataObject to) { + final DataObject from, + final DataObject to, + final boolean selectiveAccessPeriodicMeterReadsSupported) { - final DataObject selectedValues = - DataObject.newArrayData( - Arrays.asList( + final List dataObjects = + selectiveAccessPeriodicMeterReadsSupported + ? Arrays.asList( this.CLOCK, this.ACTIVE_ENERGY_IMPORT_RATE_1, this.ACTIVE_ENERGY_IMPORT_RATE_2, this.ACTIVE_ENERGY_EXPORT_RATE_1, - this.ACTIVE_ENERGY_EXPORT_RATE_2)); + this.ACTIVE_ENERGY_EXPORT_RATE_2) + : new ArrayList<>(); + + final DataObject selectedValues = DataObject.newArrayData(dataObjects); final DataObject expectedAccessParam = DataObject.newStructureData(Arrays.asList(this.CLOCK, from, to, selectedValues)); diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/periodicmeterreads/GetPeriodicMeterReadsCommandExecutorTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/periodicmeterreads/GetPeriodicMeterReadsCommandExecutorTest.java index 115e07b3ecf..77cc0b06ed2 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/periodicmeterreads/GetPeriodicMeterReadsCommandExecutorTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/periodicmeterreads/GetPeriodicMeterReadsCommandExecutorTest.java @@ -108,8 +108,7 @@ void testExecuteObjectNotFound() { this.fromDateTime.toDate(), this.toDateTime.toDate(), ChannelDto.ONE); - when(this.dlmsObjectConfigService.findAttributeAddressForProfile( - any(), any(), any(), any(), any(), any())) + when(this.dlmsObjectConfigService.findAttributeAddressForProfile(any(), any(), any())) .thenReturn(Optional.empty()); // CALL @@ -188,7 +187,8 @@ void testHappyWithDifferentTimeZones(final String timeZone) throws Exception { 0, convertedFromTime, convertedToTime, - Medium.ELECTRICITY)) + Medium.ELECTRICITY, + true)) .thenReturn(Optional.of(attributeAddressForProfile)); final DlmsObject intervalTime = mock(DlmsObject.class); @@ -306,6 +306,7 @@ private AttributeAddress createAttributeAddress(final DlmsObject dlmsObject) { private DlmsDevice createDevice(final Protocol protocol) { final DlmsDevice device = new DlmsDevice(); device.setProtocol(protocol); + device.setSelectiveAccessPeriodicMeterReadsSupported(true); return device; } } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/periodicmeterreads/GetPeriodicMeterReadsGasCommandExecutorIntegrationTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/periodicmeterreads/GetPeriodicMeterReadsGasCommandExecutorIntegrationTest.java index c01c4cdbd03..a209a2fa7f3 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/periodicmeterreads/GetPeriodicMeterReadsGasCommandExecutorIntegrationTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/periodicmeterreads/GetPeriodicMeterReadsGasCommandExecutorIntegrationTest.java @@ -4,6 +4,9 @@ package org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.periodicmeterreads; +import static java.lang.Math.abs; +import static java.lang.Math.pow; +import static java.util.Map.entry; import static org.assertj.core.api.Assertions.assertThat; import static org.opensmartgridplatform.dto.valueobjects.smartmetering.AmrProfileStatusCodeFlagDto.CLOCK_ADJUSTED; import static org.opensmartgridplatform.dto.valueobjects.smartmetering.AmrProfileStatusCodeFlagDto.CLOCK_INVALID; @@ -14,18 +17,25 @@ import static org.opensmartgridplatform.dto.valueobjects.smartmetering.AmrProfileStatusCodeFlagDto.POWER_DOWN; import static org.opensmartgridplatform.dto.valueobjects.smartmetering.AmrProfileStatusCodeFlagDto.RECOVERED_VALUE; +import java.io.IOException; +import java.math.BigDecimal; +import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Collections; import java.util.Date; import java.util.GregorianCalendar; import java.util.List; +import java.util.Map; import java.util.TimeZone; import java.util.stream.Collectors; +import java.util.stream.Stream; import org.joda.time.DateTimeZone; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import org.mockito.junit.jupiter.MockitoExtension; import org.openmuc.jdlms.AttributeAddress; import org.openmuc.jdlms.ObisCode; @@ -33,7 +43,6 @@ import org.openmuc.jdlms.datatypes.CosemDateTime; import org.openmuc.jdlms.datatypes.DataObject; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectConfigConfiguration; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectConfigService; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.stub.DlmsConnectionManagerStub; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.stub.DlmsConnectionStub; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.testutil.AttributeAddressAssert; @@ -42,7 +51,11 @@ import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.DlmsHelper; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDevice; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.Protocol; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.valueobjects.CombinedDeviceModelCode.CombinedDeviceModelCodeBuilder; +import org.opensmartgridplatform.dlms.exceptions.ObjectConfigException; +import org.opensmartgridplatform.dlms.services.ObjectConfigService; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ChannelDto; +import org.opensmartgridplatform.dto.valueobjects.smartmetering.DlmsUnitTypeDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.PeriodTypeDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.PeriodicMeterReadGasResponseDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.PeriodicMeterReadsGasResponseItemDto; @@ -56,23 +69,22 @@ class GetPeriodicMeterReadsGasCommandExecutorIntegrationTest { private DlmsHelper dlmsHelper; private AmrProfileStatusCodeHelper amrProfileStatusCodeHelper; - private DlmsObjectConfigService dlmsObjectConfigService; + private ObjectConfigService objectConfigService; private DlmsConnectionManagerStub connectionManagerStub; private DlmsConnectionStub connectionStub; private final ObisCode OBIS_DAILY_DSMR4 = new ObisCode("1.0.99.2.0.255"); - private final ObisCode OBIS_INTERVAL_DSMR4 = new ObisCode("0.1.24.3.0.255"); private final ObisCode OBIS_MONTHLY_DSMR4 = new ObisCode("0.0.98.1.0.255"); + private final String OBIS_INTERVAL_DSMR4 = "0..24.3.0.255"; - private final ObisCode OBIS_DAILY_SMR5 = new ObisCode("0.1.24.3.1.255"); - private final ObisCode OBIS_INTERVAL_SMR5 = new ObisCode("0.1.24.3.0.255"); - private final ObisCode OBIS_MONTHLY_SMR5 = new ObisCode("0.1.24.3.2.255"); + private final String OBIS_DAILY_SMR5 = "0..24.3.1.255"; + private final String OBIS_INTERVAL_SMR5 = "0..24.3.0.255"; + private final String OBIS_MONTHLY_SMR5 = "0..24.3.2.255"; private final ObisCode OBIS_CLOCK = new ObisCode("0.0.1.0.0.255"); private final ObisCode OBIS_STATUS = new ObisCode("0.0.96.10.2.255"); - private final ObisCode OBIS_GAS_VALUE_DSMR4 = new ObisCode("0.1.24.2.1.255"); - private final ObisCode OBIS_GAS_VALUE_SMR5 = new ObisCode("0.1.24.2.2.255"); + private final String OBIS_GAS_VALUE_DSMR4 = "0..24.2.1.255"; private final int CLASS_ID_CLOCK = 8; private final int CLASS_ID_DATA = 1; @@ -82,7 +94,6 @@ class GetPeriodicMeterReadsGasCommandExecutorIntegrationTest { private final byte ATTR_ID_VALUE = 2; private final byte ATTR_ID_BUFFER = 2; private final byte ATTR_ID_CAPTURE_TIME = 5; - private final byte ATTR_ID_SCALER_UNIT = 3; private final DataObject CLOCK = DataObject.newStructureData( @@ -98,22 +109,6 @@ class GetPeriodicMeterReadsGasCommandExecutorIntegrationTest { DataObject.newOctetStringData(this.OBIS_STATUS.bytes()), DataObject.newInteger8Data(this.ATTR_ID_VALUE), DataObject.newUInteger16Data(0))); - private final DataObject GAS_VALUE_DSMR4 = - DataObject.newStructureData( - Arrays.asList( - DataObject.newUInteger16Data(this.CLASS_ID_EXTENDED_REGISTER), - DataObject.newOctetStringData(this.OBIS_GAS_VALUE_DSMR4.bytes()), - DataObject.newInteger8Data(this.ATTR_ID_VALUE), - DataObject.newUInteger16Data(0))); - - private final DataObject GAS_CAPTURE_TIME_DSMR4 = - DataObject.newStructureData( - Arrays.asList( - DataObject.newUInteger16Data(this.CLASS_ID_EXTENDED_REGISTER), - DataObject.newOctetStringData(this.OBIS_GAS_VALUE_DSMR4.bytes()), - DataObject.newInteger8Data(this.ATTR_ID_CAPTURE_TIME), - DataObject.newUInteger16Data(0))); - private Date TIME_FROM; private Date TIME_TO; private DataObject PERIOD_1_CLOCK; @@ -130,11 +125,26 @@ class GetPeriodicMeterReadsGasCommandExecutorIntegrationTest { private final long PERIOD_1_LONG_VALUE = 1000L; private final long PERIOD_2_LONG_VALUE = 1500L; + private final BigDecimal SCALER = BigDecimal.valueOf(1000); + + private final long PERIOD_1_LONG_VALUE_E = 33L; + private final long PERIOD_2_LONG_VALUE_E = 44L; + private final short PERIOD1_AMR_STATUS_VALUE = 0x0F; // First 4 status bits set private final short PERIOD2_AMR_STATUS_VALUE = 0xF0; // Last 4 status bits set + private final List protocolsNoStatusMonthlyValues = + List.of(Protocol.DSMR_2_2, Protocol.DSMR_4_2_2, Protocol.SMR_4_3); + + private static final List ALL_CHANNELS = List.of(1, 2, 3, 4); + + private static final List GMETER_TYPES = List.of("G4", "G6", "G10", "G16", "G25"); + private static final Map SCALERS_FOR_METER_TYPES = + Map.ofEntries( + entry("G4", -3), entry("G6", -3), entry("G10", -2), entry("G16", -2), entry("G25", -2)); + @BeforeEach - public void setUp() { + public void setUp() throws IOException, ObjectConfigException { final TimeZone defaultTimeZone = TimeZone.getDefault(); final DateTimeZone defaultDateTimeZone = DateTimeZone.getDefault(); @@ -149,13 +159,11 @@ public void setUp() { this.amrProfileStatusCodeHelper = new AmrProfileStatusCodeHelper(); final DlmsObjectConfigConfiguration dlmsObjectConfigConfiguration = new DlmsObjectConfigConfiguration(); - this.dlmsObjectConfigService = - new DlmsObjectConfigService( - this.dlmsHelper, dlmsObjectConfigConfiguration.getDlmsObjectConfigs()); + this.objectConfigService = new ObjectConfigService(); this.executor = new GetPeriodicMeterReadsGasCommandExecutor( - this.dlmsHelper, this.amrProfileStatusCodeHelper, this.dlmsObjectConfigService); + this.dlmsHelper, this.amrProfileStatusCodeHelper, this.objectConfigService); this.connectionStub = new DlmsConnectionStub(); this.connectionManagerStub = new DlmsConnectionManagerStub(this.connectionStub); @@ -182,69 +190,112 @@ private void initDates() { new GregorianCalendar(2019, Calendar.FEBRUARY, 1, 0, 0).getTime(); } - @Test - void testExecuteDsmr4() throws Exception { - for (final PeriodTypeDto type : PeriodTypeDto.values()) { - this.testExecute(Protocol.DSMR_4_2_2, type, false); - } + private static Stream combinationsDsmr() { + final List dsmrProtocols = + Arrays.stream(Protocol.values()) + .filter(protocol -> protocol.isDsmr4() || protocol.isDsmr2()) + .collect(Collectors.toList()); + + return generateCombinations(dsmrProtocols); } - @Test - void testExecuteSmr5_0() throws Exception { - for (final PeriodTypeDto type : PeriodTypeDto.values()) { - this.testExecute(Protocol.SMR_5_0_0, type, false); - } + private static Stream combinationsSmr5() { + final List smr5Protocols = + Arrays.stream(Protocol.values()).filter(Protocol::isSmr5).toList(); + + return generateCombinations(smr5Protocols); } - @Test - void testExecuteSmr5_0_WithNullData() throws Exception { - for (final PeriodTypeDto type : PeriodTypeDto.values()) { - this.testExecute(Protocol.SMR_5_0_0, type, true); + private static Stream generateCombinations(final List protocols) { + final List arguments = new ArrayList<>(); + + for (final Protocol protocol : protocols) { + for (final PeriodTypeDto periodType : PeriodTypeDto.values()) { + for (final int channel : ALL_CHANNELS) { + for (final String gMeterType : GMETER_TYPES) { + arguments.add(Arguments.of(protocol, periodType, channel, gMeterType)); + } + } + } } + + return arguments.stream(); } - @Test - void testExecuteSmr5_1() throws Exception { - for (final PeriodTypeDto type : PeriodTypeDto.values()) { - this.testExecute(Protocol.SMR_5_1, type, false); - } + @ParameterizedTest + @MethodSource("combinationsDsmr") + void testExecuteDsmrNoSelectedValues( + final Protocol protocol, final PeriodTypeDto type, final int channel, final String gMeterType) + throws Exception { + this.testExecute(protocol, type, false, false, channel, gMeterType); } - @Test - void testExecuteSmr5_1_WithNullData() throws Exception { - for (final PeriodTypeDto type : PeriodTypeDto.values()) { - this.testExecute(Protocol.SMR_5_1, type, true); - } + @ParameterizedTest + @MethodSource("combinationsDsmr") + void testExecuteDsmr( + final Protocol protocol, final PeriodTypeDto type, final int channel, final String gMeterType) + throws Exception { + this.testExecute(protocol, type, false, true, channel, gMeterType); + } + + @ParameterizedTest + @MethodSource("combinationsSmr5") + void testExecuteSmr5( + final Protocol protocol, final PeriodTypeDto type, final int channel, final String gMeterType) + throws Exception { + this.testExecute(protocol, type, false, true, channel, gMeterType); + } + + @ParameterizedTest + @MethodSource("combinationsSmr5") + void testExecuteSmr5_WithNullData( + final Protocol protocol, final PeriodTypeDto type, final int channel, final String gMeterType) + throws Exception { + this.testExecute(protocol, type, true, true, channel, gMeterType); } private void testExecute( - final Protocol protocol, final PeriodTypeDto type, final boolean useNullData) + final Protocol protocol, + final PeriodTypeDto type, + final boolean useNullData, + final boolean selectedValuesSupported, + final int channel, + final String mbusDeviceModelCode) throws Exception { // SETUP + // set device model code in a comma seperated list per channel index 1-4 is channel 1-4 and + // index 0 is device model code of master device + final String combinedDeviceModelCodes = + new CombinedDeviceModelCodeBuilder() + .channelBasedDeviceModelCode(channel, mbusDeviceModelCode) + .build() + .toString(); + final MessageMetadata messageMetadata = - MessageMetadata.newBuilder().withCorrelationUid("123456").build(); + MessageMetadata.newBuilder() + .withCorrelationUid("123456") + .withDeviceModelCode(combinedDeviceModelCodes) + .build(); // Reset stub this.connectionStub.clearRequestedAttributeAddresses(); // Create device with requested protocol version - final DlmsDevice device = this.createDlmsDevice(protocol); + final DlmsDevice device = this.createDlmsDevice(protocol, selectedValuesSupported); // Create request object final PeriodicMeterReadsRequestDto request = new PeriodicMeterReadsRequestDto( - type, this.TIME_FROM, this.TIME_TO, ChannelDto.fromNumber(1)); + type, this.TIME_FROM, this.TIME_TO, ChannelDto.fromNumber(channel)); // Get expected values final AttributeAddress expectedAddressProfile = - this.createAttributeAddress(protocol, type, this.TIME_FROM, this.TIME_TO, device); - final List expectedScalerUnitAddresses = - this.getScalerUnitAttributeAddresses(protocol); + this.createAttributeAddress(protocol, type, this.TIME_FROM, this.TIME_TO, device, channel); // Set response in stub - this.setResponseForProfile(expectedAddressProfile, protocol, type, useNullData); - this.setResponsesForScalerUnit(expectedScalerUnitAddresses); + this.setResponseForProfile( + expectedAddressProfile, protocol, type, useNullData, selectedValuesSupported, channel); // CALL final PeriodicMeterReadGasResponseDto response = @@ -255,29 +306,18 @@ private void testExecute( // Get resulting requests from connection stub final List requestedAttributeAddresses = this.connectionStub.getRequestedAttributeAddresses(); - assertThat(requestedAttributeAddresses).hasSize(2); + assertThat(requestedAttributeAddresses).hasSize(1); // There should be 1 request to the buffer (id = 2) of a profile // (class-id = 7) final AttributeAddress actualAttributeAddressProfile = requestedAttributeAddresses.stream() .filter(a -> a.getClassId() == this.CLASS_ID_PROFILE) - .collect(Collectors.toList()) + .toList() .get(0); AttributeAddressAssert.is(actualAttributeAddressProfile, expectedAddressProfile); - // Check the amount of requests to the scaler_unit of the meter value in - // the extended register - final List attributeAddressesScalerUnit = - requestedAttributeAddresses.stream() - .filter( - a -> - a.getClassId() == this.CLASS_ID_EXTENDED_REGISTER - && a.getId() == this.ATTR_ID_SCALER_UNIT) - .collect(Collectors.toList()); - assertThat(attributeAddressesScalerUnit).hasSize(1); - // Check response assertThat(response.getPeriodType()).isEqualTo(type); final List periodicMeterReads = @@ -286,14 +326,18 @@ private void testExecute( assertThat(periodicMeterReads).hasSize(AMOUNT_OF_PERIODS); this.checkClockValues(periodicMeterReads, type, useNullData); - this.checkValues(periodicMeterReads); + this.checkValues( + periodicMeterReads, channel, this.SCALERS_FOR_METER_TYPES.get(mbusDeviceModelCode)); this.checkAmrStatus(periodicMeterReads, protocol, type); } - private DlmsDevice createDlmsDevice(final Protocol protocol) { + private DlmsDevice createDlmsDevice( + final Protocol protocol, final boolean selectiveAccessPeriodicMeterReadsSupported) { final DlmsDevice device = new DlmsDevice(); device.setProtocol(protocol); device.setSelectiveAccessSupported(true); + device.setSelectiveAccessPeriodicMeterReadsSupported( + selectiveAccessPeriodicMeterReadsSupported); return device; } @@ -302,7 +346,8 @@ private AttributeAddress createAttributeAddress( final PeriodTypeDto type, final Date timeFrom, final Date timeTo, - final DlmsDevice device) + final DlmsDevice device, + final int channel) throws Exception { final DataObject from = this.dlmsHelper.asDataObject( @@ -311,21 +356,23 @@ private AttributeAddress createAttributeAddress( this.dlmsHelper.asDataObject( DlmsDateTimeConverter.toDateTime(timeTo, device.getTimezone())); - if (protocol == Protocol.DSMR_4_2_2) { + if (protocol.isDsmr2() || protocol.isDsmr4()) { if (type == PeriodTypeDto.DAILY) { - return this.createAttributeAddressDsmr4Daily(from, to); + return this.createAttributeAddressDsmr4Daily( + from, to, device.isSelectiveAccessPeriodicMeterReadsSupported(), channel, protocol); } else if (type == PeriodTypeDto.MONTHLY) { - return this.createAttributeAddressDsmr4Monthly(from, to); + return this.createAttributeAddressDsmr4Monthly( + from, to, device.isSelectiveAccessPeriodicMeterReadsSupported(), channel, protocol); } else if (type == PeriodTypeDto.INTERVAL) { - return this.createAttributeAddressDsmr4Interval(from, to); + return this.createAttributeAddressDsmr4Interval(from, to, channel); } - } else if (protocol == Protocol.SMR_5_0_0 || protocol == Protocol.SMR_5_1) { + } else if (protocol.isSmr5()) { if (type == PeriodTypeDto.DAILY) { - return this.createAttributeAddressSmr5Daily(from, to); + return this.createAttributeAddressSmr5Daily(from, to, channel); } else if (type == PeriodTypeDto.MONTHLY) { - return this.createAttributeAddressSmr5Monthly(from, to); + return this.createAttributeAddressSmr5Monthly(from, to, channel); } else if (type == PeriodTypeDto.INTERVAL) { - return this.createAttributeAddressSmr5Interval(from, to); + return this.createAttributeAddressSmr5Interval(from, to, channel); } } @@ -336,52 +383,29 @@ private AttributeAddress createAttributeAddress( + protocol.getVersion()); } - private List getScalerUnitAttributeAddresses(final Protocol protocol) { - - final AttributeAddress attributeAddress; - - if (protocol == Protocol.DSMR_4_2_2) { - attributeAddress = - new AttributeAddress( - this.CLASS_ID_EXTENDED_REGISTER, - this.OBIS_GAS_VALUE_DSMR4, - this.ATTR_ID_SCALER_UNIT, - null); - } else { - attributeAddress = - new AttributeAddress( - this.CLASS_ID_EXTENDED_REGISTER, - this.OBIS_GAS_VALUE_SMR5, - this.ATTR_ID_SCALER_UNIT, - null); - } - - return Collections.singletonList(attributeAddress); - } - private void setResponseForProfile( final AttributeAddress attributeAddressForProfile, final Protocol protocol, final PeriodTypeDto type, - final boolean useNullData) { + final boolean useNullData, + final boolean selectedValuesSupported, + final int channel) { // PERIOD 1 - final DataObject period1Clock = this.PERIOD_1_CLOCK; - final DataObject period1Status = DataObject.newUInteger8Data(this.PERIOD1_AMR_STATUS_VALUE); - final DataObject period1Value = DataObject.newUInteger32Data(this.PERIOD_1_LONG_VALUE); final DataObject period1CaptureTime = DataObject.newDateTimeData(this.PERIOD_1_CAPTURE_TIME); - final DataObject periodItem1; - if (type == PeriodTypeDto.MONTHLY && protocol == Protocol.DSMR_4_2_2) { - periodItem1 = - DataObject.newStructureData( - Arrays.asList(period1Clock, period1Value, period1CaptureTime)); - } else { - periodItem1 = - DataObject.newStructureData( - Arrays.asList(period1Clock, period1Status, period1Value, period1CaptureTime)); - } + final DataObject periodItem1 = + this.createPeriodItem( + type, + protocol, + selectedValuesSupported, + channel, + this.PERIOD_1_CLOCK, + this.PERIOD1_AMR_STATUS_VALUE, + this.PERIOD_1_LONG_VALUE_E, + this.PERIOD_1_LONG_VALUE, + period1CaptureTime); // PERIOD 2 @@ -394,20 +418,18 @@ private void setResponseForProfile( period2Clock = this.PERIOD_2_CLOCK; period2CaptureTime = DataObject.newDateTimeData(this.PERIOD_2_CAPTURE_TIME); } - final DataObject period2Status = DataObject.newUInteger8Data(this.PERIOD2_AMR_STATUS_VALUE); - final DataObject period2Value = DataObject.newUInteger32Data(this.PERIOD_2_LONG_VALUE); - - final DataObject periodItem2; - if (type == PeriodTypeDto.MONTHLY && protocol == Protocol.DSMR_4_2_2) { - // No status for Monthly values in DSMR4.2.2 - periodItem2 = - DataObject.newStructureData( - Arrays.asList(period2Clock, period2Value, period2CaptureTime)); - } else { - periodItem2 = - DataObject.newStructureData( - Arrays.asList(period2Clock, period2Status, period2Value, period2CaptureTime)); - } + + final DataObject periodItem2 = + this.createPeriodItem( + type, + protocol, + selectedValuesSupported, + channel, + period2Clock, + this.PERIOD2_AMR_STATUS_VALUE, + this.PERIOD_2_LONG_VALUE_E, + this.PERIOD_2_LONG_VALUE, + period2CaptureTime); // Create returnvalue and set in stub final DataObject responseDataObject = @@ -415,16 +437,72 @@ private void setResponseForProfile( this.connectionStub.addReturnValue(attributeAddressForProfile, responseDataObject); } - private void setResponsesForScalerUnit( - final List attributeAddressesForScalerUnit) { - final int DLMS_ENUM_VALUE_M3 = 14; - final DataObject responseDataObject = - DataObject.newStructureData( - DataObject.newInteger8Data((byte) 0), DataObject.newEnumerateData(DLMS_ENUM_VALUE_M3)); + private DataObject createPeriodItem( + final PeriodTypeDto type, + final Protocol protocol, + final boolean selectedValuesSupported, + final int channel, + final DataObject clock, + final short statusValue, + final long longValueE, + final long longValueG, + final DataObject captureTime) { + final DataObject periodStatus = DataObject.newUInteger8Data(statusValue); + final DataObject periodValueE = DataObject.newUInteger32Data(longValueE); + + final List items = new ArrayList<>(); + + // Overview protocols - periodtypes (Interval/Daily/Monthly) - selected values supported + // + // DSMR2.2 DSMR4.2.2 / SMR4.3 SMR5.0-5.5 + // I D M I D M I D M + // + // Clock 1 1 1 1 1 1 1 1 1 + // Status 1 1 0 1 1 0 1 1 1 + // E values 0 0 0 0 0 0 0 0 0 + // G values 1 1 1 1 1 1 1 1 1 + // Capture time 0 0 0 1 1 1 1 1 1 + + // Overview protocols - periodtypes - selected values NOT supported + // + // DSMR2.2 DSMR4.2.2 / SMR4.3 + // I D M I D M + // + // Clock 1 1 1 1 1 1 + // Status 1 1 0 1 1 0 + // E values 4 4 4 4 4 4 + // G values 4 4 4 4 4 4 + // Capture time 0 0 0 4 4 4 + + // Always add clock first + items.add(clock); + + // Add status + if (type != PeriodTypeDto.MONTHLY || !this.protocolsNoStatusMonthlyValues.contains(protocol)) { + items.add(periodStatus); + } - for (final AttributeAddress attributeAddress : attributeAddressesForScalerUnit) { - this.connectionStub.addReturnValue(attributeAddress, responseDataObject); + // Add E values (import rate 1 and 2, export rate 1 and 2) + if (!selectedValuesSupported && type != PeriodTypeDto.INTERVAL) { + items.addAll(List.of(periodValueE, periodValueE, periodValueE, periodValueE)); } + + // Add G values and capture times + if (selectedValuesSupported || type == PeriodTypeDto.INTERVAL) { + items.add(this.createValue(longValueG, channel)); + if (protocol != Protocol.DSMR_2_2) { + items.add(captureTime); + } + } else { + for (final int c : this.ALL_CHANNELS) { + items.add(this.createValue(longValueG, c)); + if (protocol != Protocol.DSMR_2_2) { + items.add(captureTime); + } + } + } + + return DataObject.newStructureData(items); } private DataObject getDateAsOctetString(final int year, final int month, final int day) { @@ -461,13 +539,22 @@ private void checkClockValues( } } - private void checkValues(final List periodicMeterReads) { + private void checkValues( + final List periodicMeterReads, + final int channel, + final int scaler) { final PeriodicMeterReadsGasResponseItemDto period1 = periodicMeterReads.get(0); final PeriodicMeterReadsGasResponseItemDto period2 = periodicMeterReads.get(1); + final BigDecimal multiplier = BigDecimal.valueOf(pow(10, abs(scaler))); - assertThat(period1.getConsumption().getValue().longValue()).isEqualTo(this.PERIOD_1_LONG_VALUE); - assertThat(period2.getConsumption().getValue().longValue()).isEqualTo(this.PERIOD_2_LONG_VALUE); + assertThat(period1.getConsumption().getValue().multiply(multiplier).intValue()) + .isEqualTo(this.PERIOD_1_LONG_VALUE + channel); + assertThat(period1.getConsumption().getDlmsUnit()).isEqualTo(DlmsUnitTypeDto.M3); + + assertThat(period2.getConsumption().getValue().multiply(multiplier).intValue()) + .isEqualTo(this.PERIOD_2_LONG_VALUE + channel); + assertThat(period2.getConsumption().getDlmsUnit()).isEqualTo(DlmsUnitTypeDto.M3); } private void checkAmrStatus( @@ -478,7 +565,7 @@ private void checkAmrStatus( final PeriodicMeterReadsGasResponseItemDto period1 = periodicMeterReads.get(0); final PeriodicMeterReadsGasResponseItemDto period2 = periodicMeterReads.get(1); - if (protocol == Protocol.DSMR_4_2_2 && type == PeriodTypeDto.MONTHLY) { + if (type == PeriodTypeDto.MONTHLY && this.protocolsNoStatusMonthlyValues.contains(protocol)) { assertThat(period1.getAmrProfileStatusCode()).isNull(); assertThat(period2.getAmrProfileStatusCode()).isNull(); } else { @@ -492,20 +579,45 @@ private void checkAmrStatus( // DSMR4 private AttributeAddress createAttributeAddressDsmr4Daily( - final DataObject from, final DataObject to) { + final DataObject from, + final DataObject to, + final boolean selectedValuesSupported, + final int channel, + final Protocol protocol) { final SelectiveAccessDescription expectedSelectiveAccess = - this.createSelectiveAccessDescriptionDsmr4Daily(from, to); + this.createSelectiveAccessDescriptionDsmr4Daily( + from, to, selectedValuesSupported, channel, protocol); return new AttributeAddress( this.CLASS_ID_PROFILE, this.OBIS_DAILY_DSMR4, this.ATTR_ID_BUFFER, expectedSelectiveAccess); } private SelectiveAccessDescription createSelectiveAccessDescriptionDsmr4Daily( - final DataObject from, final DataObject to) { + final DataObject from, + final DataObject to, + final boolean selectedValuesSupported, + final int channel, + final Protocol protocol) { + + final List dataObjects; + + if (!selectedValuesSupported) { + dataObjects = new ArrayList<>(); + } else if (protocol == Protocol.DSMR_2_2) { + dataObjects = + Arrays.asList( + this.CLOCK, + this.STATUS, + this.getDataObjectForGasValueDsmr4(channel, this.ATTR_ID_VALUE)); + } else { + dataObjects = + Arrays.asList( + this.CLOCK, + this.STATUS, + this.getDataObjectForGasValueDsmr4(channel, this.ATTR_ID_VALUE), + this.getDataObjectForGasValueDsmr4(channel, this.ATTR_ID_CAPTURE_TIME)); + } - final DataObject selectedValues = - DataObject.newArrayData( - Arrays.asList( - this.CLOCK, this.STATUS, this.GAS_VALUE_DSMR4, this.GAS_CAPTURE_TIME_DSMR4)); + final DataObject selectedValues = DataObject.newArrayData(dataObjects); final DataObject expectedAccessParam = DataObject.newStructureData(Arrays.asList(this.CLOCK, from, to, selectedValues)); @@ -514,9 +626,14 @@ private SelectiveAccessDescription createSelectiveAccessDescriptionDsmr4Daily( } private AttributeAddress createAttributeAddressDsmr4Monthly( - final DataObject from, final DataObject to) { + final DataObject from, + final DataObject to, + final boolean selectiveAccessPeriodicMeterReadsSupported, + final int channel, + final Protocol protocol) { final SelectiveAccessDescription expectedSelectiveAccess = - this.createSelectiveAccessDescriptionDsmr4Monthly(from, to); + this.createSelectiveAccessDescriptionDsmr4Monthly( + from, to, selectiveAccessPeriodicMeterReadsSupported, channel, protocol); return new AttributeAddress( this.CLASS_ID_PROFILE, this.OBIS_MONTHLY_DSMR4, @@ -525,11 +642,29 @@ private AttributeAddress createAttributeAddressDsmr4Monthly( } private SelectiveAccessDescription createSelectiveAccessDescriptionDsmr4Monthly( - final DataObject from, final DataObject to) { + final DataObject from, + final DataObject to, + final boolean selectedValuesSupported, + final int channel, + final Protocol protocol) { + + final List dataObjects; + + if (!selectedValuesSupported) { + dataObjects = new ArrayList<>(); + } else if (protocol == Protocol.DSMR_2_2) { + dataObjects = + Arrays.asList( + this.CLOCK, this.getDataObjectForGasValueDsmr4(channel, this.ATTR_ID_VALUE)); + } else { + dataObjects = + Arrays.asList( + this.CLOCK, + this.getDataObjectForGasValueDsmr4(channel, this.ATTR_ID_VALUE), + this.getDataObjectForGasValueDsmr4(channel, this.ATTR_ID_CAPTURE_TIME)); + } - final DataObject selectedValues = - DataObject.newArrayData( - Arrays.asList(this.CLOCK, this.GAS_VALUE_DSMR4, this.GAS_CAPTURE_TIME_DSMR4)); + final DataObject selectedValues = DataObject.newArrayData(dataObjects); final DataObject expectedAccessParam = DataObject.newStructureData(Arrays.asList(this.CLOCK, from, to, selectedValues)); @@ -538,12 +673,12 @@ private SelectiveAccessDescription createSelectiveAccessDescriptionDsmr4Monthly( } private AttributeAddress createAttributeAddressDsmr4Interval( - final DataObject from, final DataObject to) { + final DataObject from, final DataObject to, final int channel) { final SelectiveAccessDescription expectedSelectiveAccess = this.createSelectiveAccessDescriptionDsmr4Interval(from, to); return new AttributeAddress( this.CLASS_ID_PROFILE, - this.OBIS_INTERVAL_DSMR4, + this.getObisCodeForChannel(this.OBIS_INTERVAL_DSMR4, channel), this.ATTR_ID_BUFFER, expectedSelectiveAccess); } @@ -562,31 +697,34 @@ private SelectiveAccessDescription createSelectiveAccessDescriptionDsmr4Interval // SMR5 private AttributeAddress createAttributeAddressSmr5Daily( - final DataObject from, final DataObject to) { + final DataObject from, final DataObject to, final int channel) { final SelectiveAccessDescription expectedSelectiveAccess = this.createSelectiveAccessDescriptionSmr5(from, to); return new AttributeAddress( - this.CLASS_ID_PROFILE, this.OBIS_DAILY_SMR5, this.ATTR_ID_BUFFER, expectedSelectiveAccess); + this.CLASS_ID_PROFILE, + this.getObisCodeForChannel(this.OBIS_DAILY_SMR5, channel), + this.ATTR_ID_BUFFER, + expectedSelectiveAccess); } private AttributeAddress createAttributeAddressSmr5Monthly( - final DataObject from, final DataObject to) { + final DataObject from, final DataObject to, final int channel) { final SelectiveAccessDescription expectedSelectiveAccess = this.createSelectiveAccessDescriptionSmr5(from, to); return new AttributeAddress( this.CLASS_ID_PROFILE, - this.OBIS_MONTHLY_SMR5, + this.getObisCodeForChannel(this.OBIS_MONTHLY_SMR5, channel), this.ATTR_ID_BUFFER, expectedSelectiveAccess); } private AttributeAddress createAttributeAddressSmr5Interval( - final DataObject from, final DataObject to) { + final DataObject from, final DataObject to, final int channel) { final SelectiveAccessDescription expectedSelectiveAccess = this.createSelectiveAccessDescriptionSmr5(from, to); return new AttributeAddress( this.CLASS_ID_PROFILE, - this.OBIS_INTERVAL_SMR5, + this.getObisCodeForChannel(this.OBIS_INTERVAL_SMR5, channel), this.ATTR_ID_BUFFER, expectedSelectiveAccess); } @@ -601,4 +739,23 @@ private SelectiveAccessDescription createSelectiveAccessDescriptionSmr5( return new SelectiveAccessDescription(1, expectedAccessParam); } + + private ObisCode getObisCodeForChannel(final String obis, final int channel) { + return new ObisCode(obis.replace("", String.valueOf(channel))); + } + + private DataObject getDataObjectForGasValueDsmr4(final int channel, final byte attributeId) { + return DataObject.newStructureData( + Arrays.asList( + DataObject.newUInteger16Data(this.CLASS_ID_EXTENDED_REGISTER), + DataObject.newOctetStringData( + this.getObisCodeForChannel(this.OBIS_GAS_VALUE_DSMR4, channel).bytes()), + DataObject.newInteger8Data(attributeId), + DataObject.newUInteger16Data(0))); + } + + private DataObject createValue(final long value, final int channel) { + // Add channel to value to make each value different + return DataObject.newUInteger32Data(value + channel); + } } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/periodicmeterreads/GetPeriodicMeterReadsGasCommandExecutorTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/periodicmeterreads/GetPeriodicMeterReadsGasCommandExecutorTest.java index 66399aafdba..b5524efb569 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/periodicmeterreads/GetPeriodicMeterReadsGasCommandExecutorTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/periodicmeterreads/GetPeriodicMeterReadsGasCommandExecutorTest.java @@ -4,53 +4,59 @@ package org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.periodicmeterreads; -import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Fail.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.refEq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import java.util.Arrays; -import java.util.Collections; import java.util.Date; import java.util.List; +import java.util.Map; import java.util.Optional; +import java.util.Set; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; +import org.junit.jupiter.params.provider.CsvSource; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoSettings; import org.mockito.quality.Strictness; +import org.openmuc.jdlms.AccessResultCode; import org.openmuc.jdlms.AttributeAddress; import org.openmuc.jdlms.GetResult; import org.openmuc.jdlms.ObisCode; import org.openmuc.jdlms.datatypes.DataObject; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.AttributeAddressForProfile; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsCaptureObject; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectConfigService; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectType; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.model.DlmsClock; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.model.DlmsExtendedRegister; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.model.DlmsObject; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.model.DlmsProfile; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.model.Medium; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.model.ProfileCaptureTime; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.model.RegisterUnit; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.AmrProfileStatusCodeHelper; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.DlmsDateTimeConverter; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.DlmsHelper; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDevice; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.Protocol; import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionManager; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.valueobjects.CombinedDeviceModelCode; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.valueobjects.CombinedDeviceModelCode.CombinedDeviceModelCodeBuilder; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; import org.opensmartgridplatform.adapter.protocol.dlms.infra.messaging.DlmsMessageListener; +import org.opensmartgridplatform.dlms.exceptions.ObjectConfigException; +import org.opensmartgridplatform.dlms.interfaceclass.attribute.ExtendedRegisterAttribute; +import org.opensmartgridplatform.dlms.objectconfig.AccessType; +import org.opensmartgridplatform.dlms.objectconfig.Attribute; +import org.opensmartgridplatform.dlms.objectconfig.CaptureObject; +import org.opensmartgridplatform.dlms.objectconfig.CosemObject; +import org.opensmartgridplatform.dlms.objectconfig.DlmsDataType; +import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; +import org.opensmartgridplatform.dlms.objectconfig.ValueType; +import org.opensmartgridplatform.dlms.objectconfig.dlmsclasses.ExtendedRegister; +import org.opensmartgridplatform.dlms.objectconfig.dlmsclasses.ProfileGeneric; +import org.opensmartgridplatform.dlms.services.ObjectConfigService; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ChannelDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.CosemDateDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.CosemDateTimeDto; @@ -72,10 +78,12 @@ class GetPeriodicMeterReadsGasCommandExecutorTest { @Mock private DlmsHelper dlmsHelper; - @Mock private DlmsObjectConfigService dlmsObjectConfigService; + @Mock private ObjectConfigService objectConfigService; @Mock private DlmsConnectionManager connectionManager; + @Mock private AmrProfileStatusCodeHelper amrProfileStatusCodeHelper; + private final DlmsDevice device = this.createDevice(Protocol.DSMR_4_2_2); private final long from = 1111110L; private final long to = 2222222L; @@ -83,9 +91,33 @@ class GetPeriodicMeterReadsGasCommandExecutorTest { private final DateTime toDateTime = new DateTime(this.to); private MessageMetadata messageMetadata; + private static final int CLASS_ID_DATA = 1; + private static final int CLASS_ID_EXTENDED_REGISTER = 4; + private static final int CLASS_ID_PROFILE_GENERIC = 7; + private static final int CLASS_ID_CLOCK = 8; + + private static final String SCALER_UNIT_DYNAMIC = "-3, M3"; + private static final String SCALER_UNIT_FIXED = "0, M3"; + @BeforeEach public void setUp() { - this.messageMetadata = MessageMetadata.newBuilder().withCorrelationUid("123456").build(); + + final CombinedDeviceModelCode.CombinedDeviceModelCodeBuilder builder = + new CombinedDeviceModelCodeBuilder(); + + final CombinedDeviceModelCode combinedDeviceModelCode = + builder + .gatewayDeviceModelCode("GateWayDeviceModelCode") + .channelBasedDeviceModelCode(1, "DeviceModelCh1") + .channelBasedDeviceModelCode(2, "") + .channelBasedDeviceModelCode(3, "") + .channelBasedDeviceModelCode(4, "") + .build(); + this.messageMetadata = + MessageMetadata.newBuilder() + .withCorrelationUid("123456") + .withDeviceModelCode(combinedDeviceModelCode.toString()) + .build(); when(this.connectionManager.getDlmsMessageListener()).thenReturn(this.dlmsMessageListener); } @@ -100,7 +132,7 @@ void testExecuteNullRequest() throws ProtocolAdapterException { } @Test - void testExecuteObjectNotFound() { + void testExecuteObjectNotFound() throws ProtocolAdapterException, ObjectConfigException { // SETUP final PeriodicMeterReadsRequestDto request = new PeriodicMeterReadsRequestDto( @@ -108,23 +140,24 @@ void testExecuteObjectNotFound() { this.fromDateTime.toDate(), this.toDateTime.toDate(), ChannelDto.ONE); - when(this.dlmsObjectConfigService.findAttributeAddressForProfile( - any(), any(), any(), any(), any(), any())) + when(this.objectConfigService.getOptionalCosemObject(any(), any(), any())) .thenReturn(Optional.empty()); + when(this.objectConfigService.getCosemObject(any(), any(), any())) + .thenThrow(new IllegalArgumentException("Object not found")); // CALL try { this.executor.execute(this.connectionManager, this.device, request, this.messageMetadata); - fail("When no matching object is found, then execute should fail"); - } catch (final ProtocolAdapterException e) { - assertThat(e.getMessage()) - .isEqualTo("No address found for " + DlmsObjectType.DAILY_LOAD_PROFILE); + fail("When no matching profile object is found, then execute should fail"); + } catch (final IllegalArgumentException e) { + assertThat(e.getMessage()).isEqualTo("Object not found"); } } @ParameterizedTest - @ValueSource(strings = {"UTC", "Australia/Tasmania"}) - void testHappyWithDifferentTimeZones(final String timeZone) throws Exception { + @CsvSource({"UTC,FIXED_IN_PROFILE", "Australia/Tasmania,DYNAMIC"}) + void testHappyWithDifferentTimeZones(final String timeZone, final ValueType valueType) + throws Exception { // SETUP - request final PeriodTypeDto periodType = PeriodTypeDto.DAILY; @@ -140,103 +173,117 @@ void testHappyWithDifferentTimeZones(final String timeZone) throws Exception { DlmsDateTimeConverter.toDateTime(new Date(this.to), this.device.getTimezone()); // SETUP - dlms objects - final DlmsObject dlmsClock = new DlmsClock("0.0.1.0.0.255"); - final DlmsCaptureObject captureObject1 = new DlmsCaptureObject(dlmsClock, 2); - - final DlmsObject dlmsExtendedRegister = - new DlmsExtendedRegister( - DlmsObjectType.MBUS_MASTER_VALUE, "0.0.24.0.0.255", 0, RegisterUnit.M3, Medium.GAS); - final DlmsCaptureObject captureObject2 = new DlmsCaptureObject(dlmsExtendedRegister, 2); - final DlmsCaptureObject captureObject3 = new DlmsCaptureObject(dlmsExtendedRegister, 5); - - final List captureObjects = - Arrays.asList(captureObject1, captureObject2, captureObject3); - - final DlmsProfile dlmsProfile = - new DlmsProfile( - DlmsObjectType.DAILY_LOAD_PROFILE, - "1.2.3.4.5.6", - captureObjects, - ProfileCaptureTime.DAY, - Medium.COMBINED); + final ProfileGeneric profile = this.createProfile(); + final CosemObject clock = this.createClock(); + final CosemObject status = this.createStatus(); + final ExtendedRegister value_g = this.createMBusMasterValue(valueType); + + final CaptureObject captureObjectClock = new CaptureObject(clock, 2); + final CaptureObject captureObjectStatus = new CaptureObject(status, 2); + final CaptureObject captureObjectValue = new CaptureObject(value_g, 2); + final CaptureObject captureObjectScalerUnit = new CaptureObject(value_g, 5); // SETUP - mock dlms object config to return attribute addresses - final AttributeAddressForProfile attributeAddressForProfile = - this.createAttributeAddressForProfile(dlmsProfile, captureObjects); - final AttributeAddress attributeAddressScalerUnit = - this.createAttributeAddress(dlmsExtendedRegister); - - when(this.dlmsObjectConfigService.findAttributeAddressForProfile( - eq(this.device), - eq(DlmsObjectType.DAILY_LOAD_PROFILE), - eq(channel.getChannelNumber()), - eq(convertedFromTime), - eq(convertedToTime), - eq(Medium.GAS))) - .thenReturn(Optional.of(attributeAddressForProfile)); - - when(this.dlmsObjectConfigService.getAttributeAddressesForScalerUnit( - eq(attributeAddressForProfile), eq(channel.getChannelNumber()))) - .thenReturn(Collections.singletonList(attributeAddressScalerUnit)); - - final DlmsObject intervalTime = mock(DlmsObject.class); - when(this.dlmsObjectConfigService.findDlmsObject( - any(Protocol.class), any(DlmsObjectType.class), any(Medium.class))) - .thenReturn(Optional.of(intervalTime)); + when(this.objectConfigService.getOptionalCosemObject( + "DSMR", "4.2.2", DlmsObjectType.DAILY_VALUES_G)) + .thenReturn(Optional.of(profile)); + when(this.objectConfigService.getCosemObject("DSMR", "4.2.2", DlmsObjectType.CLOCK)) + .thenReturn(clock); + when(this.objectConfigService.getCosemObject( + "DSMR", "4.2.2", DlmsObjectType.AMR_PROFILE_STATUS)) + .thenReturn(status); + when(this.objectConfigService.getCosemObject("DSMR", "4.2.2", DlmsObjectType.MBUS_MASTER_VALUE)) + .thenReturn(value_g); + when(this.objectConfigService.getCaptureObjects(profile, "DSMR", "4.2.2", "DeviceModelCh1")) + .thenReturn( + List.of( + captureObjectClock, + captureObjectStatus, + captureObjectValue, + captureObjectScalerUnit)); + + when(this.dlmsHelper.getAccessSelectionTimeRangeParameter( + eq(this.fromDateTime), eq(this.toDateTime), any())) + .thenReturn(mock(DataObject.class)); // SETUP - mock dlms helper to return data objects on request - final DataObject data0 = mock(DataObject.class); - final DataObject data1 = mock(DataObject.class); - final DataObject data2 = mock(DataObject.class); + final DataObject data0 = mock(DataObject.class); // clock + final DataObject data1 = mock(DataObject.class); // status + final DataObject data2 = mock(DataObject.class); // value + final DataObject data3 = mock(DataObject.class); // capture time final DataObject bufferedObject1 = mock(DataObject.class); - when(bufferedObject1.getValue()).thenReturn(asList(data0, data1, data2)); - - final DataObject data3 = mock(DataObject.class); - final DataObject data4 = mock(DataObject.class); - final DataObject data5 = mock(DataObject.class); + when(bufferedObject1.getValue()).thenReturn(List.of(data0, data1, data2, data3)); + when(data1.isNumber()).thenReturn(true); + when(data1.getValue()).thenReturn(0); + + final DataObject data4 = mock(DataObject.class); // clock + final DataObject data5 = mock(DataObject.class); // status + final DataObject data6 = mock(DataObject.class); // value + final DataObject data7 = mock(DataObject.class); // capture time final DataObject bufferedObject2 = mock(DataObject.class); - when(bufferedObject2.getValue()).thenReturn(asList(data3, data4, data5)); - - final DataObject data6 = mock(DataObject.class); - final DataObject data7 = mock(DataObject.class); - final DataObject data8 = mock(DataObject.class); + when(bufferedObject2.getValue()).thenReturn(List.of(data4, data5, data6, data7)); + when(data5.isNumber()).thenReturn(true); + when(data5.getValue()).thenReturn(0); + + final DataObject data8 = mock(DataObject.class); // clock + final DataObject data9 = mock(DataObject.class); // status + final DataObject data10 = mock(DataObject.class); // value + final DataObject data11 = mock(DataObject.class); // capture time final DataObject bufferedObject3 = mock(DataObject.class); - when(bufferedObject3.getValue()).thenReturn(asList(data6, data7, data8)); + when(bufferedObject3.getValue()).thenReturn(List.of(data8, data9, data10, data11)); final DataObject resultData = mock(DataObject.class); - when(resultData.getValue()).thenReturn(asList(bufferedObject1, bufferedObject2)); + when(resultData.getValue()).thenReturn(List.of(bufferedObject1, bufferedObject2)); final String expectedDescription = - "retrieve periodic meter reads for " + periodType + ", channel " + channel; + "retrieve periodic meter reads for " + + periodType + + ", channel " + + channel.getChannelNumber(); final GetResult getResult = mock(GetResult.class); when(this.dlmsHelper.getAndCheck( - eq(this.connectionManager), - eq(this.device), - eq(expectedDescription), - eq(attributeAddressForProfile.getAttributeAddress()))) - .thenReturn(Collections.singletonList(getResult)); - when(this.dlmsHelper.getAndCheck( - this.connectionManager, this.device, expectedDescription, attributeAddressScalerUnit)) - .thenReturn(Collections.singletonList(getResult)); + eq(this.connectionManager), eq(this.device), eq(expectedDescription), any())) + .thenReturn(List.of(getResult)); when(this.dlmsHelper.readDataObject(eq(getResult), any(String.class))).thenReturn(resultData); + // SETUP - mock dlms helper to return data objects for scaler units on request + final String scalerUnit = + valueType.equals(ValueType.DYNAMIC) ? SCALER_UNIT_DYNAMIC : SCALER_UNIT_FIXED; + final GetResult getResultScalerUnits = mock(GetResult.class); + final AttributeAddress expectedAttributeAddressScalerUnit = + new AttributeAddress( + CLASS_ID_EXTENDED_REGISTER, + new ObisCode("0.1.24.1.0.255"), + ExtendedRegisterAttribute.SCALER_UNIT.attributeId(), + null); + when(this.dlmsHelper.getWithList( + eq(this.connectionManager), eq(this.device), refEq(expectedAttributeAddressScalerUnit))) + .thenReturn(List.of(getResultScalerUnits)); + when(getResultScalerUnits.getResultCode()).thenReturn(AccessResultCode.SUCCESS); + + when(this.dlmsHelper.getScalerUnit(any(), any())).thenReturn(scalerUnit); + // Make mocks return different times for each meterread. The last meterread has a time - // outside of the requested period, causing the meterread to be not included in the result. + // outside the requested period, causing the meterread to be not included in the result. final CosemDateTimeDto timeMeterRead1 = new CosemDateTimeDto(this.fromDateTime); final CosemDateTimeDto timeMeterRead2 = new CosemDateTimeDto(this.fromDateTime.plusMinutes(1)); final CosemDateTimeDto timeMeterRead3 = new CosemDateTimeDto(this.fromDateTime.plusYears(1)); when(this.dlmsHelper.readDateTime(eq(data0), any())).thenReturn(timeMeterRead1); - when(this.dlmsHelper.readDateTime(eq(data2), any())).thenReturn(timeMeterRead1); - when(this.dlmsHelper.readDateTime(eq(data3), any())).thenReturn(timeMeterRead2); - when(this.dlmsHelper.readDateTime(eq(data5), any())).thenReturn(timeMeterRead2); - when(this.dlmsHelper.readDateTime(eq(data6), any())).thenReturn(timeMeterRead3); + when(this.dlmsHelper.readDateTime(eq(data3), any())).thenReturn(timeMeterRead1); + when(this.dlmsHelper.readDateTime(eq(data4), any())).thenReturn(timeMeterRead2); + when(this.dlmsHelper.readDateTime(eq(data7), any())).thenReturn(timeMeterRead2); when(this.dlmsHelper.readDateTime(eq(data8), any())).thenReturn(timeMeterRead3); + when(this.dlmsHelper.readDateTime(eq(data11), any())).thenReturn(timeMeterRead3); + + when(this.amrProfileStatusCodeHelper.toAmrProfileStatusCodeFlags(0)).thenReturn(Set.of()); final DlmsMeterValueDto meterValue1 = mock(DlmsMeterValueDto.class); final DlmsMeterValueDto meterValue2 = mock(DlmsMeterValueDto.class); - when(this.dlmsHelper.getScaledMeterValue(data1, null, "gasValue")).thenReturn(meterValue1); - when(this.dlmsHelper.getScaledMeterValue(data4, null, "gasValue")).thenReturn(meterValue2); + when(this.dlmsHelper.getScaledMeterValueWithScalerUnit(data2, scalerUnit, "gasValue")) + .thenReturn(meterValue1); + when(this.dlmsHelper.getScaledMeterValueWithScalerUnit(data6, scalerUnit, "gasValue")) + .thenReturn(meterValue2); // CALL final PeriodicMeterReadGasResponseDto result = @@ -249,12 +296,17 @@ void testHappyWithDifferentTimeZones(final String timeZone) throws Exception { "GetPeriodicMeterReadsGas for channel ONE, DAILY from %s until %s, retrieve attribute: {%s,%s,%s}", convertedFromTime, convertedToTime, - dlmsProfile.getClassId(), - dlmsProfile.getObisCodeAsString(), - dlmsProfile.getDefaultAttributeId())); + profile.getClassId(), + profile.getObis().replace("x", String.valueOf(channel.getChannelNumber())), + 2)); - verify(this.dlmsObjectConfigService) - .findDlmsObject(any(Protocol.class), any(DlmsObjectType.class), any(Medium.class)); + // Expect only one call to retrieve the values from the buffer + verify(this.dlmsHelper, times(1)) + .getAndCheck(eq(this.connectionManager), eq(this.device), any(), any()); + + // If a dynamic scalerUnit is used then expect 1 additional call + verify(this.dlmsHelper, times(valueType == ValueType.DYNAMIC ? 1 : 0)) + .getWithList(eq(this.connectionManager), eq(this.device), any()); // ASSERT - the result should contain 2 values final List periodicMeterReads = @@ -285,30 +337,75 @@ void testHappyWithDifferentTimeZones(final String timeZone) throws Exception { .isTrue(); } - private AttributeAddress createAttributeAddress(final DlmsObject dlmsObject) { - return new AttributeAddress( - dlmsObject.getClassId(), - new ObisCode(dlmsObject.getObisCodeAsString()), - dlmsObject.getDefaultAttributeId()); + private CosemObject createCosemObject( + final int classId, + final String tag, + final String obis, + final String group, + final List attributes) { + return new CosemObject( + tag, "descr", classId, 0, obis, group, null, List.of(), Map.of(), attributes); } - private AttributeAddressForProfile createAttributeAddressForProfile( - final DlmsObject dlmsObject, final List selectedObjects) { - return new AttributeAddressForProfile( - new AttributeAddress( - dlmsObject.getClassId(), - new ObisCode(dlmsObject.getObisCodeAsString()), - dlmsObject.getDefaultAttributeId(), - null), - selectedObjects); + private Attribute createAttribute(final int id, final String value) { + return this.createAttribute(id, value, ValueType.FIXED_IN_PROFILE); + } + + private Attribute createAttribute(final int id, final String value, final ValueType valueType) { + return new Attribute( + id, "descr", null, DlmsDataType.DONT_CARE, valueType, value, null, AccessType.RW); } private DlmsDevice createDevice(final Protocol protocol) { final DlmsDevice device = new DlmsDevice(); + device.setSelectiveAccessPeriodicMeterReadsSupported(true); device.setProtocol(protocol); return device; } + private ProfileGeneric createProfile() { + final Attribute attributeCaptureObjects = + this.createAttribute( + 3, "CLOCK,2|AMR_PROFILE_STATUS,2|MBUS_MASTER_VALUE,2|MBUS_MASTER_VALUE,5"); + final Attribute attributeCapturePeriod = this.createAttribute(4, "86400"); + return new ProfileGeneric( + "DAILY_VALUES_G", + "descr", + this.CLASS_ID_PROFILE_GENERIC, + 0, + "1.x.3.4.5.6", + "GAS", + null, + List.of(), + Map.of(), + List.of(attributeCaptureObjects, attributeCapturePeriod)); + } + + private CosemObject createClock() { + return this.createCosemObject( + this.CLASS_ID_CLOCK, "CLOCK", "0.0.1.0.0.255", "ABSTRACT", List.of()); + } + + private CosemObject createStatus() { + return this.createCosemObject( + this.CLASS_ID_DATA, "AMR_PROFILE_STATUS", "0.x.1.2.3.255", "GAS", List.of()); + } + + private ExtendedRegister createMBusMasterValue(final ValueType valueType) { + final Attribute attributeScalerUnit = this.createAttribute(3, "0, M3", valueType); + return new ExtendedRegister( + "MBUS_MASTER_VALUE", + "descr", + this.CLASS_ID_EXTENDED_REGISTER, + 0, + "0.x.24.1.0.255", + "GAS", + null, + List.of(), + Map.of(), + List.of(attributeScalerUnit)); + } + // Compares date with cosemDateTime. Note: cosemDateTime uses hundredths and // not milliseconds private boolean areDatesEqual(final Date date, final CosemDateTimeDto cosemDateTime) { diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/stub/DlmsConnectionStub.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/stub/DlmsConnectionStub.java index c4cf1b64d6d..ef3ee48fe9e 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/stub/DlmsConnectionStub.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/stub/DlmsConnectionStub.java @@ -164,6 +164,12 @@ public boolean hasMethodBeenInvoked(final MethodClass methodClass) { .anyMatch(parameter -> parameter.getId() == methodClass.getMethodId()); } + public long getMethodInvocationCount(final MethodClass methodClass) { + return this.methodsInvoked.stream() + .filter(parameter -> parameter.getId() == methodClass.getMethodId()) + .count(); + } + public void addReturnValue( final AttributeAddress attributeAddress, final DataObject dataObject, diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/testutil/ObjectConfigServiceHelper.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/testutil/ObjectConfigServiceHelper.java index 460874da1fc..cc797cee340 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/testutil/ObjectConfigServiceHelper.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/testutil/ObjectConfigServiceHelper.java @@ -7,11 +7,17 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Map; +import org.opensmartgridplatform.dlms.objectconfig.AccessType; import org.opensmartgridplatform.dlms.objectconfig.Attribute; import org.opensmartgridplatform.dlms.objectconfig.CosemObject; +import org.opensmartgridplatform.dlms.objectconfig.DlmsDataType; import org.opensmartgridplatform.dlms.objectconfig.MeterType; +import org.opensmartgridplatform.dlms.objectconfig.ObjectProperty; +import org.opensmartgridplatform.dlms.objectconfig.ValueType; public class ObjectConfigServiceHelper { + private static final int ATTRIBUTE_ID_SCALER_UNIT = 3; public static CosemObject createObject( @@ -20,23 +26,47 @@ public static CosemObject createObject( final String tag, final String scalerUnitValue, final boolean polyphase) { - final CosemObject object = new CosemObject(); - object.setClassId(classId); - object.setObis(obis); - object.setTag(tag); - if (scalerUnitValue != null) { - object.setAttributes(createScalerUnitAttributeList(scalerUnitValue)); - } - object.setMeterTypes(getMeterTypes(polyphase)); + return createObject(classId, obis, tag, scalerUnitValue, polyphase, Map.of()); + } + + public static CosemObject createObject( + final int classId, + final String obis, + final String tag, + final String scalerUnitValue, + final boolean polyphase, + final Map properties) { + return createObject( + classId, + obis, + tag, + polyphase, + properties, + scalerUnitValue != null ? createScalerUnitAttributeList(scalerUnitValue) : List.of()); + } - return object; + public static CosemObject createObject( + final int classId, + final String obis, + final String tag, + final boolean polyphase, + final Map properties, + final List attributes) { + return new CosemObject( + tag, "descr", classId, 0, obis, "", null, getMeterTypes(polyphase), properties, attributes); } private static List createScalerUnitAttributeList(final String value) { - final Attribute scalerUnitAttribute = new Attribute(); - scalerUnitAttribute.setId(ATTRIBUTE_ID_SCALER_UNIT); - scalerUnitAttribute.setValue(value); - return Collections.singletonList(scalerUnitAttribute); + return List.of( + new Attribute( + ATTRIBUTE_ID_SCALER_UNIT, + "descr", + null, + DlmsDataType.DONT_CARE, + ValueType.FIXED_IN_PROFILE, + value, + null, + AccessType.RW)); } private static List getMeterTypes(final boolean polyphase) { @@ -46,4 +76,16 @@ private static List getMeterTypes(final boolean polyphase) { return Arrays.asList(MeterType.PP, MeterType.SP); } } + + public static Attribute createAttribute(final int id, final String value) { + return new Attribute( + id, + "descr", + null, + DlmsDataType.DONT_CARE, + ValueType.FIXED_IN_PROFILE, + value, + null, + AccessType.RW); + } } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/utils/DlmsHelperTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/utils/DlmsHelperTest.java index 9da73aa2284..c7c6db7c986 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/utils/DlmsHelperTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/utils/DlmsHelperTest.java @@ -6,8 +6,10 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.when; import java.io.IOException; @@ -17,12 +19,16 @@ import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.Arrays; +import java.util.List; +import java.util.Map; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.joda.time.format.ISODateTimeFormat; import org.junit.jupiter.api.Test; +import org.openmuc.jdlms.AccessResultCode; import org.openmuc.jdlms.AttributeAddress; import org.openmuc.jdlms.DlmsConnection; +import org.openmuc.jdlms.GetResult; import org.openmuc.jdlms.datatypes.CosemDateTime; import org.openmuc.jdlms.datatypes.DataObject; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.testutil.GetResultImpl; @@ -30,6 +36,11 @@ import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionManager; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ConnectionException; import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; +import org.opensmartgridplatform.dlms.objectconfig.AccessType; +import org.opensmartgridplatform.dlms.objectconfig.Attribute; +import org.opensmartgridplatform.dlms.objectconfig.CosemObject; +import org.opensmartgridplatform.dlms.objectconfig.DlmsDataType; +import org.opensmartgridplatform.dlms.objectconfig.ValueType; import org.opensmartgridplatform.dto.valueobjects.smartmetering.ClockStatusDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.CosemDateDto; import org.opensmartgridplatform.dto.valueobjects.smartmetering.CosemDateTimeDto; @@ -63,6 +74,10 @@ public class DlmsHelperTest { public static final int DLMS_UNIT_WH = 30; public static final int DLMS_UNIT_UNDEFINED = 0; + public static final int CLASS_ID = 3; + public static final String OBIS = "1.0.32.7.0.255"; + private final int ATTRIBUTE_ID = 3; + private final DlmsHelper dlmsHelper = new DlmsHelper(); @Test @@ -282,6 +297,148 @@ void testGetScaledMeterValueWithDataObject() throws ProtocolAdapterException { assertThat(meterValueDto.getDlmsUnit()).isEqualTo(DlmsUnitTypeDto.VAR); } + @Test + void testGetScalerUnit() { + final DataObject wrongType = DataObject.newBoolData(false); + final DataObject structureWithOnlyOneElement = + DataObject.newStructureData(DataObject.newInteger8Data((byte) 2)); + final DataObject unitUndefined = + DataObject.newStructureData( + DataObject.newInteger8Data((byte) 2), DataObject.newEnumerateData(0)); + + assertThrows( + ProtocolAdapterException.class, + () -> { + this.dlmsHelper.getScalerUnit(wrongType, "getScalerUnitTest"); + }); + + assertThrows( + ProtocolAdapterException.class, + () -> { + this.dlmsHelper.getScalerUnit(structureWithOnlyOneElement, "getScalerUnitTest"); + }); + + assertThrows( + ProtocolAdapterException.class, + () -> { + this.dlmsHelper.getScalerUnit(unitUndefined, "getScalerUnitTest"); + }); + } + + void getScalerUnitValueFixedInProfile() throws ProtocolAdapterException { + final int scaler = 0; + final DlmsUnitTypeDto unit = DlmsUnitTypeDto.VOLT; + + final DlmsConnectionManager connectionManager = mock(DlmsConnectionManager.class); + + final CosemObject cosemObject = + this.newCosemObject(ValueType.FIXED_IN_PROFILE, scaler + ", " + unit.getUnit()); + + final String result = this.dlmsHelper.getScalerUnitValue(connectionManager, cosemObject); + assertThat(result).isEqualTo(scaler + ", " + unit.getUnit()); + verifyNoInteractions(connectionManager); + } + + @Test + void getScalerUnitValue() throws ProtocolAdapterException, IOException { + final int scaler = -1; + final DlmsUnitTypeDto unit = DlmsUnitTypeDto.VOLT; + + final DlmsConnectionManager connectionManager = mock(DlmsConnectionManager.class); + final DataObject dataObject = + DataObject.newArrayData( + List.of( + DataObject.newInteger32Data(scaler), DataObject.newInteger32Data(unit.getIndex()))); + this.mockGetAttribute(connectionManager, dataObject); + + final CosemObject cosemObject = this.newCosemObject(ValueType.DYNAMIC, "0, V"); + + final String result = this.dlmsHelper.getScalerUnitValue(connectionManager, cosemObject); + assertThat(result).isEqualTo(scaler + ", " + unit.getUnit()); + } + + @Test + void getScalerUnitValueWrongDataType() throws ProtocolAdapterException, IOException { + final DlmsConnectionManager connectionManager = mock(DlmsConnectionManager.class); + final DataObject dataObject = DataObject.newInteger32Data(666); + this.mockGetAttribute(connectionManager, dataObject); + + final CosemObject cosemObject = this.newCosemObject(ValueType.DYNAMIC, "0, V"); + + final ProtocolAdapterException protocolAdapterException = + assertThrows( + ProtocolAdapterException.class, + () -> { + this.dlmsHelper.getScalerUnitValue(connectionManager, cosemObject); + }); + assertThat(protocolAdapterException.getMessage()) + .contains("complex data (structure) expected while retrieving scaler and unit."); + } + + @Test + void getScalerUnitValueWrongSize() throws ProtocolAdapterException, IOException { + final DlmsConnectionManager connectionManager = mock(DlmsConnectionManager.class); + final DataObject dataObject = + DataObject.newArrayData(List.of(DataObject.newInteger32Data(666))); + this.mockGetAttribute(connectionManager, dataObject); + + final CosemObject cosemObject = this.newCosemObject(ValueType.DYNAMIC, "0, V"); + + final ProtocolAdapterException protocolAdapterException = + assertThrows( + ProtocolAdapterException.class, + () -> { + this.dlmsHelper.getScalerUnitValue(connectionManager, cosemObject); + }); + assertThat(protocolAdapterException.getMessage()) + .contains("expected 2 values while retrieving scaler and unit."); + } + + @Test + void getScalerUnitValueFunctionalException() throws ProtocolAdapterException, IOException { + final DlmsConnectionManager connectionManager = mock(DlmsConnectionManager.class); + final DlmsConnection dlmsConnection = mock(DlmsConnection.class); + final GetResult getResult = + new GetResultImpl(DataObject.newNullData(), AccessResultCode.OTHER_REASON); + when(dlmsConnection.get(any(AttributeAddress.class))).thenReturn(getResult); + when(connectionManager.getConnection()).thenReturn(dlmsConnection); + + final CosemObject cosemObject = this.newCosemObject(ValueType.DYNAMIC, "0, V"); + + final ProtocolAdapterException protocolAdapterException = + assertThrows( + ProtocolAdapterException.class, + () -> { + this.dlmsHelper.getScalerUnitValue(connectionManager, cosemObject); + }); + assertThat(protocolAdapterException.getMessage()) + .contains("FunctionalException occurred when reading dynamic scalar unit for object"); + } + + private void mockGetAttribute( + final DlmsConnectionManager connectionManager, final DataObject dataObject) + throws IOException { + final DlmsConnection dlmsConnection = mock(DlmsConnection.class); + final GetResult getResult = new GetResultImpl(dataObject, AccessResultCode.SUCCESS); + when(dlmsConnection.get(any(AttributeAddress.class))).thenReturn(getResult); + when(connectionManager.getConnection()).thenReturn(dlmsConnection); + } + + private CosemObject newCosemObject(final ValueType valueType, final String value) { + final Attribute attribute = + new Attribute( + this.ATTRIBUTE_ID, + "descr", + null, + DlmsDataType.DONT_CARE, + valueType, + value, + null, + AccessType.RW); + return new CosemObject( + "TAG", "descr", CLASS_ID, 0, OBIS, "", null, List.of(), Map.of(), List.of(attribute)); + } + private void assertGetWithListException( final Class jdlmsExceptionClazz, final Class exceptionClazz) diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/utils/ObjectConfigServiceHelperTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/utils/ObjectConfigServiceHelperTest.java new file mode 100644 index 00000000000..f2ee9a49b9b --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/commands/utils/ObjectConfigServiceHelperTest.java @@ -0,0 +1,209 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.when; + +import java.util.Optional; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.openmuc.jdlms.AttributeAddress; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDevice; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.Protocol; +import org.opensmartgridplatform.adapter.protocol.dlms.exceptions.ProtocolAdapterException; +import org.opensmartgridplatform.dlms.exceptions.ObjectConfigException; +import org.opensmartgridplatform.dlms.objectconfig.Attribute; +import org.opensmartgridplatform.dlms.objectconfig.CosemObject; +import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; +import org.opensmartgridplatform.dlms.services.ObjectConfigService; + +@ExtendWith(MockitoExtension.class) +class ObjectConfigServiceHelperTest { + + @Mock private ObjectConfigService objectConfigService; + @Mock private DlmsDevice dlmsDevice; + + @Mock private Attribute attribute; + + @Mock CosemObject cosemObject; + + @InjectMocks private ObjectConfigServiceHelper objectConfigServiceHelper; + + @Test + void findDefaultAttributeAddressShouldReturnAnObject() + throws ProtocolAdapterException, ObjectConfigException { + + when(this.attribute.getId()).thenReturn(2); + when(this.cosemObject.getObis()).thenReturn("0.1.24.1.0.255"); + when(this.cosemObject.getAttribute(2)).thenReturn(this.attribute); + + when(this.objectConfigService.getOptionalCosemObject( + Protocol.SMR_5_1.getName(), + Protocol.SMR_5_1.getVersion(), + org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.MBUS_CLIENT_SETUP)) + .thenReturn(Optional.of(this.cosemObject)); + + final AttributeAddress attributeAddress = + this.objectConfigServiceHelper.findDefaultAttributeAddress( + this.dlmsDevice, Protocol.SMR_5_1, DlmsObjectType.MBUS_CLIENT_SETUP, 1); + + assertAttributeAddress(attributeAddress); + } + + @Test + void findAttributeAddressShouldReturnAnObject() + throws ProtocolAdapterException, ObjectConfigException { + + when(this.attribute.getId()).thenReturn(2); + when(this.cosemObject.getObis()).thenReturn("0.1.24.1.0.255"); + when(this.cosemObject.getAttribute(2)).thenReturn(this.attribute); + + when(this.objectConfigService.getOptionalCosemObject( + Protocol.SMR_5_1.getName(), + Protocol.SMR_5_1.getVersion(), + org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.MBUS_CLIENT_SETUP)) + .thenReturn(Optional.of(this.cosemObject)); + + final AttributeAddress attributeAddress = + this.objectConfigServiceHelper.findAttributeAddress( + this.dlmsDevice, Protocol.SMR_5_1, DlmsObjectType.MBUS_CLIENT_SETUP, 1, 2); + + assertAttributeAddress(attributeAddress); + } + + @Test + void findDefaultAttributeAddressShouldThrowException() throws ObjectConfigException { + when(this.cosemObject.getObis()).thenReturn("0.1.24.1.0.255"); + when(this.dlmsDevice.getDeviceId()).thenReturn(Long.valueOf("28001")); + + when(this.objectConfigService.getOptionalCosemObject( + Protocol.SMR_5_1.getName(), + Protocol.SMR_5_1.getVersion(), + org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.MBUS_CLIENT_SETUP)) + .thenReturn(Optional.of(this.cosemObject)); + + final ProtocolAdapterException protocolAdapterException = + assertThrows( + ProtocolAdapterException.class, + () -> + this.objectConfigServiceHelper.findDefaultAttributeAddress( + this.dlmsDevice, Protocol.SMR_5_1, DlmsObjectType.MBUS_CLIENT_SETUP, 1)); + + assertThat(protocolAdapterException).isNotNull(); + assertThat(protocolAdapterException.getMessage()) + .isEqualTo("Did not find MBUS_CLIENT_SETUP object for device 28001 for channel 1"); + } + + @Test + void findAttributeAddressShouldThrowException() throws ObjectConfigException { + when(this.cosemObject.getObis()).thenReturn("0.1.24.1.0.255"); + when(this.dlmsDevice.getDeviceId()).thenReturn(Long.valueOf("28001")); + + when(this.objectConfigService.getOptionalCosemObject( + Protocol.SMR_5_1.getName(), + Protocol.SMR_5_1.getVersion(), + org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.MBUS_CLIENT_SETUP)) + .thenReturn(Optional.of(this.cosemObject)); + + final ProtocolAdapterException protocolAdapterException = + assertThrows( + ProtocolAdapterException.class, + () -> + this.objectConfigServiceHelper.findAttributeAddress( + this.dlmsDevice, Protocol.SMR_5_1, DlmsObjectType.MBUS_CLIENT_SETUP, 1, 2)); + + assertThat(protocolAdapterException).isNotNull(); + assertThat(protocolAdapterException.getMessage()) + .isEqualTo("Did not find MBUS_CLIENT_SETUP object for device 28001 for channel 1"); + } + + @Test + void findOptionalDefaultAttributeAddressShouldReturnAnAttributeAddress() + throws ObjectConfigException { + + when(this.attribute.getId()).thenReturn(2); + when(this.cosemObject.getObis()).thenReturn("0.1.24.1.0.255"); + when(this.cosemObject.getAttribute(2)).thenReturn(this.attribute); + + when(this.objectConfigService.getOptionalCosemObject( + Protocol.SMR_5_1.getName(), + Protocol.SMR_5_1.getVersion(), + org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.MBUS_CLIENT_SETUP)) + .thenReturn(Optional.of(this.cosemObject)); + + final Optional attributeAddressOpt = + this.objectConfigServiceHelper.findOptionalDefaultAttributeAddress( + Protocol.SMR_5_1, DlmsObjectType.MBUS_CLIENT_SETUP, 1); + + assertThat(attributeAddressOpt).isPresent(); + assertAttributeAddress(attributeAddressOpt.get()); + } + + @Test + void findOptionalAttributeAddressShouldReturnAnAttributeAddress() throws ObjectConfigException { + + when(this.attribute.getId()).thenReturn(2); + when(this.cosemObject.getObis()).thenReturn("0.1.24.1.0.255"); + when(this.cosemObject.getAttribute(2)).thenReturn(this.attribute); + + when(this.objectConfigService.getOptionalCosemObject( + Protocol.SMR_5_1.getName(), + Protocol.SMR_5_1.getVersion(), + org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.MBUS_CLIENT_SETUP)) + .thenReturn(Optional.of(this.cosemObject)); + + final Optional attributeAddressOpt = + this.objectConfigServiceHelper.findOptionalAttributeAddress( + Protocol.SMR_5_1, DlmsObjectType.MBUS_CLIENT_SETUP, 1, 2); + + assertThat(attributeAddressOpt).isPresent(); + assertAttributeAddress(attributeAddressOpt.get()); + } + + @Test + void findOptionalDefaultAttributeAddressShouldReturnAEmptyOptional() + throws ObjectConfigException { + + when(this.objectConfigService.getOptionalCosemObject( + Protocol.SMR_5_1.getName(), + Protocol.SMR_5_1.getVersion(), + org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.MBUS_CLIENT_SETUP)) + .thenReturn(Optional.empty()); + + final Optional attributeAddressOpt = + this.objectConfigServiceHelper.findOptionalDefaultAttributeAddress( + Protocol.SMR_5_1, DlmsObjectType.MBUS_CLIENT_SETUP, 1); + + assertThat(attributeAddressOpt).isEmpty(); + } + + @Test + void findOptionalAttributeAddressShouldReturnAEmptyOptional() throws ObjectConfigException { + + when(this.objectConfigService.getOptionalCosemObject( + Protocol.SMR_5_1.getName(), + Protocol.SMR_5_1.getVersion(), + org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType.MBUS_CLIENT_SETUP)) + .thenReturn(Optional.empty()); + + final Optional attributeAddressOpt = + this.objectConfigServiceHelper.findOptionalAttributeAddress( + Protocol.SMR_5_1, DlmsObjectType.MBUS_CLIENT_SETUP, 1, 2); + + assertThat(attributeAddressOpt).isEmpty(); + } + + private static void assertAttributeAddress(final AttributeAddress attributeAddress) { + assertThat(attributeAddress).isNotNull(); + assertThat(attributeAddress.getClassId()).as("classId").isZero(); + assertThat(attributeAddress.getId()).as("id").isEqualTo(2); + assertThat(attributeAddress.getInstanceId()).as("instanceId").hasToString("0.1.24.1.0.255"); + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/entities/ProtocolTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/entities/ProtocolTest.java index 19fa6ce6c96..40fa3885999 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/entities/ProtocolTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/entities/ProtocolTest.java @@ -46,15 +46,6 @@ public void testProtocolWithNameAndVersion() { assertThat(Protocol.withNameAndVersion("other", "0.1")).isEqualTo(Protocol.OTHER_PROTOCOL); } - @Test - public void testIsSelectingValuesSupported() { - assertThat(Protocol.DSMR_4_2_2.isSelectValuesInSelectiveAccessSupported()).isEqualTo(true); - assertThat(Protocol.SMR_5_0_0.isSelectValuesInSelectiveAccessSupported()).isEqualTo(true); - assertThat(Protocol.SMR_5_1.isSelectValuesInSelectiveAccessSupported()).isEqualTo(true); - assertThat(Protocol.SMR_5_2.isSelectValuesInSelectiveAccessSupported()).isEqualTo(true); - assertThat(Protocol.OTHER_PROTOCOL.isSelectValuesInSelectiveAccessSupported()).isEqualTo(true); - } - @Test public void testIsSMR5() { assertThat(Protocol.DSMR_4_2_2.isSmr5()).isEqualTo(false); diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/DlmsConnectionFactoryTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/DlmsConnectionFactoryTest.java index 7549f8ed8a8..07b2105e486 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/DlmsConnectionFactoryTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/DlmsConnectionFactoryTest.java @@ -138,7 +138,7 @@ void createsPublicClientConnectionManagerForDevice() throws Exception { this.newConnectionManager(device, listener, this.lls0Connector); this.factory.createAndHandlePublicClientConnection( - this.messageMetadata, device, listener, this.task); + this.messageMetadata, device, listener, null, this.task); this.assertConnectionManagerForDevice(expected); } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/DlmsConnectionHelperTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/DlmsConnectionHelperTest.java index e1492590654..4dbac73214b 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/DlmsConnectionHelperTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/DlmsConnectionHelperTest.java @@ -56,7 +56,7 @@ void setUp() { this.messageMetadata = MessageMetadata.newBuilder() .withCorrelationUid("123456") - .withIpAddress("192.168.92.56") + .withNetworkAddress("192.168.92.56") .build(); this.task = dlmsConnectionManager -> {}; } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/InvocationCounterManagerTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/InvocationCounterManagerTest.java index cfeb772c919..f3360122038 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/InvocationCounterManagerTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/factories/InvocationCounterManagerTest.java @@ -11,6 +11,7 @@ import static org.mockito.ArgumentMatchers.isNotNull; import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.ArgumentMatchers.refEq; +import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -24,6 +25,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.openmuc.jdlms.AttributeAddress; @@ -44,6 +46,7 @@ class InvocationCounterManagerTest { private static final AttributeAddress ATTRIBUTE_ADDRESS_INVOCATION_COUNTER_VALUE = new AttributeAddress(1, new ObisCode(new byte[] {0, 0, 43, 1, 0, -1}), 2); + private static final String IP_ADDRESS = "1.2.3.4"; private InvocationCounterManager manager; private MessageMetadata messageMetadata; @@ -74,19 +77,28 @@ void setUp() { } @Test - void initializeInvocationCounterForDeviceTaskExecuted() throws OsgpException { + void resetIpAddressAfterInitialize() throws OsgpException { + this.device = mock(DlmsDevice.class); + this.manager.initializeInvocationCounter(this.messageMetadata, this.device); - verify(this.connectionFactory, times(1)) + final InOrder inOrder = inOrder(this.connectionFactory, this.device); + inOrder.verify(this.device).setIpAddress(null); + inOrder + .verify(this.connectionFactory, times(1)) .createAndHandlePublicClientConnection( any(MessageMetadata.class), eq(this.device), isNull(), isNull(), any()); + inOrder.verify(this.device).setIpAddress(null); } @Test void initializeInvocationCounterForDeviceTaskExecutedDebugEnabled() throws OsgpException { this.device.setInDebugMode(true); + this.device.setIpAddress(IP_ADDRESS); + this.manager.initializeInvocationCounter(this.messageMetadata, this.device); + assertThat(this.device.getIpAddress()).isNull(); verify(this.connectionFactory, times(1)) .createAndHandlePublicClientConnection( any(MessageMetadata.class), eq(this.device), isNotNull(), isNull(), any()); diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/valueobjects/CombinedDeviceModelCodeTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/valueobjects/CombinedDeviceModelCodeTest.java new file mode 100644 index 00000000000..96114303a1f --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/domain/valueobjects/CombinedDeviceModelCodeTest.java @@ -0,0 +1,86 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.adapter.protocol.dlms.domain.valueobjects; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.mockito.junit.jupiter.MockitoExtension; +import org.opensmartgridplatform.adapter.protocol.dlms.domain.valueobjects.CombinedDeviceModelCode.CombinedDeviceModelCodeBuilder; + +@ExtendWith(MockitoExtension.class) +class CombinedDeviceModelCodeTest { + private static final String GATEWAYCODE = "gwcode"; + private static final String CH1_DEVICE_MODEL_CODE = "ch1DeviceModelCode"; + private static final String CH2_DEVICE_MODEL_CODE = "ch2DeviceModelCode"; + private static final String CH3_DEVICE_MODEL_CODE = "ch3DeviceModelCode"; + private static final String CH4_DEVICE_MODEL_CODE = "ch4DeviceModelCode"; + + private static final String DEVICE_MODEL_CODE_STRING = + String.format( + "%s,%s,%s,%s,%s", + GATEWAYCODE, + CH1_DEVICE_MODEL_CODE, + CH2_DEVICE_MODEL_CODE, + CH3_DEVICE_MODEL_CODE, + CH4_DEVICE_MODEL_CODE); + + @Test + void parseShouldSucceed() { + + final CombinedDeviceModelCode combinedDeviceModelCode = + CombinedDeviceModelCode.parse(DEVICE_MODEL_CODE_STRING); + + assertEquals(GATEWAYCODE, combinedDeviceModelCode.getGatewayDeviceModelCode()); + assertEquals(CH1_DEVICE_MODEL_CODE, combinedDeviceModelCode.getCodeFromChannel(1)); + assertEquals(CH2_DEVICE_MODEL_CODE, combinedDeviceModelCode.getCodeFromChannel(2)); + assertEquals(CH3_DEVICE_MODEL_CODE, combinedDeviceModelCode.getCodeFromChannel(3)); + assertEquals(CH4_DEVICE_MODEL_CODE, combinedDeviceModelCode.getCodeFromChannel(4)); + } + + @Test + void parseShouldGetEmptyResponse() { + + final CombinedDeviceModelCode combinedDeviceModelCode = CombinedDeviceModelCode.parse(",,,,"); + + assertNull(combinedDeviceModelCode.getGatewayDeviceModelCode()); + assertNull(combinedDeviceModelCode.getCodeFromChannel(1)); + assertNull(combinedDeviceModelCode.getCodeFromChannel(2)); + assertNull(combinedDeviceModelCode.getCodeFromChannel(3)); + assertNull(combinedDeviceModelCode.getCodeFromChannel(4)); + } + + @ParameterizedTest + @CsvSource( + value = {"invalid", ",", ",,", ",,,", ",,,,", ",,,,,"}, + delimiterString = ";") + void parseShouldReturnEmptyCombinedDeviceModelCode(final String noCombinedDeviceModelCode) { + final CombinedDeviceModelCode combinedDeviceModelCode = + CombinedDeviceModelCode.parse(noCombinedDeviceModelCode); + + assertNull(combinedDeviceModelCode.getGatewayDeviceModelCode()); + assertNull(combinedDeviceModelCode.getCodeFromChannel(1)); + assertNull(combinedDeviceModelCode.getCodeFromChannel(2)); + assertNull(combinedDeviceModelCode.getCodeFromChannel(3)); + assertNull(combinedDeviceModelCode.getCodeFromChannel(4)); + } + + @Test + void builderShouldSucceed() { + final CombinedDeviceModelCode deviceModelCode = + new CombinedDeviceModelCodeBuilder() + .gatewayDeviceModelCode(GATEWAYCODE) + .channelBasedDeviceModelCode(1, CH1_DEVICE_MODEL_CODE) + .channelBasedDeviceModelCode(2, CH2_DEVICE_MODEL_CODE) + .channelBasedDeviceModelCode(3, CH3_DEVICE_MODEL_CODE) + .channelBasedDeviceModelCode(4, CH4_DEVICE_MODEL_CODE) + .build(); + + assertEquals(DEVICE_MODEL_CODE_STRING, deviceModelCode.toString()); + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/DeviceRequestMessageListenerIT.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/DeviceRequestMessageListenerIT.java index cabf6e93e68..eba0d9e801c 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/DeviceRequestMessageListenerIT.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/DeviceRequestMessageListenerIT.java @@ -27,11 +27,13 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit.jupiter.SpringExtension; /** Tests the incoming JMS messages and processors. Verifies that response messages were sent. */ @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = MessagingTestConfiguration.class) +@TestPropertySource(properties = {"throttling.max.new.connection.requests=200"}) class DeviceRequestMessageListenerIT { private static final Logger LOGGER = diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/MessagingTestConfiguration.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/MessagingTestConfiguration.java index 9da196deb7d..2e01dcc0aaa 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/MessagingTestConfiguration.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/MessagingTestConfiguration.java @@ -11,14 +11,13 @@ import org.apache.activemq.command.ActiveMQDestination; import org.mockito.Mockito; import org.opensmartgridplatform.adapter.protocol.dlms.application.config.DevicePingConfig; -import org.opensmartgridplatform.adapter.protocol.dlms.application.config.ThrottlingClientConfig; +import org.opensmartgridplatform.adapter.protocol.dlms.application.config.ThrottlingConfig; import org.opensmartgridplatform.adapter.protocol.dlms.application.config.messaging.OutboundLogItemRequestsMessagingConfig; import org.opensmartgridplatform.adapter.protocol.dlms.application.config.messaging.OutboundOsgpCoreResponsesMessagingConfig; import org.opensmartgridplatform.adapter.protocol.dlms.application.services.DomainHelperService; import org.opensmartgridplatform.adapter.protocol.dlms.application.services.MonitoringService; import org.opensmartgridplatform.adapter.protocol.dlms.application.services.SecretManagementService; import org.opensmartgridplatform.adapter.protocol.dlms.application.services.SystemEventService; -import org.opensmartgridplatform.adapter.protocol.dlms.application.services.ThrottlingService; import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.utils.DlmsHelper; import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionFactory; import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionHelper; @@ -29,9 +28,11 @@ import org.opensmartgridplatform.adapter.protocol.dlms.infra.messaging.requests.to.core.OsgpRequestMessageSender; import org.opensmartgridplatform.shared.application.config.AbstractConfig; import org.opensmartgridplatform.shared.application.config.messaging.DefaultJmsConfiguration; +import org.opensmartgridplatform.shared.application.config.messaging.JmsBrokerType; import org.opensmartgridplatform.shared.domain.services.CorrelationIdProviderService; import org.opensmartgridplatform.shared.domain.services.CorrelationIdProviderUUIDService; import org.opensmartgridplatform.shared.infra.jms.BaseMessageProcessorMap; +import org.opensmartgridplatform.shared.infra.jms.JmsMessageCreator; import org.opensmartgridplatform.shared.infra.jms.MessageProcessorMap; import org.opensmartgridplatform.shared.infra.networking.ping.Pinger; import org.springframework.context.annotation.Bean; @@ -51,7 +52,6 @@ /** Test Configuration for JMS Listener triggered tests. */ @Configuration @ComponentScan( - basePackages = {}, excludeFilters = @ComponentScan.Filter( type = FilterType.CUSTOM, @@ -73,6 +73,11 @@ public DefaultJmsConfiguration defaultJmsConfiguration() { return new DefaultJmsConfiguration(); } + @Bean + public JmsMessageCreator jmsMessageCreator() { + return new JmsMessageCreator(JmsBrokerType.ACTIVE_MQ); + } + @Bean("protocolDlmsInboundOsgpCoreRequestsMessageListener") public DeviceRequestMessageListener deviceRequestMessageListener() { return new DeviceRequestMessageListener(); @@ -187,13 +192,8 @@ public OsgpExceptionConverter osgpExceptionConverter() { } @Bean - public ThrottlingService throttlingService() { - return new ThrottlingService(); - } - - @Bean - public ThrottlingClientConfig throttlingClientConfig() { - return new ThrottlingClientConfig(); + public ThrottlingConfig throttlingConfig() { + return new ThrottlingConfig(); } @Bean diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/BundleMessageProcessorTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/BundleMessageProcessorTest.java index 3a79f06d461..30d2ee9277e 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/BundleMessageProcessorTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/BundleMessageProcessorTest.java @@ -22,10 +22,9 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import org.opensmartgridplatform.adapter.protocol.dlms.application.config.ThrottlingClientConfig; import org.opensmartgridplatform.adapter.protocol.dlms.application.services.BundleService; import org.opensmartgridplatform.adapter.protocol.dlms.application.services.DomainHelperService; -import org.opensmartgridplatform.adapter.protocol.dlms.application.services.ThrottlingService; +import org.opensmartgridplatform.adapter.protocol.dlms.application.throttling.ThrottlingService; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDevice; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDeviceBuilder; import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionHelper; @@ -66,8 +65,6 @@ class BundleMessageProcessorTest { @Mock private DlmsMessageListener messageListener; - @Mock private ThrottlingClientConfig throttlingClientConfig; - private DlmsDevice dlmsDevice; private MessageMetadata messageMetadata; @@ -77,7 +74,6 @@ class BundleMessageProcessorTest { void setUp() throws OsgpException, JMSException { this.dlmsDevice = new DlmsDeviceBuilder().withHls5Active(true).build(); this.messageMetadata = MessageMetadata.fromMessage(this.message); - when(this.throttlingClientConfig.clientEnabled()).thenReturn(false); } @Test diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/UpdateFirmwareRequestMessageProcessorTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/UpdateFirmwareRequestMessageProcessorTest.java index 5b648f526cf..ae1e335add5 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/UpdateFirmwareRequestMessageProcessorTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/processors/UpdateFirmwareRequestMessageProcessorTest.java @@ -4,6 +4,7 @@ package org.opensmartgridplatform.adapter.protocol.dlms.infra.messaging.processors; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.ArgumentMatchers.same; @@ -19,6 +20,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; @@ -28,7 +31,7 @@ import org.opensmartgridplatform.adapter.protocol.dlms.application.services.ConfigurationService; import org.opensmartgridplatform.adapter.protocol.dlms.application.services.DomainHelperService; import org.opensmartgridplatform.adapter.protocol.dlms.application.services.FirmwareService; -import org.opensmartgridplatform.adapter.protocol.dlms.application.services.ThrottlingService; +import org.opensmartgridplatform.adapter.protocol.dlms.application.throttling.ThrottlingService; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDevice; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDeviceBuilder; import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionHelper; @@ -109,8 +112,7 @@ void processMessageTaskShouldSendFirmwareFileRequestWhenFirmwareFileNotAvailable when(this.firmwareService.isFirmwareFileAvailable(firmwareIdentification)).thenReturn(false); // Act - this.processor.processMessageTasks( - message.getObject(), messageMetadata, this.dlmsConnectionManagerMock, this.device); + this.processor.processMessageTasks(message.getObject(), messageMetadata, null, this.device); // Assert verify(this.osgpRequestMessageSender, times(1)) @@ -201,4 +203,38 @@ void processMessageTaskShouldNotUpdateFirmwareWhenFirmwareFileNotAvailable() same(updateFirmwareRequestDto), any(MessageMetadata.class)); } + + @ParameterizedTest + @ValueSource(booleans = {true, false}) + void testUsesDeviceConnection(final boolean isFirmwareFileAvailable) { + final String firmwareIdentification = "unavailable"; + final String deviceIdentification = "unavailableEither"; + final UpdateFirmwareRequestDto updateFirmwareRequestDto = + new UpdateFirmwareRequestDto(firmwareIdentification, deviceIdentification); + + when(this.firmwareService.isFirmwareFileAvailable(firmwareIdentification)) + .thenReturn(isFirmwareFileAvailable); + + assertThat(this.processor.usesDeviceConnection(updateFirmwareRequestDto)) + .isEqualTo(isFirmwareFileAvailable); + } + + @ParameterizedTest + @ValueSource(booleans = {true, false}) + void testProcessMessage(final boolean isFirmwareFileAvailable) throws JMSException { + final String firmwareIdentification = "unavailable"; + final String deviceIdentification = "unavailableEither"; + final UpdateFirmwareRequestDto updateFirmwareRequestDto = + new UpdateFirmwareRequestDto(firmwareIdentification, deviceIdentification); + final ObjectMessage message = + new ObjectMessageBuilder() + .withObject(updateFirmwareRequestDto) + .withCorrelationUid("123456") + .build(); + + when(this.firmwareService.isFirmwareFileAvailable(firmwareIdentification)) + .thenReturn(isFirmwareFileAvailable); + + this.processor.processMessage(message); + } } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/responses/from/core/processors/GetFirmwareFileResponseMessageProcessorTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/responses/from/core/processors/GetFirmwareFileResponseMessageProcessorTest.java index 9675ba7ae55..f87e47390a3 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/responses/from/core/processors/GetFirmwareFileResponseMessageProcessorTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/messaging/responses/from/core/processors/GetFirmwareFileResponseMessageProcessorTest.java @@ -28,7 +28,7 @@ import org.opensmartgridplatform.adapter.protocol.dlms.application.config.ThrottlingClientConfig; import org.opensmartgridplatform.adapter.protocol.dlms.application.services.DomainHelperService; import org.opensmartgridplatform.adapter.protocol.dlms.application.services.FirmwareService; -import org.opensmartgridplatform.adapter.protocol.dlms.application.services.ThrottlingService; +import org.opensmartgridplatform.adapter.protocol.dlms.application.throttling.ThrottlingService; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDevice; import org.opensmartgridplatform.adapter.protocol.dlms.domain.entities.DlmsDeviceBuilder; import org.opensmartgridplatform.adapter.protocol.dlms.domain.factories.DlmsConnectionHelper; diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/AlarmDecoderTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/AlarmDecoderTest.java index 7cb7a3c266d..e46d7024765 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/AlarmDecoderTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/AlarmDecoderTest.java @@ -25,14 +25,12 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.junit.jupiter.MockitoExtension; -import org.opensmartgridplatform.adapter.protocol.dlms.domain.commands.dlmsobjectconfig.DlmsObjectType; import org.opensmartgridplatform.dlms.DlmsPushNotification; +import org.opensmartgridplatform.dlms.objectconfig.DlmsObjectType; @ExtendWith(MockitoExtension.class) class AlarmDecoderTest { - static final int NUMBER_OF_BYTES_FOR_ALARM = 4; - private final AlarmDecoder decoder = new AlarmDecoder(); @Test diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/DlmsChannelHandlerServerTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/DlmsChannelHandlerServerTest.java new file mode 100644 index 00000000000..744d14fb3b3 --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/DlmsChannelHandlerServerTest.java @@ -0,0 +1,98 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.adapter.protocol.dlms.infra.networking; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.when; + +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import java.net.InetSocketAddress; +import java.util.HashSet; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.opensmartgridplatform.dlms.DlmsPushNotification; + +@ExtendWith(MockitoExtension.class) +class DlmsChannelHandlerServerTest { + + @Mock private PushedMessageProcessor pushedMessageProcessor; + + @InjectMocks private DlmsChannelHandlerServer dlmsChannelHandlerServer; + + @Test + void testChannelRead0() { + final String equipmentIdentifier = "123"; + final String ipAddress = "127.0.0.1"; + final ChannelHandlerContext ctx = this.newChannelHandlerContextMock(ipAddress); + final DlmsPushNotification message = + new DlmsPushNotification("bytes".getBytes(), equipmentIdentifier, "", new HashSet<>()); + + this.dlmsChannelHandlerServer.channelRead0(ctx, message); + + verify(this.pushedMessageProcessor) + .process(eq(message), any(String.class), eq(equipmentIdentifier), eq(ipAddress)); + } + + @Test + void testChannelRead0EmptyEqId() { + final String equipmentIdentifier = ""; + final String ipAddress = "127.0.0.1"; + final ChannelHandlerContext ctx = this.newChannelHandlerContextMock(ipAddress); + final DlmsPushNotification message = + new DlmsPushNotification("bytes".getBytes(), equipmentIdentifier, "", new HashSet<>()); + + this.dlmsChannelHandlerServer.channelRead0(ctx, message); + + verifyNoInteractions(this.pushedMessageProcessor); + } + + @Test + void testChannelRead0EqIdNull() { + final String equipmentIdentifier = null; + final String ipAddress = "127.0.0.1"; + final ChannelHandlerContext ctx = this.newChannelHandlerContextMock(ipAddress); + final DlmsPushNotification message = + new DlmsPushNotification("bytes".getBytes(), equipmentIdentifier, "", new HashSet<>()); + + this.dlmsChannelHandlerServer.channelRead0(ctx, message); + + verifyNoInteractions(this.pushedMessageProcessor); + } + + @Test + void testChannelRead0ExceptionIpAddress() { + final String equipmentIdentifier = "123"; + final String ipAddress = null; + + final ChannelHandlerContext ctx = mock(ChannelHandlerContext.class); + when(ctx.channel()).thenThrow(new RuntimeException()); + + final DlmsPushNotification message = + new DlmsPushNotification("bytes".getBytes(), equipmentIdentifier, "", new HashSet<>()); + + this.dlmsChannelHandlerServer.channelRead0(ctx, message); + + verify(this.pushedMessageProcessor) + .process(eq(message), any(String.class), eq(equipmentIdentifier), eq(ipAddress)); + } + + private ChannelHandlerContext newChannelHandlerContextMock(final String ipAddress) { + final ChannelHandlerContext ctx = mock(ChannelHandlerContext.class); + final Channel channel = mock(Channel.class); + final InetSocketAddress socketAddress = mock(InetSocketAddress.class); + when(ctx.channel()).thenReturn(channel); + when(channel.remoteAddress()).thenReturn(socketAddress); + when(socketAddress.getHostString()).thenReturn(ipAddress); + return ctx; + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/DlmsPushNotificationDecoderTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/DlmsPushNotificationReplayingDecoderTest.java similarity index 86% rename from osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/DlmsPushNotificationDecoderTest.java rename to osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/DlmsPushNotificationReplayingDecoderTest.java index a697ee0c451..7ed61402f1e 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/DlmsPushNotificationDecoderTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/DlmsPushNotificationReplayingDecoderTest.java @@ -5,12 +5,9 @@ package org.opensmartgridplatform.adapter.protocol.dlms.infra.networking; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import java.io.IOException; import java.util.ArrayList; @@ -27,7 +24,7 @@ import org.opensmartgridplatform.dto.valueobjects.smartmetering.AlarmTypeDto; @ExtendWith(MockitoExtension.class) -class DlmsPushNotificationDecoderTest { +class DlmsPushNotificationReplayingDecoderTest { private static final String IDENTIFIER = "EXXXX123456789012"; @@ -49,13 +46,13 @@ class DlmsPushNotificationDecoderTest { private static final int PUSH_SETUP_TCP_BIT = 1; - private DlmsPushNotificationDecoder decoder; + private DlmsPushNotificationReplayingDecoder decoder; @Mock private ChannelHandlerContext ctx; @BeforeEach void setUp() { - this.decoder = new DlmsPushNotificationDecoder(); + this.decoder = new DlmsPushNotificationReplayingDecoder(); } @Test @@ -92,6 +89,18 @@ void testDecodeSmr5() throws UnrecognizedMessageDataException, IOException { Collections.singleton(AlarmTypeDto.CLOCK_INVALID)); } + @Test + void testDecodeSmr5_sms_wakeup() throws UnrecognizedMessageDataException, IOException { + final List out = new ArrayList<>(); + final ByteBuf byteBuf = + this.newByteBuf(AlarmGeneratorUtil.smr5Alarm(IDENTIFIER, 2, Collections.EMPTY_LIST)); + this.decoder.decode(this.ctx, byteBuf, out); + + assertThat(out).hasSize(1); + this.assertPushNotification( + (DlmsPushNotification) out.get(0), IDENTIFIER, PUSH_SMS_TRIGGER, Set.of()); + } + @Test void decodeDsmr4AlarmsWithLogicalNames() throws UnrecognizedMessageDataException, IOException { @@ -119,17 +128,7 @@ private void decodeDsmr4AlarmsWithLogicalName( } private ByteBuf newByteBuf(final byte[] byteArray) { - final ByteBuf byteBuf = mock(ByteBuf.class); - when(byteBuf.readableBytes()).thenReturn(byteArray.length); - doAnswer( - invocation -> { - final byte[] outputValue = (byte[]) invocation.getArguments()[0]; - System.arraycopy(byteArray, 0, outputValue, 0, byteArray.length); - return null; - }) - .when(byteBuf) - .readBytes(any(byte[].class)); - return byteBuf; + return Unpooled.copiedBuffer(byteArray); } private void assertPushNotification( diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/Mx382AlarmDecoderTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/Mx382AlarmDecoderTest.java index ffb128a1360..3215a2d3d1a 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/Mx382AlarmDecoderTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/Mx382AlarmDecoderTest.java @@ -6,11 +6,16 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.ThrowableAssert.catchThrowable; +import static org.junit.jupiter.api.Assertions.assertThrows; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.nio.ByteBuffer; +import javax.xml.bind.DatatypeConverter; +import lombok.Builder; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import org.opensmartgridplatform.dlms.DlmsPushNotification; import org.opensmartgridplatform.dto.valueobjects.smartmetering.AlarmTypeDto; @@ -22,16 +27,58 @@ class Mx382AlarmDecoderTest { private final byte preconfiguredClient = 0x66; private final byte apduType = (byte) 0xC2; + @ParameterizedTest + @ValueSource(strings = {"KA6P005039021110", "KAL70005088116712"}) + void decodeWithoutDate(final String deviceIdentification) + throws UnrecognizedMessageDataException { + + final byte[] mx382message = + Mx382AlarmMessage.builder() + .equipmentIdentifier(deviceIdentification) + .obiscode(this.obiscode) + .client(this.preconfiguredClient) + .apduType(this.apduType) + .build() + .encode(); + final Mx382AlarmDecoder decoder = new Mx382AlarmDecoder(); + final InputStream is = new ByteArrayInputStream(mx382message); + final DlmsPushNotification dlmsPushNotification = + decoder.decodeMx382alarm(is, ConnectionProtocol.TCP); + assertThat(dlmsPushNotification.getAlarms()).hasSize(1); + assertThat(dlmsPushNotification.getAlarms().iterator().next()) + .isEqualTo(AlarmTypeDto.LAST_GASP); + assertThat(dlmsPushNotification.getTriggerType()).isEqualTo(AlarmDecoder.PUSH_ALARM_TRIGGER); + assertThat(dlmsPushNotification.getEquipmentIdentifier()).isEqualTo(deviceIdentification); + } + + /* + * Decode with an alarm message that contains a date time stamp, this has an alternative length within the WDPU header (2a on index 7, 8th byte). + * Build an alarm message with an exact message from the log with spaces removed. + * +----------------------------------------------------------|----------------+ + * | | 0 1 2 3 4 5 6 7 8 9 a b c d e f | | + * +--------+-------------------------------------------------+----------------+ + * |00000000| 00 01 00 67 00 66 00 2a c2 09 0c 07 e7 07 06 04 |...g.f.*........| + * |00000010| 0a 36 26 00 ff 88 80 00 01 80 80 80 80 80 00 02 |.6&.............| + * |00000020| 09 10 4b 41 36 50 30 30 35 30 33 39 30 32 31 31 |..KA6P0050390211| + * |00000030| 31 30 |10 | + * +--------+-------------------------------------------------+----------------+ + */ + @Test - void testDecode() throws UnrecognizedMessageDataException { + void decodeWithDateTimeShouldPass() throws UnrecognizedMessageDataException { + final String message = + "000100670066002ac2090c07e70706040a362600ff888000018080808080000209104b413650303035303339303231313130"; final byte[] mx382message = - new Mx382AlarmMessage( - this.equipmentIdentifier, this.obiscode, this.preconfiguredClient, this.apduType) + Mx382AlarmMessage.builder() // + .message(message) + .build() .encode(); + final Mx382AlarmDecoder decoder = new Mx382AlarmDecoder(); final InputStream is = new ByteArrayInputStream(mx382message); - final DlmsPushNotification dlmsPushNotification = decoder.decodeMx382alarm(is); + final DlmsPushNotification dlmsPushNotification = + decoder.decodeMx382alarm(is, ConnectionProtocol.TCP); assertThat(dlmsPushNotification.getAlarms()).hasSize(1); assertThat(dlmsPushNotification.getAlarms().iterator().next()) .isEqualTo(AlarmTypeDto.LAST_GASP); @@ -39,16 +86,64 @@ void testDecode() throws UnrecognizedMessageDataException { assertThat(dlmsPushNotification.getEquipmentIdentifier()).isEqualTo(this.equipmentIdentifier); } + @Test + void decodeWakeupAlarm() throws UnrecognizedMessageDataException { + final String deviceIdentification = "KAL7005088116712"; + final String message = + "000100670066002ac2090c07e70a19030b122900ff888000010000600101ff0209104b414c37303035303838313136373132"; + + final byte[] mx382message = + Mx382AlarmMessage.builder() // + .message(message) + .build() + .encode(); + + final Mx382AlarmDecoder decoder = new Mx382AlarmDecoder(); + final InputStream is = new ByteArrayInputStream(mx382message); + final DlmsPushNotification dlmsPushNotification = + decoder.decodeMx382alarm(is, ConnectionProtocol.UDP); + assertThat(dlmsPushNotification.getAlarms()).isEmpty(); + assertThat(dlmsPushNotification.getTriggerType()).isEqualTo(AlarmDecoder.PUSH_SMS_TRIGGER); + assertThat(dlmsPushNotification.getEquipmentIdentifier()).isEqualTo(deviceIdentification); + } + + @Test + void invalidDeviceIdentificationLength() throws UnrecognizedMessageDataException { + final String deviceIdentification = "KAL123"; + + final byte[] mx382message = + Mx382AlarmMessage.builder() + .equipmentIdentifier(deviceIdentification) + .obiscode(this.obiscode) + .client(this.preconfiguredClient) + .apduType(this.apduType) + .build() + .encode(); + final Mx382AlarmDecoder decoder = new Mx382AlarmDecoder(); + final InputStream is = new ByteArrayInputStream(mx382message); + final UnrecognizedMessageDataException exception = + assertThrows( + UnrecognizedMessageDataException.class, + () -> { + decoder.decodeMx382alarm(is, ConnectionProtocol.TCP); + }); + assertThat(exception.getMessage()) + .contains( + "Data in DLMS Push Notification cannot be decoded. Reason: Expected length value of 29,30,42 or 43, but found length of 19"); + } + @Test void testCheckOnObiscode() { + final byte[] incorrectObiscode = new byte[] {(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00}; final byte[] mx382message = - new Mx382AlarmMessage( - this.equipmentIdentifier, - incorrectObiscode, - this.preconfiguredClient, - this.apduType) + Mx382AlarmMessage.builder() + .equipmentIdentifier(this.equipmentIdentifier) + .obiscode(incorrectObiscode) + .client(this.preconfiguredClient) + .apduType(this.apduType) + .build() .encode(); assertDecodingException(mx382message); } @@ -57,7 +152,12 @@ void testCheckOnObiscode() { void testCheckOnHeader() { final byte[] mx382message = - new Mx382AlarmMessage(this.equipmentIdentifier, this.obiscode, (byte) 0x00, this.apduType) + Mx382AlarmMessage.builder() + .equipmentIdentifier(this.equipmentIdentifier) + .obiscode(this.obiscode) + .client((byte) 0x00) + .apduType(this.apduType) + .build() .encode(); assertDecodingException(mx382message); } @@ -66,8 +166,12 @@ void testCheckOnHeader() { void testCheckOnApduType() { final byte[] mx382message = - new Mx382AlarmMessage( - this.equipmentIdentifier, this.obiscode, this.preconfiguredClient, (byte) 0x10) + Mx382AlarmMessage.builder() + .equipmentIdentifier(this.equipmentIdentifier) + .obiscode(this.obiscode) + .client(this.preconfiguredClient) + .apduType((byte) 0x10) + .build() .encode(); assertDecodingException(mx382message); } @@ -76,29 +180,41 @@ private static void assertDecodingException(final byte[] mx382message) { final Mx382AlarmDecoder decoder = new Mx382AlarmDecoder(); final InputStream is = new ByteArrayInputStream(mx382message); - final Throwable actual = catchThrowable(() -> decoder.decodeMx382alarm(is)); + final Throwable actual = + catchThrowable(() -> decoder.decodeMx382alarm(is, ConnectionProtocol.TCP)); assertThat(actual).isInstanceOf(UnrecognizedMessageDataException.class); } + @Builder public static final class Mx382AlarmMessage { + + public static final int DATA_TYPE_NULL_DATA = 0x00; + private final String equipmentIdentifier; private final byte[] obiscode; private final byte client; private final byte apduType; - public Mx382AlarmMessage( + private final String message; + + protected Mx382AlarmMessage( final String equipmentIdentifier, final byte[] obiscode, final byte client, - final byte apduType) { + final byte apduType, + final String message) { this.equipmentIdentifier = equipmentIdentifier; this.obiscode = obiscode; this.client = client; this.apduType = apduType; + this.message = message; } public byte[] encode() { + if (this.message != null) { + return DatatypeConverter.parseHexBinary(this.message); + } final byte[] apdu = this.createApdu(); final byte[] header = this.createWpduHeader(apdu.length); final byte[] wnm = new byte[header.length + apdu.length]; @@ -110,13 +226,15 @@ public byte[] encode() { private byte[] createApdu() { final ByteBuffer buf = ByteBuffer.allocate(64); buf.put(this.apduType); - buf.put((byte) 0x00); + buf.put((byte) DATA_TYPE_NULL_DATA); - final byte[] classId = new byte[] {0x00, 0x01}; + final byte[] classId = Mx382AlarmDecoder.CLASS_ID_1; buf.put(classId); buf.put(this.obiscode); - final byte attribute = 0x02; + final byte attribute = Mx382AlarmDecoder.ATTRIBUTE_ID_2; buf.put((byte) attribute); + buf.put((byte) Mx382AlarmDecoder.DATA_TYPE_OCTET_STRING); + buf.put((byte) this.equipmentIdentifier.getBytes().length); buf.put(this.equipmentIdentifier.getBytes()); buf.flip(); final byte[] bytes = new byte[buf.limit()]; diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/PushedMessageProcessorTest.java b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/PushedMessageProcessorTest.java index a770996937a..8699b269631 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/PushedMessageProcessorTest.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-adapter-dlms/src/test/java/org/opensmartgridplatform/adapter/protocol/dlms/infra/networking/PushedMessageProcessorTest.java @@ -7,6 +7,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; @@ -15,17 +16,21 @@ import java.util.Set; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.opensmartgridplatform.adapter.protocol.dlms.infra.messaging.DlmsLogItemRequestMessage; import org.opensmartgridplatform.adapter.protocol.dlms.infra.messaging.DlmsLogItemRequestMessageSender; import org.opensmartgridplatform.adapter.protocol.dlms.infra.messaging.requests.to.core.OsgpRequestMessageSender; +import org.opensmartgridplatform.adapter.protocol.jasper.service.DeviceSessionService; import org.opensmartgridplatform.dlms.DlmsPushNotification; import org.opensmartgridplatform.dto.valueobjects.smartmetering.AlarmTypeDto; import org.opensmartgridplatform.shared.infra.jms.MessageMetadata; import org.opensmartgridplatform.shared.infra.jms.MessageType; import org.opensmartgridplatform.shared.infra.jms.RequestMessage; +import org.springframework.test.util.ReflectionTestUtils; @ExtendWith(MockitoExtension.class) class PushedMessageProcessorTest { @@ -40,6 +45,7 @@ class PushedMessageProcessorTest { @Mock private OsgpRequestMessageSender osgpRequestMessageSender; @Mock private DlmsLogItemRequestMessageSender dlmsLogItemRequestMessageSender; + @Mock private DeviceSessionService deviceSessionService; @InjectMocks private PushedMessageProcessor processor; @Test @@ -48,10 +54,11 @@ void testProcessNoAction() throws IOException { final DlmsPushNotification message = this.newDlmsPushNotification(bytes, IDENTIFIER, PUSH_CSD_TRIGGER, Collections.emptySet()); - this.processor.process(message, IDENTIFIER, CORRELATION_UID, IP_ADDRESS); + this.processor.process(message, CORRELATION_UID, IDENTIFIER, IP_ADDRESS); verifyNoInteractions(this.osgpRequestMessageSender); verifyNoInteractions(this.dlmsLogItemRequestMessageSender); + verifyNoInteractions(this.deviceSessionService); } @Test @@ -60,7 +67,7 @@ void testProcessAlarm() throws IOException { final DlmsPushNotification message = this.newDlmsPushNotification(bytes, IDENTIFIER, PUSH_ALARM_TRIGGER, Collections.emptySet()); - this.processor.process(message, IDENTIFIER, CORRELATION_UID, IP_ADDRESS); + this.processor.process(message, CORRELATION_UID, IDENTIFIER, IP_ADDRESS); verify(this.osgpRequestMessageSender) .send( @@ -68,19 +75,25 @@ void testProcessAlarm() throws IOException { eq(MessageType.PUSH_NOTIFICATION_ALARM.name()), any(MessageMetadata.class)); verify(this.dlmsLogItemRequestMessageSender).send(any(DlmsLogItemRequestMessage.class)); + verifyNoInteractions(this.deviceSessionService); } - @Test - void testProcessSms() throws IOException { + @ParameterizedTest + @ValueSource(booleans = {true, false}) + void testProcessSms(final boolean pushWakeupAlarmToCore) throws IOException { + ReflectionTestUtils.setField( + this.processor, "pushWakeupAlarmToCore", pushWakeupAlarmToCore, boolean.class); + final byte[] bytes = AlarmGeneratorUtil.smr5Alarm(IDENTIFIER, 1, Collections.emptyList()); final DlmsPushNotification message = this.newDlmsPushNotification(bytes, IDENTIFIER, PUSH_SMS_TRIGGER, Collections.emptySet()); - this.processor.process(message, IDENTIFIER, CORRELATION_UID, IP_ADDRESS); + this.processor.process(message, CORRELATION_UID, IDENTIFIER, IP_ADDRESS); - verify(this.osgpRequestMessageSender) + verify(this.osgpRequestMessageSender, times(pushWakeupAlarmToCore ? 1 : 0)) .send(any(RequestMessage.class), eq(MessageType.PUSH_NOTIFICATION_SMS.name()), isNull()); verify(this.dlmsLogItemRequestMessageSender).send(any(DlmsLogItemRequestMessage.class)); + verify(this.deviceSessionService).notifyIpAddress(IDENTIFIER, IP_ADDRESS); } private DlmsPushNotification newDlmsPushNotification( diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/osgp-simulator-dlms-triggered/pom.xml b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/osgp-simulator-dlms-triggered/pom.xml index a50b774b6c2..b8dfd5eb407 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/osgp-simulator-dlms-triggered/pom.xml +++ b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/osgp-simulator-dlms-triggered/pom.xml @@ -15,7 +15,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform osgp-protocol-simulator-dlms - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/pom.xml b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/pom.xml index abecff2e31a..295a54961ba 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/pom.xml +++ b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/pom.xml @@ -16,14 +16,14 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform super-osgp - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../../../super/pom.xml ${project.version}-${BUILD_TAG} - 4.1 - 2.7.2 + 4.4 + 2.7.18 true diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator-starter/pom.xml b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator-starter/pom.xml index 446ef65d630..d2d23aa1ac4 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator-starter/pom.xml +++ b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator-starter/pom.xml @@ -18,7 +18,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform osgp-protocol-simulator-dlms - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../../../osgp-protocol-simulator-dlms/pom.xml diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/pom.xml b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/pom.xml index 568cf6edebc..7ca78cc22a3 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/pom.xml +++ b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/pom.xml @@ -16,7 +16,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform osgp-protocol-simulator-dlms - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../../../osgp-protocol-simulator-dlms/pom.xml @@ -40,6 +40,12 @@ SPDX-License-Identifier: Apache-2.0 org.springframework.ws spring-ws-security + + + org.bouncycastle + bcprov-jdk15on + + com.fasterxml.jackson.jaxrs diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/cosem/DefinableLoadProfile.java b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/cosem/DefinableLoadProfile.java index 2ff54759968..7ce6388f6ad 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/cosem/DefinableLoadProfile.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/cosem/DefinableLoadProfile.java @@ -4,15 +4,10 @@ package org.opensmartgridplatform.simulator.protocol.dlms.cosem; -import java.util.ArrayList; -import java.util.Arrays; import java.util.Calendar; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Random; -import org.apache.commons.collections4.queue.CircularFifoQueue; -import org.openmuc.jdlms.AccessResultCode; import org.openmuc.jdlms.AttributeAccessMode; import org.openmuc.jdlms.CosemAttribute; import org.openmuc.jdlms.CosemClass; @@ -23,308 +18,370 @@ import org.opensmartgridplatform.dlms.interfaceclass.InterfaceClass; import org.opensmartgridplatform.dlms.interfaceclass.attribute.ClockAttribute; import org.opensmartgridplatform.dlms.interfaceclass.attribute.DataAttribute; -import org.opensmartgridplatform.dlms.interfaceclass.attribute.ProfileGenericAttribute; +import org.opensmartgridplatform.dlms.interfaceclass.attribute.GsmDiagnosticAttribute; +import org.opensmartgridplatform.dlms.interfaceclass.attribute.MbusClientAttribute; +import org.opensmartgridplatform.dlms.interfaceclass.attribute.MbusDiagnosticAttribute; import org.opensmartgridplatform.dlms.interfaceclass.attribute.RegisterAttribute; -import org.opensmartgridplatform.simulator.protocol.dlms.cosem.processing.CaptureObjectDefinition; -import org.opensmartgridplatform.simulator.protocol.dlms.cosem.processing.CaptureObjectDefinitionCollection; -import org.opensmartgridplatform.simulator.protocol.dlms.cosem.processing.CosemDateTimeProcessor; import org.opensmartgridplatform.simulator.protocol.dlms.cosem.processing.DataProcessor; -import org.opensmartgridplatform.simulator.protocol.dlms.cosem.processing.Integer32DataProcessor; -import org.opensmartgridplatform.simulator.protocol.dlms.cosem.processing.UInteger16DataProcessor; -import org.opensmartgridplatform.simulator.protocol.dlms.cosem.processing.UInteger32DataProcessor; import org.opensmartgridplatform.simulator.protocol.dlms.util.DynamicValues; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; @CosemClass(id = 7) -public class DefinableLoadProfile extends ProfileGeneric { - private static final Logger LOGGER = LoggerFactory.getLogger(DefinableLoadProfile.class); - - private static final int MAX_CAPTURE_OBJECTS = 20; - private static final int MAX_PROFILE_ENTRIES = 960; - - private static final DataProcessor COSEM_DATE_TIME_PROCESSOR = new CosemDateTimeProcessor(); - private static final DataProcessor LONG_UNSIGNED_PROCESSOR = new UInteger16DataProcessor(); - private static final DataProcessor DOUBLE_LONG_PROCESSOR = new Integer32DataProcessor(); - private static final DataProcessor DOUBLE_LONG_UNSIGNED_PROCESSOR = new UInteger32DataProcessor(); +public class DefinableLoadProfile extends DynamicProfile { + private static final String LOGICAL_NAME_DEFINABLE_LOAD_PROFILE = "0.1.94.31.6.255"; private static final Map PROCESSORS_BY_CAPTURE_OBJECT = new HashMap<>(); - private static final CaptureObject CLOCK_TIME = + public static final CaptureObject CLOCK_TIME = new CaptureObject( InterfaceClass.CLOCK.id(), "0.0.1.0.0.255", (byte) ClockAttribute.TIME.attributeId(), 0); - private static final CaptureObject NUMBER_OF_POWER_FAILURES_IN_ANY_PHASE_VALUE = + public static final CaptureObject CDMA_DIAGNOSTIC_SIGNAL_QUALITY = + new CaptureObject( + InterfaceClass.GSM_DIAGNOSTIC.id(), + "0.1.25.6.0.255", + (byte) GsmDiagnosticAttribute.CELL_INFO.attributeId(), + 3); + + public static final CaptureObject GPRS_DIAGNOSTIC_SIGNAL_QUALITY = + new CaptureObject( + InterfaceClass.GSM_DIAGNOSTIC.id(), + "0.0.25.6.0.255", + (byte) GsmDiagnosticAttribute.CELL_INFO.attributeId(), + 3); + + public static final CaptureObject CDMA_DIAGNOSTIC_BER = + new CaptureObject( + InterfaceClass.GSM_DIAGNOSTIC.id(), + "0.1.25.6.0.255", + (byte) GsmDiagnosticAttribute.CELL_INFO.attributeId(), + 4); + + public static final CaptureObject GPRS_DIAGNOSTIC_BER = + new CaptureObject( + InterfaceClass.GSM_DIAGNOSTIC.id(), + "0.0.25.6.0.255", + (byte) GsmDiagnosticAttribute.CELL_INFO.attributeId(), + 4); + + public static final CaptureObject MBUS_CLIENT_SETUP_CHN1_VALUE = + new CaptureObject( + InterfaceClass.MBUS_CLIENT.id(), + "0.1.24.1.0.255", + (byte) MbusClientAttribute.STATUS.attributeId(), + 0); + public static final CaptureObject MBUS_CLIENT_SETUP_CHN2_VALUE = + new CaptureObject( + InterfaceClass.MBUS_CLIENT.id(), + "0.2.24.1.0.255", + (byte) MbusClientAttribute.STATUS.attributeId(), + 0); + + public static final CaptureObject MBUS_DIAGNOSTIC_RSSI_CHN1_VALUE = + new CaptureObject( + InterfaceClass.MBUS_DIAGNOSTIC.id(), + "0.1.24.9.0.255", + (byte) MbusDiagnosticAttribute.RECEIVED_SIGNAL_STRENGTH.attributeId(), + 0); + public static final CaptureObject MBUS_DIAGNOSTIC_RSSI_CHN2_VALUE = + new CaptureObject( + InterfaceClass.MBUS_DIAGNOSTIC.id(), + "0.2.24.9.0.255", + (byte) MbusDiagnosticAttribute.RECEIVED_SIGNAL_STRENGTH.attributeId(), + 0); + public static final CaptureObject MBUS_DIAGNOSTIC_FCS_NOK_CHN1_VALUE = + new CaptureObject( + InterfaceClass.MBUS_DIAGNOSTIC.id(), + "0.1.24.9.0.255", + (byte) MbusDiagnosticAttribute.FCS_NOK_FRAMES_COUNTER.attributeId(), + 0); + public static final CaptureObject MBUS_DIAGNOSTIC_FCS_NOK_CHN2_VALUE = + new CaptureObject( + InterfaceClass.MBUS_DIAGNOSTIC.id(), + "0.2.24.9.0.255", + (byte) MbusDiagnosticAttribute.FCS_NOK_FRAMES_COUNTER.attributeId(), + 0); + public static final CaptureObject NUMBER_OF_POWER_FAILURES_IN_ANY_PHASE_VALUE = new CaptureObject( InterfaceClass.DATA.id(), "0.0.96.7.21.255", (byte) DataAttribute.VALUE.attributeId(), 0); - private static final CaptureObject NUMBER_OF_LONG_POWER_FAILURES_IN_ANY_PHASE_VALUE = + + public static final CaptureObject NUMBER_OF_LONG_POWER_FAILURES_IN_ANY_PHASE_VALUE = new CaptureObject( InterfaceClass.DATA.id(), "0.0.96.7.9.255", (byte) DataAttribute.VALUE.attributeId(), 0); - private static final CaptureObject TIME_THRESHOLD_FOR_LONG_POWER_FAILURE_VALUE = + public static final CaptureObject TIME_THRESHOLD_FOR_LONG_POWER_FAILURE_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "0.0.96.7.20.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject DURATION_OF_LONG_POWER_FAILURES_IN_ANY_PHASE_VALUE = + public static final CaptureObject DURATION_OF_LONG_POWER_FAILURES_IN_ANY_PHASE_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "0.0.96.7.19.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject INSTANTANEOUS_VOLTAGE_L1_VALUE = + public static final CaptureObject INSTANTANEOUS_VOLTAGE_L1_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.32.7.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject AVERAGE_VOLTAGE_L1_VALUE = + public static final CaptureObject AVERAGE_VOLTAGE_L1_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.32.24.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject INSTANTANEOUS_CURRENT_L1_VALUE = + public static final CaptureObject INSTANTANEOUS_CURRENT_L1_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.31.7.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject AVERAGE_ACTIVE_POWER_IMPORT_L1_VALUE = + public static final CaptureObject AVERAGE_ACTIVE_POWER_IMPORT_L1_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.21.24.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject AVERAGE_ACTIVE_POWER_EXPORT_L1_VALUE = + public static final CaptureObject AVERAGE_ACTIVE_POWER_EXPORT_L1_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.22.24.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject INSTANTANEOUS_ACTIVE_POWER_IMPORT_L1_VALUE = + public static final CaptureObject INSTANTANEOUS_ACTIVE_POWER_IMPORT_L1_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.21.7.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject INSTANTANEOUS_ACTIVE_POWER_EXPORT_L1_VALUE = + public static final CaptureObject INSTANTANEOUS_ACTIVE_POWER_EXPORT_L1_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.22.7.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject AVERAGE_REACTIVE_POWER_IMPORT_L1_VALUE = + public static final CaptureObject AVERAGE_REACTIVE_POWER_IMPORT_L1_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.23.24.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject AVERAGE_REACTIVE_POWER_EXPORT_L1_VALUE = + public static final CaptureObject AVERAGE_REACTIVE_POWER_EXPORT_L1_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.24.24.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject AVERAGE_CURRENT_L1_VALUE = + public static final CaptureObject AVERAGE_CURRENT_L1_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.31.24.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject INSTANTANEOUS_VOLTAGE_L2_VALUE = + public static final CaptureObject INSTANTANEOUS_VOLTAGE_L2_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.52.7.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject AVERAGE_VOLTAGE_L2_VALUE = + public static final CaptureObject AVERAGE_VOLTAGE_L2_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.52.24.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject INSTANTANEOUS_CURRENT_L2_VALUE = + public static final CaptureObject INSTANTANEOUS_CURRENT_L2_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.51.7.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject AVERAGE_ACTIVE_POWER_IMPORT_L2_VALUE = + public static final CaptureObject AVERAGE_ACTIVE_POWER_IMPORT_L2_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.41.24.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject AVERAGE_ACTIVE_POWER_EXPORT_L2_VALUE = + public static final CaptureObject AVERAGE_ACTIVE_POWER_EXPORT_L2_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.42.24.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject INSTANTANEOUS_ACTIVE_POWER_IMPORT_L2_VALUE = + public static final CaptureObject INSTANTANEOUS_ACTIVE_POWER_IMPORT_L2_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.41.7.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject INSTANTANEOUS_ACTIVE_POWER_EXPORT_L2_VALUE = + public static final CaptureObject INSTANTANEOUS_ACTIVE_POWER_EXPORT_L2_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.42.7.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject AVERAGE_REACTIVE_POWER_IMPORT_L2_VALUE = + public static final CaptureObject AVERAGE_REACTIVE_POWER_IMPORT_L2_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.43.24.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject AVERAGE_REACTIVE_POWER_EXPORT_L2_VALUE = + public static final CaptureObject AVERAGE_REACTIVE_POWER_EXPORT_L2_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.44.24.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject AVERAGE_CURRENT_L2_VALUE = + public static final CaptureObject AVERAGE_CURRENT_L2_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.51.24.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject INSTANTANEOUS_VOLTAGE_L3_VALUE = + public static final CaptureObject INSTANTANEOUS_VOLTAGE_L3_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.72.7.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject AVERAGE_VOLTAGE_L3_VALUE = + public static final CaptureObject AVERAGE_VOLTAGE_L3_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.72.24.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject INSTANTANEOUS_CURRENT_L3_VALUE = + public static final CaptureObject INSTANTANEOUS_CURRENT_L3_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.71.7.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject AVERAGE_ACTIVE_POWER_IMPORT_L3_VALUE = + public static final CaptureObject AVERAGE_ACTIVE_POWER_IMPORT_L3_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.61.24.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject AVERAGE_ACTIVE_POWER_EXPORT_L3_VALUE = + public static final CaptureObject AVERAGE_ACTIVE_POWER_EXPORT_L3_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.62.24.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject INSTANTANEOUS_ACTIVE_POWER_IMPORT_L3_VALUE = + public static final CaptureObject INSTANTANEOUS_ACTIVE_POWER_IMPORT_L3_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.61.7.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject INSTANTANEOUS_ACTIVE_POWER_EXPORT_L3_VALUE = + public static final CaptureObject INSTANTANEOUS_ACTIVE_POWER_EXPORT_L3_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.62.7.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject AVERAGE_REACTIVE_POWER_IMPORT_L3_VALUE = + public static final CaptureObject AVERAGE_REACTIVE_POWER_IMPORT_L3_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.63.24.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject AVERAGE_REACTIVE_POWER_EXPORT_L3_VALUE = + public static final CaptureObject AVERAGE_REACTIVE_POWER_EXPORT_L3_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.64.24.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject AVERAGE_CURRENT_L3_VALUE = + public static final CaptureObject AVERAGE_CURRENT_L3_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.71.24.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject INSTANTANEOUS_ACTIVE_POWER_IMPORT_VALUE = + public static final CaptureObject INSTANTANEOUS_ACTIVE_POWER_IMPORT_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.1.7.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject INSTANTANEOUS_ACTIVE_POWER_EXPORT_VALUE = + public static final CaptureObject INSTANTANEOUS_ACTIVE_POWER_EXPORT_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.2.7.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject INSTANTANEOUS_ACTIVE_POWER_VALUE = + public static final CaptureObject INSTANTANEOUS_ACTIVE_POWER_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.16.7.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject INSTANTANEOUS_CURRENT_VALUE = + public static final CaptureObject INSTANTANEOUS_CURRENT_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.90.7.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject THRESHOLD_FOR_VOLTAGE_SAG_VALUE = + public static final CaptureObject THRESHOLD_FOR_VOLTAGE_SAG_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.12.31.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject TIME_THRESHOLD_FOR_VOLTAGE_SAG_VALUE = + public static final CaptureObject TIME_THRESHOLD_FOR_VOLTAGE_SAG_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.12.43.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject NUMBER_OF_VOLTAGE_SAGS_IN_PHASE_L1_VALUE = + public static final CaptureObject NUMBER_OF_VOLTAGE_SAGS_IN_PHASE_L1_VALUE = new CaptureObject( InterfaceClass.DATA.id(), "1.0.32.32.0.255", (byte) DataAttribute.VALUE.attributeId(), 0); - private static final CaptureObject NUMBER_OF_VOLTAGE_SAGS_IN_PHASE_L2_VALUE = + public static final CaptureObject NUMBER_OF_VOLTAGE_SAGS_IN_PHASE_L2_VALUE = new CaptureObject( InterfaceClass.DATA.id(), "1.0.52.32.0.255", (byte) DataAttribute.VALUE.attributeId(), 0); - private static final CaptureObject NUMBER_OF_VOLTAGE_SAGS_IN_PHASE_L3_VALUE = + public static final CaptureObject NUMBER_OF_VOLTAGE_SAGS_IN_PHASE_L3_VALUE = new CaptureObject( InterfaceClass.DATA.id(), "1.0.72.32.0.255", (byte) DataAttribute.VALUE.attributeId(), 0); - private static final CaptureObject THRESHOLD_FOR_VOLTAGE_SWELL_VALUE = + public static final CaptureObject THRESHOLD_FOR_VOLTAGE_SWELL_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.12.35.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject TIME_THRESHOLD_FOR_VOLTAGE_SWELL_VALUE = + public static final CaptureObject TIME_THRESHOLD_FOR_VOLTAGE_SWELL_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), "1.0.12.44.0.255", (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject NUMBER_OF_VOLTAGE_SWELLS_IN_PHASE_L1_VALUE = + public static final CaptureObject NUMBER_OF_VOLTAGE_SWELLS_IN_PHASE_L1_VALUE = new CaptureObject( InterfaceClass.DATA.id(), "1.0.32.36.0.255", (byte) DataAttribute.VALUE.attributeId(), 0); - private static final CaptureObject NUMBER_OF_VOLTAGE_SWELLS_IN_PHASE_L2_VALUE = + public static final CaptureObject NUMBER_OF_VOLTAGE_SWELLS_IN_PHASE_L2_VALUE = new CaptureObject( InterfaceClass.DATA.id(), "1.0.52.36.0.255", (byte) DataAttribute.VALUE.attributeId(), 0); - private static final CaptureObject NUMBER_OF_VOLTAGE_SWELLS_IN_PHASE_L3_VALUE = + public static final CaptureObject NUMBER_OF_VOLTAGE_SWELLS_IN_PHASE_L3_VALUE = new CaptureObject( InterfaceClass.DATA.id(), "1.0.72.36.0.255", (byte) DataAttribute.VALUE.attributeId(), 0); static { PROCESSORS_BY_CAPTURE_OBJECT.put(CLOCK_TIME, COSEM_DATE_TIME_PROCESSOR); + PROCESSORS_BY_CAPTURE_OBJECT.put(CDMA_DIAGNOSTIC_SIGNAL_QUALITY, UNSIGNED_PROCESSOR); + PROCESSORS_BY_CAPTURE_OBJECT.put(GPRS_DIAGNOSTIC_SIGNAL_QUALITY, UNSIGNED_PROCESSOR); + PROCESSORS_BY_CAPTURE_OBJECT.put(CDMA_DIAGNOSTIC_BER, UNSIGNED_PROCESSOR); + PROCESSORS_BY_CAPTURE_OBJECT.put(GPRS_DIAGNOSTIC_BER, UNSIGNED_PROCESSOR); + PROCESSORS_BY_CAPTURE_OBJECT.put(MBUS_CLIENT_SETUP_CHN1_VALUE, UNSIGNED_PROCESSOR); + PROCESSORS_BY_CAPTURE_OBJECT.put(MBUS_CLIENT_SETUP_CHN2_VALUE, UNSIGNED_PROCESSOR); + PROCESSORS_BY_CAPTURE_OBJECT.put(MBUS_DIAGNOSTIC_RSSI_CHN1_VALUE, UNSIGNED_PROCESSOR); + PROCESSORS_BY_CAPTURE_OBJECT.put(MBUS_DIAGNOSTIC_RSSI_CHN2_VALUE, UNSIGNED_PROCESSOR); + PROCESSORS_BY_CAPTURE_OBJECT.put(MBUS_DIAGNOSTIC_FCS_NOK_CHN1_VALUE, UNSIGNED_PROCESSOR); + PROCESSORS_BY_CAPTURE_OBJECT.put(MBUS_DIAGNOSTIC_FCS_NOK_CHN2_VALUE, UNSIGNED_PROCESSOR); + PROCESSORS_BY_CAPTURE_OBJECT.put( NUMBER_OF_POWER_FAILURES_IN_ANY_PHASE_VALUE, LONG_UNSIGNED_PROCESSOR); PROCESSORS_BY_CAPTURE_OBJECT.put( @@ -402,42 +459,6 @@ public class DefinableLoadProfile extends ProfileGeneric { NUMBER_OF_VOLTAGE_SWELLS_IN_PHASE_L3_VALUE, LONG_UNSIGNED_PROCESSOR); } - private static final List DEFAULT_CAPTURE_OBJECTS = - Arrays.asList( - CLOCK_TIME, - INSTANTANEOUS_VOLTAGE_L1_VALUE, - INSTANTANEOUS_VOLTAGE_L2_VALUE, - INSTANTANEOUS_VOLTAGE_L3_VALUE, - AVERAGE_VOLTAGE_L1_VALUE, - AVERAGE_VOLTAGE_L2_VALUE, - AVERAGE_VOLTAGE_L3_VALUE, - INSTANTANEOUS_ACTIVE_POWER_IMPORT_L1_VALUE, - INSTANTANEOUS_ACTIVE_POWER_EXPORT_L1_VALUE, - AVERAGE_CURRENT_L1_VALUE, - AVERAGE_ACTIVE_POWER_IMPORT_L1_VALUE, - AVERAGE_ACTIVE_POWER_IMPORT_L2_VALUE, - AVERAGE_ACTIVE_POWER_IMPORT_L3_VALUE, - AVERAGE_ACTIVE_POWER_EXPORT_L1_VALUE, - AVERAGE_ACTIVE_POWER_EXPORT_L2_VALUE, - AVERAGE_ACTIVE_POWER_EXPORT_L3_VALUE, - AVERAGE_REACTIVE_POWER_IMPORT_L1_VALUE, - AVERAGE_REACTIVE_POWER_IMPORT_L2_VALUE, - AVERAGE_REACTIVE_POWER_IMPORT_L3_VALUE, - AVERAGE_REACTIVE_POWER_EXPORT_L1_VALUE, - AVERAGE_REACTIVE_POWER_EXPORT_L2_VALUE, - AVERAGE_REACTIVE_POWER_EXPORT_L3_VALUE, - NUMBER_OF_LONG_POWER_FAILURES_IN_ANY_PHASE_VALUE, - NUMBER_OF_POWER_FAILURES_IN_ANY_PHASE_VALUE, - NUMBER_OF_VOLTAGE_SAGS_IN_PHASE_L1_VALUE, - NUMBER_OF_VOLTAGE_SWELLS_IN_PHASE_L1_VALUE, - NUMBER_OF_VOLTAGE_SAGS_IN_PHASE_L2_VALUE, - NUMBER_OF_VOLTAGE_SWELLS_IN_PHASE_L2_VALUE, - NUMBER_OF_VOLTAGE_SAGS_IN_PHASE_L3_VALUE, - NUMBER_OF_VOLTAGE_SWELLS_IN_PHASE_L3_VALUE, - INSTANTANEOUS_CURRENT_VALUE); - - @Autowired private DynamicValues dynamicValues; - /** * Only for cosem attribute definition, data remains untouched. Attribute data is gathered from * {@link #bufferData}. @@ -492,221 +513,59 @@ public class DefinableLoadProfile extends ProfileGeneric { snOffset = 0x38) private DataObject profileEntries; - private final Calendar time; - - private CaptureObjectDefinitionCollection captureObjectDefinitionCollection; - - private final Random random = new Random(); - - public DefinableLoadProfile(final Calendar time) { - super("0.1.94.31.6.255"); - this.time = time; + public DefinableLoadProfile( + final DynamicValues dynamicValues, + final Calendar time, + final Integer maxNumberOfCaptureObjects, + final List captureObjectList) { + super( + LOGICAL_NAME_DEFINABLE_LOAD_PROFILE, + dynamicValues, + time, + maxNumberOfCaptureObjects, + captureObjectList, + PROCESSORS_BY_CAPTURE_OBJECT); this.buffer = DataObject.newNullData(); - this.captureObjects = this.defaultCaptureObjects(); - this.captureObjectDefinitionCollection = - DefinableLoadProfile.initCaptureObjects(DEFAULT_CAPTURE_OBJECTS); this.sortMethod = DataObject.newEnumerateData(SortMethod.FIFO.value()); this.sortObject = DataObject.newNullData(); this.entriesInUse = DataObject.newNullData(); } - private static CaptureObjectDefinitionCollection initCaptureObjects( - final List captureObjects) { - final CaptureObjectDefinitionCollection definitions = new CaptureObjectDefinitionCollection(); - for (final CaptureObject captureObject : captureObjects) { - definitions.add( - new CaptureObjectDefinition( - captureObject, PROCESSORS_BY_CAPTURE_OBJECT.get(captureObject))); - } - return definitions; - } - - private DataObject defaultCaptureObjects() { - final List captureObjectList = new ArrayList<>(); - for (final CaptureObject captureObject : DEFAULT_CAPTURE_OBJECTS) { - captureObjectList.add(captureObject.asDataObject()); - } - return DataObject.newArrayData(captureObjectList); - } - - /** Initializes buffer with some data. */ - private void initBufferData() { - - final long numberOfProfileEntries = this.getProfileEntries().getValue(); - - this.bufferData = new CircularFifoQueue<>((int) numberOfProfileEntries); - - final List captureObjectDefinitions = this.getCaptureObjectDefinitions(); - final int numberOfCaptureObjects = captureObjectDefinitions.size(); - final long capturePeriodSeconds = this.getCapturePeriod().getValue(); - - for (int i = 0; i < numberOfProfileEntries; i++) { - final Calendar cal = this.getNextDateTime((int) capturePeriodSeconds); - final List profileEntryList = new ArrayList<>(); - profileEntryList.add(cal); - for (int j = 1; j < numberOfCaptureObjects; j++) { - final CaptureObject captureObject = captureObjectDefinitions.get(j); - this.addProfileEntry(profileEntryList, captureObject, cal, this.random); - } - this.bufferData.add(profileEntryList); - } - } - - private void addProfileEntry( - final List profileEntryList, - final CaptureObject captureObject, - final Calendar profileEntryTime, - final Random random) { - - final DataProcessor processor = PROCESSORS_BY_CAPTURE_OBJECT.get(captureObject); - if (COSEM_DATE_TIME_PROCESSOR == processor) { - profileEntryList.add(profileEntryTime); - } else if (LONG_UNSIGNED_PROCESSOR == processor) { - /* - * Random value in the range of valid long-unsigned values [0 .. - * 0xFFFF] - */ - profileEntryList.add(random.nextInt(0xFFFF + 1)); - } else if (DOUBLE_LONG_PROCESSOR == processor) { - /* - * Random value in the range of valid double-long values (any int) - */ - int next = random.nextInt(); - if (random.nextBoolean()) { - next = -next; - } - profileEntryList.add(next); - } else if (DOUBLE_LONG_UNSIGNED_PROCESSOR == processor) { - /* - * Random value in the range of valid double-long-unsigned values [0 - * .. 0xFFFFFFFFL] - */ - profileEntryList.add(Math.max(0xFFFFFFFFL, random.nextLong())); - } - } - - private List getCaptureObjectDefinitions() { - final List captureObjectList = this.captureObjects.getValue(); - final List captureObjectDefinitions = new ArrayList<>(); - for (final DataObject captureObject : captureObjectList) { - captureObjectDefinitions.add(CaptureObject.newCaptureObject(captureObject)); - } - return captureObjectDefinitions; - } - - private Calendar getNextDateTime(final int capturePeriodSeconds) { - final Calendar next = (Calendar) this.time.clone(); - this.time.add(Calendar.SECOND, capturePeriodSeconds); - return next; - } - - @Override - protected CaptureObjectDefinitionCollection getCaptureObjectDefinitionCollection() { - return this.captureObjectDefinitionCollection; - } - @Override public DataObject getBuffer(final SelectiveAccessDescription selectiveAccessDescription) { - if (this.bufferData == null) { - this.initBufferData(); - } return super.getBuffer(selectiveAccessDescription); } @Override public DataObject getCaptureObjects() { - return this.captureObjects; + return super.getCaptureObjects(); } + @Override public void setCaptureObjects(final DataObject captureObjects) throws IllegalAttributeAccessException { - final List captureObjectList = captureObjects.getValue(); - final int numberOfCaptureObjects = captureObjectList.size(); - if (numberOfCaptureObjects > MAX_CAPTURE_OBJECTS) { - LOGGER.error( - "Number of capture objects larger than supported (max {}): {}", - MAX_CAPTURE_OBJECTS, - numberOfCaptureObjects); - throw new IllegalAttributeAccessException( - AccessResultCode.OTHER_REASON, - new IllegalArgumentException( - "Number of capture objects larger than supported (max " - + MAX_CAPTURE_OBJECTS - + "): " - + numberOfCaptureObjects)); - } - this.reinitializeCaptureObjects(captureObjectList); - this.captureObjects = captureObjects; - /* - * Setting the capture objects has an effect on the buffer. Make sure - * the buffer will be reinitialized when getBuffer is called. - */ - this.bufferData = null; - } - - private void reinitializeCaptureObjects(final List captureObjectList) - throws IllegalAttributeAccessException { - final List captureObjectInitList = new ArrayList<>(); - for (final DataObject captureObject : captureObjectList) { - final CaptureObject initCaptureObject; - try { - initCaptureObject = CaptureObject.newCaptureObject(captureObject); - } catch (final RuntimeException e) { - throw new IllegalAttributeAccessException( - AccessResultCode.OTHER_REASON, - new IllegalArgumentException( - "Unable to create capture object from: " + captureObject, e)); - } - if (!PROCESSORS_BY_CAPTURE_OBJECT.containsKey(initCaptureObject)) { - LOGGER.error("No data processor configured for {}", initCaptureObject); - throw new IllegalAttributeAccessException( - AccessResultCode.OTHER_REASON, - new IllegalArgumentException("No data processor configured for " + initCaptureObject)); - } - captureObjectInitList.add(initCaptureObject); - } - this.captureObjectDefinitionCollection = - DefinableLoadProfile.initCaptureObjects(captureObjectInitList); + super.setCaptureObjects(captureObjects); } + @Override public DataObject getCapturePeriod() { - return this.dynamicValues.getDlmsAttributeValue( - this, ProfileGenericAttribute.CAPTURE_PERIOD.attributeId()); + return super.getCapturePeriod(); } + @Override public void setCapturePeriod(final DataObject capturePeriod) { - this.dynamicValues.setDlmsAttributeValue( - this, ProfileGenericAttribute.CAPTURE_PERIOD.attributeId(), capturePeriod); + super.setCapturePeriod(capturePeriod); } + @Override public DataObject getProfileEntries() { - return this.dynamicValues.getDlmsAttributeValue( - this, ProfileGenericAttribute.PROFILE_ENTRIES.attributeId()); + return super.getProfileEntries(); } + @Override public void setProfileEntries(final DataObject profileEntries) throws IllegalAttributeAccessException { - final long numberOfProfileEntries = profileEntries.getValue(); - if (numberOfProfileEntries > MAX_PROFILE_ENTRIES) { - LOGGER.error( - "Number of profile entries larger than supported (max {}): {}", - MAX_PROFILE_ENTRIES, - numberOfProfileEntries); - throw new IllegalAttributeAccessException( - AccessResultCode.OTHER_REASON, - new IllegalArgumentException( - "Number of profile entries larger than supported (max " - + MAX_PROFILE_ENTRIES - + "): " - + numberOfProfileEntries)); - } - this.dynamicValues.setDlmsAttributeValue( - this, ProfileGenericAttribute.PROFILE_ENTRIES.attributeId(), profileEntries); - /* - * Setting the number of profile entries has an effect on the buffer. - * Make sure the buffer will be reinitialized when getBuffer is called. - */ - this.bufferData = null; + super.setProfileEntries(profileEntries); } } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/cosem/DynamicProfile.java b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/cosem/DynamicProfile.java new file mode 100644 index 00000000000..040a8b03676 --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/cosem/DynamicProfile.java @@ -0,0 +1,291 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.simulator.protocol.dlms.cosem; + +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.CDMA_DIAGNOSTIC_BER; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.CDMA_DIAGNOSTIC_SIGNAL_QUALITY; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.GPRS_DIAGNOSTIC_BER; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.GPRS_DIAGNOSTIC_SIGNAL_QUALITY; + +import java.security.SecureRandom; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; +import java.util.Map; +import java.util.Random; +import org.apache.commons.collections4.queue.CircularFifoQueue; +import org.openmuc.jdlms.AccessResultCode; +import org.openmuc.jdlms.IllegalAttributeAccessException; +import org.openmuc.jdlms.SelectiveAccessDescription; +import org.openmuc.jdlms.datatypes.DataObject; +import org.opensmartgridplatform.dlms.interfaceclass.attribute.ProfileGenericAttribute; +import org.opensmartgridplatform.simulator.protocol.dlms.cosem.processing.CaptureObjectDefinition; +import org.opensmartgridplatform.simulator.protocol.dlms.cosem.processing.CaptureObjectDefinitionCollection; +import org.opensmartgridplatform.simulator.protocol.dlms.cosem.processing.CosemDateTimeProcessor; +import org.opensmartgridplatform.simulator.protocol.dlms.cosem.processing.DataProcessor; +import org.opensmartgridplatform.simulator.protocol.dlms.cosem.processing.Integer32DataProcessor; +import org.opensmartgridplatform.simulator.protocol.dlms.cosem.processing.UInteger16DataProcessor; +import org.opensmartgridplatform.simulator.protocol.dlms.cosem.processing.UInteger32DataProcessor; +import org.opensmartgridplatform.simulator.protocol.dlms.cosem.processing.UInteger8DataProcessor; +import org.opensmartgridplatform.simulator.protocol.dlms.util.DynamicValues; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class DynamicProfile extends ProfileGeneric { + private static final Logger LOGGER = LoggerFactory.getLogger(DynamicProfile.class); + + private static final int MAX_PROFILE_ENTRIES = 960; + + protected static final DataProcessor COSEM_DATE_TIME_PROCESSOR = new CosemDateTimeProcessor(); + protected static final DataProcessor UNSIGNED_PROCESSOR = new UInteger8DataProcessor(); + protected static final DataProcessor LONG_UNSIGNED_PROCESSOR = new UInteger16DataProcessor(); + protected static final DataProcessor DOUBLE_LONG_PROCESSOR = new Integer32DataProcessor(); + protected static final DataProcessor DOUBLE_LONG_UNSIGNED_PROCESSOR = + new UInteger32DataProcessor(); + + private DataObject captureObjects; + private final DynamicValues dynamicValues; + private final Map dataProcessorByCaptureObject; + private final Calendar time; + private final Integer maxNumberOfCaptureObjects; + + private final SecureRandom random = new SecureRandom(); + + protected DynamicProfile( + final String instanceId, + final DynamicValues dynamicValues, + final Calendar time, + final Integer maxNumberOfCaptureObjects, + final List captureObjectList, + final Map dataProcessorByCaptureObject) { + super(instanceId); + this.dynamicValues = dynamicValues; + this.maxNumberOfCaptureObjects = maxNumberOfCaptureObjects; + this.time = time; + this.dataProcessorByCaptureObject = dataProcessorByCaptureObject; + + this.captureObjects = this.newCaptureObjectsData(captureObjectList); + } + + protected DataObject newCaptureObjectsData(final List captureObjectList) { + final List dataObjectList = new ArrayList<>(); + for (final CaptureObject captureObject : captureObjectList) { + dataObjectList.add(captureObject.asDataObject()); + } + return DataObject.newArrayData(dataObjectList); + } + + /** Initializes buffer with some data. */ + private void initBufferData() { + + final long numberOfProfileEntries = this.getProfileEntries().getValue(); + + this.bufferData = new CircularFifoQueue<>((int) numberOfProfileEntries); + + final List captureObjectDefinitions = this.getCaptureObjectDefinitions(); + final int numberOfCaptureObjects = captureObjectDefinitions.size(); + final long capturePeriodSeconds = this.getCapturePeriod().getValue(); + + for (int i = 0; i < numberOfProfileEntries; i++) { + final Calendar cal = this.getNextDateTime((int) capturePeriodSeconds); + final List profileEntryList = new ArrayList<>(); + profileEntryList.add(cal); + for (int j = 1; j < numberOfCaptureObjects; j++) { + final CaptureObject captureObject = captureObjectDefinitions.get(j); + this.addProfileEntry(profileEntryList, captureObject, cal, this.random); + } + this.bufferData.add(profileEntryList); + } + } + + private void addProfileEntry( + final List profileEntryList, + final CaptureObject captureObject, + final Calendar profileEntryTime, + final Random random) { + + final DataProcessor processor = this.dataProcessorByCaptureObject.get(captureObject); + if (processor instanceof CosemDateTimeProcessor) { + profileEntryList.add(profileEntryTime); + } else if (processor instanceof UInteger8DataProcessor) { + /* + * Random value in the range of valid unsigned values [0 .. + * 0xFF] + */ + int maxValue = 0xFF + 1; + if (captureObject.equals(GPRS_DIAGNOSTIC_BER) || captureObject.equals(CDMA_DIAGNOSTIC_BER)) { + /* + * ber: 0-7 or 99 + */ + maxValue = 7; + } else if (captureObject.equals(GPRS_DIAGNOSTIC_SIGNAL_QUALITY) + || captureObject.equals(CDMA_DIAGNOSTIC_SIGNAL_QUALITY)) { + /* + * Signal quality: 0-31 or 99 + */ + maxValue = 31; + } + profileEntryList.add((short) random.nextInt(maxValue)); + } else if (processor instanceof UInteger16DataProcessor) { + /* + * Random value in the range of valid long-unsigned values [0 .. + * 0xFFFF] + */ + profileEntryList.add(random.nextInt(0xFFFF + 1)); + } else if (processor instanceof Integer32DataProcessor) { + /* + * Random value in the range of valid double-long values (any int) + */ + int next = random.nextInt(); + if (random.nextBoolean()) { + next = -next; + } + profileEntryList.add(next); + } else if (processor instanceof UInteger32DataProcessor) { + /* + * Random value in the range of valid double-long-unsigned values [0 + * .. 0xFFFFFFFFL] + */ + profileEntryList.add(this.randomDoubleLongUnsigned()); + } else { + throw new IllegalArgumentException("Unknown data processor class: " + processor.getClass()); + } + } + + private long randomDoubleLongUnsigned() { + final long minValue = 0; + final long maxValue = 0xFFFFFFFFL; + return minValue + (long) (this.random.nextDouble() * (maxValue - minValue)); + } + + private List getCaptureObjectDefinitions() { + final List captureObjectList = this.captureObjects.getValue(); + final List captureObjectDefinitions = new ArrayList<>(); + for (final DataObject captureObject : captureObjectList) { + captureObjectDefinitions.add(CaptureObject.newCaptureObject(captureObject)); + } + return captureObjectDefinitions; + } + + private Calendar getNextDateTime(final int capturePeriodSeconds) { + final Calendar next = (Calendar) this.time.clone(); + this.time.add(Calendar.SECOND, capturePeriodSeconds); + return next; + } + + @Override + protected CaptureObjectDefinitionCollection getCaptureObjectDefinitionCollection() { + final List dataObjectList = this.captureObjects.getValue(); + final CaptureObjectDefinitionCollection definitions = new CaptureObjectDefinitionCollection(); + for (final DataObject dataObject : dataObjectList) { + final CaptureObject captureObject = CaptureObject.newCaptureObject(dataObject); + definitions.add( + new CaptureObjectDefinition( + captureObject, this.dataProcessorByCaptureObject.get(captureObject))); + } + return definitions; + } + + @Override + public DataObject getBuffer(final SelectiveAccessDescription selectiveAccessDescription) { + if (this.bufferData == null) { + this.initBufferData(); + } + return super.getBuffer(selectiveAccessDescription); + } + + @Override + public DataObject getCaptureObjects() { + return this.captureObjects; + } + + public void setCaptureObjects(final DataObject captureObjects) + throws IllegalAttributeAccessException { + final List captureObjectList = captureObjects.getValue(); + final int numberOfCaptureObjects = captureObjectList.size(); + if (this.maxNumberOfCaptureObjects != null + && numberOfCaptureObjects > this.maxNumberOfCaptureObjects) { + LOGGER.error( + "Number of capture objects larger than supported (max {}): {}", + this.maxNumberOfCaptureObjects, + numberOfCaptureObjects); + throw new IllegalAttributeAccessException( + AccessResultCode.OTHER_REASON, + new IllegalArgumentException( + "Number of capture objects larger than supported (max " + + this.maxNumberOfCaptureObjects + + "): " + + numberOfCaptureObjects)); + } + this.reinitializeCaptureObjects(captureObjectList); + this.captureObjects = captureObjects; + /* + * Setting the capture objects has an effect on the buffer. Make sure + * the buffer will be reinitialized when getBuffer is called. + */ + this.bufferData = null; + } + + private void reinitializeCaptureObjects(final List captureObjectList) + throws IllegalAttributeAccessException { + for (final DataObject captureObject : captureObjectList) { + final CaptureObject initCaptureObject; + try { + initCaptureObject = CaptureObject.newCaptureObject(captureObject); + } catch (final RuntimeException e) { + throw new IllegalAttributeAccessException( + AccessResultCode.OTHER_REASON, + new IllegalArgumentException( + "Unable to create capture object from: " + captureObject, e)); + } + if (!this.dataProcessorByCaptureObject.containsKey(initCaptureObject)) { + LOGGER.error("No data processor configured for {}", initCaptureObject); + throw new IllegalAttributeAccessException( + AccessResultCode.OTHER_REASON, + new IllegalArgumentException("No data processor configured for " + initCaptureObject)); + } + } + } + + public DataObject getCapturePeriod() { + return this.dynamicValues.getDlmsAttributeValue( + this, ProfileGenericAttribute.CAPTURE_PERIOD.attributeId()); + } + + public void setCapturePeriod(final DataObject capturePeriod) { + this.dynamicValues.setDlmsAttributeValue( + this, ProfileGenericAttribute.CAPTURE_PERIOD.attributeId(), capturePeriod); + } + + public DataObject getProfileEntries() { + return this.dynamicValues.getDlmsAttributeValue( + this, ProfileGenericAttribute.PROFILE_ENTRIES.attributeId()); + } + + public void setProfileEntries(final DataObject profileEntries) + throws IllegalAttributeAccessException { + final long numberOfProfileEntries = profileEntries.getValue(); + if (numberOfProfileEntries > MAX_PROFILE_ENTRIES) { + LOGGER.error( + "Number of profile entries larger than supported (max {}): {}", + MAX_PROFILE_ENTRIES, + numberOfProfileEntries); + throw new IllegalAttributeAccessException( + AccessResultCode.OTHER_REASON, + new IllegalArgumentException( + "Number of profile entries larger than supported (max " + + MAX_PROFILE_ENTRIES + + "): " + + numberOfProfileEntries)); + } + this.dynamicValues.setDlmsAttributeValue( + this, ProfileGenericAttribute.PROFILE_ENTRIES.attributeId(), profileEntries); + /* + * Setting the number of profile entries has an effect on the buffer. + * Make sure the buffer will be reinitialized when getBuffer is called. + */ + this.bufferData = null; + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/cosem/PowerQualityProfile1.java b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/cosem/PowerQualityProfile1.java index 83d21fbd23c..9a6ddcd800b 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/cosem/PowerQualityProfile1.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/cosem/PowerQualityProfile1.java @@ -6,35 +6,30 @@ import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.Clock.LOGICAL_NAME_CLOCK; -import java.util.ArrayList; -import java.util.Arrays; import java.util.Calendar; import java.util.HashMap; import java.util.List; import java.util.Map; -import org.apache.commons.collections4.queue.CircularFifoQueue; import org.openmuc.jdlms.AttributeAccessMode; import org.openmuc.jdlms.CosemAttribute; import org.openmuc.jdlms.CosemClass; +import org.openmuc.jdlms.IllegalAttributeAccessException; +import org.openmuc.jdlms.SelectiveAccessDescription; import org.openmuc.jdlms.datatypes.DataObject; import org.opensmartgridplatform.dlms.interfaceclass.InterfaceClass; import org.opensmartgridplatform.dlms.interfaceclass.attribute.ClockAttribute; import org.opensmartgridplatform.dlms.interfaceclass.attribute.RegisterAttribute; -import org.opensmartgridplatform.simulator.protocol.dlms.cosem.processing.CaptureObjectDefinition; -import org.opensmartgridplatform.simulator.protocol.dlms.cosem.processing.CaptureObjectDefinitionCollection; -import org.opensmartgridplatform.simulator.protocol.dlms.cosem.processing.CosemDateTimeProcessor; import org.opensmartgridplatform.simulator.protocol.dlms.cosem.processing.DataProcessor; -import org.opensmartgridplatform.simulator.protocol.dlms.cosem.processing.UInteger16DataProcessor; +import org.opensmartgridplatform.simulator.protocol.dlms.util.DynamicValues; @CosemClass(id = 7) -public class PowerQualityProfile1 extends ProfileGeneric { - /** Every 15 minutes. */ - private static final int CAPTURE_PERIOD = 900; +public class PowerQualityProfile1 extends DynamicProfile { + public static final String LOGICAL_NAME = "1.0.99.1.1.255"; + public static final int CAPTURE_PERIOD = 900; /** 10 days = 240 hours = 960 periods of 15 minutes. */ - private static final int PROFILE_ENTRIES = 960; + public static final int PROFILE_ENTRIES = 960; - private static final String LOGICAL_NAME_POWER_QUALITY_PROFILE_1 = "1.0.99.1.1.255"; public static final String AVERAGE_ACTIVE_POWER_IMPORT_L1_LOGICAL_NAME = "1.0.21.4.0.255"; public static final String AVERAGE_ACTIVE_POWER_IMPORT_L2_LOGICAL_NAME = "1.0.41.4.0.255"; public static final String AVERAGE_ACTIVE_POWER_IMPORT_L3_LOGICAL_NAME = "1.0.61.4.0.255"; @@ -48,86 +43,83 @@ public class PowerQualityProfile1 extends ProfileGeneric { public static final String AVERAGE_REACTIVE_POWER_EXPORT_L2_LOGICAL_NAME = "1.0.44.4.0.255"; public static final String AVERAGE_REACTIVE_POWER_EXPORT_L3_LOGICAL_NAME = "1.0.64.4.0.255"; - private CaptureObjectDefinitionCollection captureObjectDefinitionCollection; private static final Map PROCESSORS_BY_CAPTURE_OBJECT = new HashMap<>(); - private static final DataProcessor COSEM_DATE_TIME_PROCESSOR = new CosemDateTimeProcessor(); - private static final DataProcessor LONG_UNSIGNED_PROCESSOR = new UInteger16DataProcessor(); - private static final CaptureObject CLOCK_TIME = + public static final CaptureObject CLOCK_TIME = new CaptureObject( InterfaceClass.CLOCK.id(), LOGICAL_NAME_CLOCK, (byte) ClockAttribute.TIME.attributeId(), 0); - private static final CaptureObject AVERAGE_ACTIVE_POWER_IMPORT_L1_VALUE = + public static final CaptureObject AVERAGE_ACTIVE_POWER_IMPORT_L1_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), AVERAGE_ACTIVE_POWER_IMPORT_L1_LOGICAL_NAME, (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject AVERAGE_ACTIVE_POWER_IMPORT_L2_VALUE = + public static final CaptureObject AVERAGE_ACTIVE_POWER_IMPORT_L2_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), AVERAGE_ACTIVE_POWER_IMPORT_L2_LOGICAL_NAME, (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject AVERAGE_ACTIVE_POWER_IMPORT_L3_VALUE = + public static final CaptureObject AVERAGE_ACTIVE_POWER_IMPORT_L3_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), AVERAGE_ACTIVE_POWER_IMPORT_L3_LOGICAL_NAME, (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject AVERAGE_ACTIVE_POWER_EXPORT_L1_VALUE = + public static final CaptureObject AVERAGE_ACTIVE_POWER_EXPORT_L1_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), PowerQualityProfile1.AVERAGE_ACTIVE_POWER_EXPORT_L1_LOGICAL_NAME, (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject AVERAGE_ACTIVE_POWER_EXPORT_L2_VALUE = + public static final CaptureObject AVERAGE_ACTIVE_POWER_EXPORT_L2_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), AVERAGE_ACTIVE_POWER_EXPORT_L2_LOGICAL_NAME, (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject AVERAGE_ACTIVE_POWER_EXPORT_L3_VALUE = + public static final CaptureObject AVERAGE_ACTIVE_POWER_EXPORT_L3_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), AVERAGE_ACTIVE_POWER_EXPORT_L3_LOGICAL_NAME, (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject AVERAGE_REACTIVE_POWER_IMPORT_L1_VALUE = + public static final CaptureObject AVERAGE_REACTIVE_POWER_IMPORT_L1_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), AVERAGE_REACTIVE_POWER_IMPORT_L1_LOGICAL_NAME, (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject AVERAGE_REACTIVE_POWER_IMPORT_L2_VALUE = + public static final CaptureObject AVERAGE_REACTIVE_POWER_IMPORT_L2_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), AVERAGE_REACTIVE_POWER_IMPORT_L2_LOGICAL_NAME, (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject AVERAGE_REACTIVE_POWER_IMPORT_L3_VALUE = + public static final CaptureObject AVERAGE_REACTIVE_POWER_IMPORT_L3_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), AVERAGE_REACTIVE_POWER_IMPORT_L3_LOGICAL_NAME, (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject AVERAGE_REACTIVE_POWER_EXPORT_L1_VALUE = + public static final CaptureObject AVERAGE_REACTIVE_POWER_EXPORT_L1_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), AVERAGE_REACTIVE_POWER_EXPORT_L1_LOGICAL_NAME, (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject AVERAGE_REACTIVE_POWER_EXPORT_L2_VALUE = + public static final CaptureObject AVERAGE_REACTIVE_POWER_EXPORT_L2_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), AVERAGE_REACTIVE_POWER_EXPORT_L2_LOGICAL_NAME, (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject AVERAGE_REACTIVE_POWER_EXPORT_L3_VALUE = + public static final CaptureObject AVERAGE_REACTIVE_POWER_EXPORT_L3_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), AVERAGE_REACTIVE_POWER_EXPORT_L3_LOGICAL_NAME, @@ -177,7 +169,7 @@ public class PowerQualityProfile1 extends ProfileGeneric { type = DataObject.Type.ARRAY, accessMode = AttributeAccessMode.READ_AND_WRITE, snOffset = 0x10) - private final DataObject captureObjects; + private DataObject captureObjects; @CosemAttribute( id = 4, @@ -218,104 +210,59 @@ public class PowerQualityProfile1 extends ProfileGeneric { snOffset = 0x38) public DataObject profileEntries; - private final Calendar time; - - private static final List DEFAULT_CAPTURE_OBJECTS = - Arrays.asList( - CLOCK_TIME, - AVERAGE_ACTIVE_POWER_IMPORT_L1_VALUE, - AVERAGE_ACTIVE_POWER_IMPORT_L2_VALUE, - AVERAGE_ACTIVE_POWER_IMPORT_L3_VALUE, - AVERAGE_ACTIVE_POWER_EXPORT_L1_VALUE, - AVERAGE_ACTIVE_POWER_EXPORT_L2_VALUE, - AVERAGE_ACTIVE_POWER_EXPORT_L3_VALUE, - AVERAGE_REACTIVE_POWER_IMPORT_L1_VALUE, - AVERAGE_REACTIVE_POWER_IMPORT_L2_VALUE, - AVERAGE_REACTIVE_POWER_IMPORT_L3_VALUE, - AVERAGE_REACTIVE_POWER_EXPORT_L1_VALUE, - AVERAGE_REACTIVE_POWER_EXPORT_L2_VALUE, - AVERAGE_REACTIVE_POWER_EXPORT_L3_VALUE); - - public PowerQualityProfile1(final Calendar time) { - super(LOGICAL_NAME_POWER_QUALITY_PROFILE_1); - this.time = time; + public PowerQualityProfile1( + final DynamicValues dynamicValues, + final Calendar time, + final Integer maxNumberOfCaptureObjects, + final List captureObjectList) { + super( + LOGICAL_NAME, + dynamicValues, + time, + maxNumberOfCaptureObjects, + captureObjectList, + PROCESSORS_BY_CAPTURE_OBJECT); this.buffer = DataObject.newNullData(); - this.captureObjects = this.defaultCaptureObjects(); - this.captureObjectDefinitionCollection = initCaptureObjects(DEFAULT_CAPTURE_OBJECTS); - this.capturePeriod = DataObject.newUInteger32Data(CAPTURE_PERIOD); this.sortMethod = DataObject.newEnumerateData(SortMethod.FIFO.value()); this.sortObject = DataObject.newNullData(); this.entriesInUse = DataObject.newNullData(); - this.profileEntries = DataObject.newUInteger32Data(PROFILE_ENTRIES); - - this.initBufferData(); } - private static CaptureObjectDefinitionCollection initCaptureObjects( - final List captureObjects) { - final CaptureObjectDefinitionCollection definitions = new CaptureObjectDefinitionCollection(); + @Override + public DataObject getBuffer(final SelectiveAccessDescription selectiveAccessDescription) { + return super.getBuffer(selectiveAccessDescription); + } - for (final CaptureObject captureObject : captureObjects) { - definitions.add( - new CaptureObjectDefinition( - captureObject, PROCESSORS_BY_CAPTURE_OBJECT.get(captureObject))); - } - return definitions; + @Override + public DataObject getCaptureObjects() { + return super.getCaptureObjects(); } - private DataObject defaultCaptureObjects() { - final List captureObjectList = new ArrayList<>(); - for (final CaptureObject captureObject : DEFAULT_CAPTURE_OBJECTS) { - captureObjectList.add(captureObject.asDataObject()); - } - return DataObject.newArrayData(captureObjectList); + @Override + public void setCaptureObjects(final DataObject captureObjects) + throws IllegalAttributeAccessException { + super.setCaptureObjects(captureObjects); } - /** Initializes buffer with some data. */ - private void initBufferData() { - this.bufferData = new CircularFifoQueue<>(PROFILE_ENTRIES); - final int averageActivePowerImportL1Value = 10; - final int averageActivePowerImportL2Value = 10; - final int averageActivePowerImportL3Value = 10; - final int averageActivePowerExportL1Value = 10; - final int averageActivePowerExportL2Value = 10; - final int averageActivePowerExportL3Value = 10; - final int averageReactivePowerImportL1Value = 15; - final int averageReactivePowerImportL2Value = 15; - final int averageReactivePowerImportL3Value = 15; - final int averageReactivePowerExportL1Value = 15; - final int averageReactivePowerExportL2Value = 15; - final int averageReactivePowerExportL3Value = 15; + @Override + public DataObject getCapturePeriod() { + return super.getCapturePeriod(); + } - for (int i = 0; i < PROFILE_ENTRIES; i++) { - final Calendar cal = this.getNextDateTime(); - this.bufferData.add( - Arrays.asList( - cal, - averageActivePowerImportL1Value, - averageActivePowerImportL2Value, - averageActivePowerImportL3Value, - averageActivePowerExportL1Value, - averageActivePowerExportL2Value, - averageActivePowerExportL3Value, - averageReactivePowerImportL1Value, - averageReactivePowerImportL2Value, - averageReactivePowerImportL3Value, - averageReactivePowerExportL1Value, - averageReactivePowerExportL2Value, - averageReactivePowerExportL3Value)); - } + @Override + public void setCapturePeriod(final DataObject capturePeriod) { + super.setCapturePeriod(capturePeriod); } - private Calendar getNextDateTime() { - final Calendar next = (Calendar) this.time.clone(); - this.time.add(Calendar.MINUTE, 10); - return next; + @Override + public DataObject getProfileEntries() { + return super.getProfileEntries(); } @Override - protected CaptureObjectDefinitionCollection getCaptureObjectDefinitionCollection() { - return this.captureObjectDefinitionCollection; + public void setProfileEntries(final DataObject profileEntries) + throws IllegalAttributeAccessException { + super.setProfileEntries(profileEntries); } } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/cosem/PowerQualityProfile2.java b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/cosem/PowerQualityProfile2.java index 2dd9924841a..53ec90ea5d8 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/cosem/PowerQualityProfile2.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/cosem/PowerQualityProfile2.java @@ -6,35 +6,31 @@ import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.Clock.LOGICAL_NAME_CLOCK; -import java.util.ArrayList; -import java.util.Arrays; import java.util.Calendar; import java.util.HashMap; import java.util.List; import java.util.Map; -import org.apache.commons.collections4.queue.CircularFifoQueue; import org.openmuc.jdlms.AttributeAccessMode; import org.openmuc.jdlms.CosemAttribute; import org.openmuc.jdlms.CosemClass; +import org.openmuc.jdlms.IllegalAttributeAccessException; +import org.openmuc.jdlms.SelectiveAccessDescription; import org.openmuc.jdlms.datatypes.DataObject; import org.opensmartgridplatform.dlms.interfaceclass.InterfaceClass; import org.opensmartgridplatform.dlms.interfaceclass.attribute.ClockAttribute; import org.opensmartgridplatform.dlms.interfaceclass.attribute.RegisterAttribute; -import org.opensmartgridplatform.simulator.protocol.dlms.cosem.processing.CaptureObjectDefinition; -import org.opensmartgridplatform.simulator.protocol.dlms.cosem.processing.CaptureObjectDefinitionCollection; -import org.opensmartgridplatform.simulator.protocol.dlms.cosem.processing.CosemDateTimeProcessor; import org.opensmartgridplatform.simulator.protocol.dlms.cosem.processing.DataProcessor; -import org.opensmartgridplatform.simulator.protocol.dlms.cosem.processing.UInteger16DataProcessor; +import org.opensmartgridplatform.simulator.protocol.dlms.util.DynamicValues; @CosemClass(id = 7) -public class PowerQualityProfile2 extends ProfileGeneric { +public class PowerQualityProfile2 extends DynamicProfile { /** Every 10 minutes. */ - private static final int CAPTURE_PERIOD = 600; + public static final int CAPTURE_PERIOD = 600; /** 10 days = 240 hours = 1440 periods of 10 minutes. */ - private static final int PROFILE_ENTRIES = 1440; + public static final int PROFILE_ENTRIES = 1440; - private static final String LOGICAL_NAME_POWER_QUALITY_PROFILE_2 = "1.0.99.1.2.255"; + public static final String LOGICAL_NAME = "1.0.99.1.2.255"; public static final String AVERAGE_VOLTAGE_L1_LOGICAL_NAME = "1.0.32.24.0.255"; public static final String AVERAGE_VOLTAGE_L2_LOGICAL_NAME = "1.0.52.24.0.255"; @@ -65,80 +61,126 @@ public class PowerQualityProfile2 extends ProfileGeneric { public static final String INSTANTANEOUS_ACTIVE_POWER_IMPORT_L2_LOGICAL_NAME = "1.0.41.7.0.255"; public static final String INSTANTANEOUS_ACTIVE_POWER_IMPORT_L3_LOGICAL_NAME = "1.0.61.7.0.255"; - private final CaptureObjectDefinitionCollection captureObjectDefinitionCollection; private static final Map PROCESSORS_BY_CAPTURE_OBJECT = new HashMap<>(); - private static final DataProcessor COSEM_DATE_TIME_PROCESSOR = new CosemDateTimeProcessor(); - private static final DataProcessor LONG_UNSIGNED_PROCESSOR = new UInteger16DataProcessor(); - private static final CaptureObject CLOCK_TIME = + public static final CaptureObject CLOCK_TIME = new CaptureObject( InterfaceClass.CLOCK.id(), LOGICAL_NAME_CLOCK, (byte) ClockAttribute.TIME.attributeId(), 0); - private static final CaptureObject AVERAGE_VOLTAGE_L1_VALUE = + public static final CaptureObject AVERAGE_VOLTAGE_L1_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), AVERAGE_VOLTAGE_L1_LOGICAL_NAME, (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject AVERAGE_VOLTAGE_L2_VALUE = + public static final CaptureObject AVERAGE_VOLTAGE_L2_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), AVERAGE_VOLTAGE_L2_LOGICAL_NAME, (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject AVERAGE_VOLTAGE_L3_VALUE = + public static final CaptureObject AVERAGE_VOLTAGE_L3_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), AVERAGE_VOLTAGE_L3_LOGICAL_NAME, (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject INSTANTANEOUS_VOLTAGE_L1_VALUE = + public static final CaptureObject INSTANTANEOUS_VOLTAGE_L1_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), INSTANTANEOUS_VOLTAGE_L1_LOGICAL_NAME, (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject INSTANTANEOUS_VOLTAGE_L2_VALUE = + public static final CaptureObject INSTANTANEOUS_VOLTAGE_L2_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), INSTANTANEOUS_VOLTAGE_L2_LOGICAL_NAME, (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject INSTANTANEOUS_VOLTAGE_L3_VALUE = + public static final CaptureObject INSTANTANEOUS_VOLTAGE_L3_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), INSTANTANEOUS_VOLTAGE_L3_LOGICAL_NAME, (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject AVERAGE_CURRENT_L1_VALUE = + public static final CaptureObject AVERAGE_CURRENT_L1_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), AVERAGE_CURRENT_L1_LOGICAL_NAME, (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject AVERAGE_CURRENT_L2_VALUE = + public static final CaptureObject AVERAGE_CURRENT_L2_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), AVERAGE_CURRENT_L2_LOGICAL_NAME, (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject AVERAGE_CURRENT_L3_VALUE = + public static final CaptureObject AVERAGE_CURRENT_L3_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), AVERAGE_CURRENT_L3_LOGICAL_NAME, (byte) RegisterAttribute.VALUE.attributeId(), 0); - private static final CaptureObject INSTANTANEOUS_CURRENT_L1_VALUE = + public static final CaptureObject INSTANTANEOUS_CURRENT_L1_VALUE = new CaptureObject( InterfaceClass.REGISTER.id(), INSTANTANEOUS_CURRENT_L1_LOGICAL_NAME, (byte) RegisterAttribute.VALUE.attributeId(), 0); + public static final CaptureObject INSTANTANEOUS_ACTIVE_POWER_IMPORT_VALUE = + new CaptureObject( + InterfaceClass.REGISTER.id(), + INSTANTANEOUS_ACTIVE_POWER_IMPORT_LOGICAL_NAME, + (byte) RegisterAttribute.VALUE.attributeId(), + 0); + public static final CaptureObject INSTANTANEOUS_ACTIVE_POWER_EXPORT_VALUE = + new CaptureObject( + InterfaceClass.REGISTER.id(), + INSTANTANEOUS_ACTIVE_POWER_EXPORT_LOGICAL_NAME, + (byte) RegisterAttribute.VALUE.attributeId(), + 0); + + public static final CaptureObject INSTANTANEOUS_ACTIVE_POWER_IMPORT_L1_VALUE = + new CaptureObject( + InterfaceClass.REGISTER.id(), + INSTANTANEOUS_ACTIVE_POWER_IMPORT_LOGICAL_NAME, + (byte) RegisterAttribute.VALUE.attributeId(), + 0); + public static final CaptureObject INSTANTANEOUS_ACTIVE_POWER_IMPORT_L2_VALUE = + new CaptureObject( + InterfaceClass.REGISTER.id(), + INSTANTANEOUS_ACTIVE_POWER_IMPORT_L2_LOGICAL_NAME, + (byte) RegisterAttribute.VALUE.attributeId(), + 0); + public static final CaptureObject INSTANTANEOUS_ACTIVE_POWER_IMPORT_L3_VALUE = + new CaptureObject( + InterfaceClass.REGISTER.id(), + INSTANTANEOUS_ACTIVE_POWER_IMPORT_L3_LOGICAL_NAME, + (byte) RegisterAttribute.VALUE.attributeId(), + 0); + public static final CaptureObject INSTANTANEOUS_ACTIVE_POWER_EXPORT_L1_VALUE = + new CaptureObject( + InterfaceClass.REGISTER.id(), + INSTANTANEOUS_ACTIVE_POWER_EXPORT_L1_LOGICAL_NAME, + (byte) RegisterAttribute.VALUE.attributeId(), + 0); + public static final CaptureObject INSTANTANEOUS_ACTIVE_POWER_EXPORT_L2_VALUE = + new CaptureObject( + InterfaceClass.REGISTER.id(), + INSTANTANEOUS_ACTIVE_POWER_EXPORT_L2_LOGICAL_NAME, + (byte) RegisterAttribute.VALUE.attributeId(), + 0); + public static final CaptureObject INSTANTANEOUS_ACTIVE_POWER_EXPORT_L3_VALUE = + new CaptureObject( + InterfaceClass.REGISTER.id(), + INSTANTANEOUS_ACTIVE_POWER_EXPORT_L3_LOGICAL_NAME, + (byte) RegisterAttribute.VALUE.attributeId(), + 0); static { PROCESSORS_BY_CAPTURE_OBJECT.put(CLOCK_TIME, COSEM_DATE_TIME_PROCESSOR); @@ -152,6 +194,22 @@ public class PowerQualityProfile2 extends ProfileGeneric { PROCESSORS_BY_CAPTURE_OBJECT.put(AVERAGE_CURRENT_L2_VALUE, LONG_UNSIGNED_PROCESSOR); PROCESSORS_BY_CAPTURE_OBJECT.put(AVERAGE_CURRENT_L3_VALUE, LONG_UNSIGNED_PROCESSOR); PROCESSORS_BY_CAPTURE_OBJECT.put(INSTANTANEOUS_CURRENT_L1_VALUE, LONG_UNSIGNED_PROCESSOR); + PROCESSORS_BY_CAPTURE_OBJECT.put( + INSTANTANEOUS_ACTIVE_POWER_IMPORT_VALUE, DOUBLE_LONG_UNSIGNED_PROCESSOR); + PROCESSORS_BY_CAPTURE_OBJECT.put( + INSTANTANEOUS_ACTIVE_POWER_EXPORT_VALUE, DOUBLE_LONG_UNSIGNED_PROCESSOR); + PROCESSORS_BY_CAPTURE_OBJECT.put( + INSTANTANEOUS_ACTIVE_POWER_IMPORT_L1_VALUE, LONG_UNSIGNED_PROCESSOR); + PROCESSORS_BY_CAPTURE_OBJECT.put( + INSTANTANEOUS_ACTIVE_POWER_IMPORT_L2_VALUE, LONG_UNSIGNED_PROCESSOR); + PROCESSORS_BY_CAPTURE_OBJECT.put( + INSTANTANEOUS_ACTIVE_POWER_IMPORT_L3_VALUE, LONG_UNSIGNED_PROCESSOR); + PROCESSORS_BY_CAPTURE_OBJECT.put( + INSTANTANEOUS_ACTIVE_POWER_EXPORT_L1_VALUE, LONG_UNSIGNED_PROCESSOR); + PROCESSORS_BY_CAPTURE_OBJECT.put( + INSTANTANEOUS_ACTIVE_POWER_EXPORT_L2_VALUE, LONG_UNSIGNED_PROCESSOR); + PROCESSORS_BY_CAPTURE_OBJECT.put( + INSTANTANEOUS_ACTIVE_POWER_EXPORT_L3_VALUE, LONG_UNSIGNED_PROCESSOR); } /** @@ -175,7 +233,7 @@ public class PowerQualityProfile2 extends ProfileGeneric { type = DataObject.Type.ARRAY, accessMode = AttributeAccessMode.READ_AND_WRITE, snOffset = 0x10) - private final DataObject captureObjects; + private DataObject captureObjects; @CosemAttribute( id = 4, @@ -216,98 +274,59 @@ public class PowerQualityProfile2 extends ProfileGeneric { snOffset = 0x38) public DataObject profileEntries; - private final Calendar time; - - private static final List DEFAULT_CAPTURE_OBJECTS = - Arrays.asList( - CLOCK_TIME, - AVERAGE_VOLTAGE_L1_VALUE, - AVERAGE_VOLTAGE_L2_VALUE, - AVERAGE_VOLTAGE_L3_VALUE, - INSTANTANEOUS_VOLTAGE_L1_VALUE, - INSTANTANEOUS_VOLTAGE_L2_VALUE, - INSTANTANEOUS_VOLTAGE_L3_VALUE, - AVERAGE_CURRENT_L1_VALUE, - AVERAGE_CURRENT_L2_VALUE, - AVERAGE_CURRENT_L3_VALUE, - INSTANTANEOUS_CURRENT_L1_VALUE); - - public PowerQualityProfile2(final Calendar time) { - super(LOGICAL_NAME_POWER_QUALITY_PROFILE_2); - this.time = time; + public PowerQualityProfile2( + final DynamicValues dynamicValues, + final Calendar time, + final Integer maxNumberOfCaptureObjects, + final List captureObjectList) { + super( + LOGICAL_NAME, + dynamicValues, + time, + maxNumberOfCaptureObjects, + captureObjectList, + PROCESSORS_BY_CAPTURE_OBJECT); this.buffer = DataObject.newNullData(); - this.captureObjects = this.defaultCaptureObjects(); - this.captureObjectDefinitionCollection = initCaptureObjects(DEFAULT_CAPTURE_OBJECTS); - this.capturePeriod = DataObject.newUInteger32Data(CAPTURE_PERIOD); this.sortMethod = DataObject.newEnumerateData(SortMethod.FIFO.value()); this.sortObject = DataObject.newNullData(); this.entriesInUse = DataObject.newNullData(); - this.profileEntries = DataObject.newUInteger32Data(PROFILE_ENTRIES); + } - this.initBufferData(); + @Override + public DataObject getBuffer(final SelectiveAccessDescription selectiveAccessDescription) { + return super.getBuffer(selectiveAccessDescription); } - private static CaptureObjectDefinitionCollection initCaptureObjects( - final List captureObjects) { - final CaptureObjectDefinitionCollection definitions = new CaptureObjectDefinitionCollection(); + @Override + public DataObject getCaptureObjects() { + return super.getCaptureObjects(); + } - for (final CaptureObject captureObject : captureObjects) { - definitions.add( - new CaptureObjectDefinition( - captureObject, PROCESSORS_BY_CAPTURE_OBJECT.get(captureObject))); - } - return definitions; + @Override + public void setCaptureObjects(final DataObject captureObjects) + throws IllegalAttributeAccessException { + super.setCaptureObjects(captureObjects); } - private DataObject defaultCaptureObjects() { - final List captureObjectList = new ArrayList<>(); - for (final CaptureObject captureObject : DEFAULT_CAPTURE_OBJECTS) { - captureObjectList.add(captureObject.asDataObject()); - } - return DataObject.newArrayData(captureObjectList); + @Override + public DataObject getCapturePeriod() { + return super.getCapturePeriod(); } - /** Initializes buffer with some data. */ - private void initBufferData() { - this.bufferData = new CircularFifoQueue<>(PROFILE_ENTRIES); - final long averageCurrentL1Value = 1; - final long averageCurrentL2Value = 1; - final long averageCurrentL3Value = 1; - final long averageVoltageL1Value = 1; - final long averageVoltageL2Value = 1; - final long averageVoltageL3Value = 1; - final long instantaneousVoltageL1Value = 230; - final long instantaneousVoltageL2Value = 230; - final long instantaneousVoltageL3Value = 230; - final long instantaneousCurrentL1Value = 1; - - for (int i = 0; i < PROFILE_ENTRIES; i++) { - final Calendar cal = this.getNextDateTime(); - this.bufferData.add( - Arrays.asList( - cal, - averageCurrentL1Value, - averageCurrentL2Value, - averageCurrentL3Value, - averageVoltageL1Value, - averageVoltageL2Value, - averageVoltageL3Value, - instantaneousVoltageL1Value, - instantaneousVoltageL2Value, - instantaneousVoltageL3Value, - instantaneousCurrentL1Value)); - } + @Override + public void setCapturePeriod(final DataObject capturePeriod) { + super.setCapturePeriod(capturePeriod); } - private Calendar getNextDateTime() { - final Calendar next = (Calendar) this.time.clone(); - this.time.add(Calendar.MINUTE, 10); - return next; + @Override + public DataObject getProfileEntries() { + return super.getProfileEntries(); } @Override - protected CaptureObjectDefinitionCollection getCaptureObjectDefinitionCollection() { - return this.captureObjectDefinitionCollection; + public void setProfileEntries(final DataObject profileEntries) + throws IllegalAttributeAccessException { + super.setProfileEntries(profileEntries); } } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/rest/client/DlmsAttributeValuesClient.java b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/rest/client/DlmsAttributeValuesClient.java index 3602fcdc83a..4fe5ef5a50c 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/rest/client/DlmsAttributeValuesClient.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/rest/client/DlmsAttributeValuesClient.java @@ -87,6 +87,7 @@ public class DlmsAttributeValuesClient { "array", json -> DataObject.newArrayData(asDataObjectList(json))); JSON_TO_DATA_OBJECT_CONVERTERS.put( "structure", json -> DataObject.newStructureData(asDataObjectList(json))); + JSON_TO_DATA_OBJECT_CONVERTERS.put("boolean", json -> DataObject.newBoolData(json.asBoolean())); } private final WebClient webClient; diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/server/profile/DefaultDeviceProfile.java b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/server/profile/DefaultDeviceProfile.java index c809f475588..309d3ee2817 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/server/profile/DefaultDeviceProfile.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/server/profile/DefaultDeviceProfile.java @@ -55,7 +55,6 @@ import org.openmuc.jdlms.datatypes.DataObject; import org.opensmartgridplatform.dlms.interfaceclass.InterfaceClass; import org.opensmartgridplatform.dlms.interfaceclass.attribute.DataAttribute; -import org.opensmartgridplatform.dlms.interfaceclass.attribute.ProfileGenericAttribute; import org.opensmartgridplatform.simulator.protocol.dlms.cosem.ActiveFirmwareIdentifier; import org.opensmartgridplatform.simulator.protocol.dlms.cosem.ActiveFirmwareSignature; import org.opensmartgridplatform.simulator.protocol.dlms.cosem.ActivityCalendar; @@ -70,7 +69,6 @@ import org.opensmartgridplatform.simulator.protocol.dlms.cosem.CommunicationSessionLog; import org.opensmartgridplatform.simulator.protocol.dlms.cosem.ConfigurationObject; import org.opensmartgridplatform.simulator.protocol.dlms.cosem.CurrentlyActiveTariff; -import org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile; import org.opensmartgridplatform.simulator.protocol.dlms.cosem.DoubleLongUnsignedExtendedRegister; import org.opensmartgridplatform.simulator.protocol.dlms.cosem.DoubleLongUnsignedRegister; import org.opensmartgridplatform.simulator.protocol.dlms.cosem.ErrorObject; @@ -823,26 +821,6 @@ public LoadProfileWithPeriod2 loadProfile2(final Calendar cal) { return new LoadProfileWithPeriod2(cal); } - @Bean - public DefinableLoadProfile definableLoadProfile(final Calendar cal) { - final Integer classId = InterfaceClass.PROFILE_GENERIC.id(); - final ObisCode obisCode = new ObisCode(0, 1, 94, 31, 6, 255); - this.dynamicValues() - .setDefaultAttributeValue( - classId, - obisCode, - ProfileGenericAttribute.CAPTURE_PERIOD.attributeId(), - DataObject.newUInteger32Data(300)); - this.dynamicValues() - .setDefaultAttributeValue( - classId, - obisCode, - ProfileGenericAttribute.PROFILE_ENTRIES.attributeId(), - DataObject.newUInteger32Data(960)); - - return new DefinableLoadProfile(cal); - } - @Bean public AmrProfileStatusCodeEMeter amrProfileStatusCodeEMeter() { return new AmrProfileStatusCodeEMeter(this.amrProfileStatusCodeEMeter); diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/server/profile/Dsmr422Profile.java b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/server/profile/Dsmr422Profile.java new file mode 100644 index 00000000000..66ffa8e8b9f --- /dev/null +++ b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/server/profile/Dsmr422Profile.java @@ -0,0 +1,80 @@ +// SPDX-FileCopyrightText: Copyright Contributors to the GXF project +// +// SPDX-License-Identifier: Apache-2.0 + +package org.opensmartgridplatform.simulator.protocol.dlms.server.profile; + +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.*; + +import java.util.Arrays; +import java.util.Calendar; +import java.util.List; +import org.openmuc.jdlms.ObisCode; +import org.openmuc.jdlms.datatypes.DataObject; +import org.opensmartgridplatform.dlms.interfaceclass.InterfaceClass; +import org.opensmartgridplatform.dlms.interfaceclass.attribute.ProfileGenericAttribute; +import org.opensmartgridplatform.simulator.protocol.dlms.cosem.CaptureObject; +import org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile; +import org.opensmartgridplatform.simulator.protocol.dlms.util.DynamicValues; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; + +@Configuration +@Profile("dsmr422") +public class Dsmr422Profile { + private static final List DEFAULT_CAPTURE_OBJECTS = + Arrays.asList( + CLOCK_TIME, + INSTANTANEOUS_VOLTAGE_L1_VALUE, + INSTANTANEOUS_VOLTAGE_L2_VALUE, + INSTANTANEOUS_VOLTAGE_L3_VALUE, + AVERAGE_VOLTAGE_L1_VALUE, + AVERAGE_VOLTAGE_L2_VALUE, + AVERAGE_VOLTAGE_L3_VALUE, + INSTANTANEOUS_ACTIVE_POWER_IMPORT_L1_VALUE, + INSTANTANEOUS_ACTIVE_POWER_EXPORT_L1_VALUE, + AVERAGE_CURRENT_L1_VALUE, + AVERAGE_ACTIVE_POWER_IMPORT_L1_VALUE, + AVERAGE_ACTIVE_POWER_IMPORT_L2_VALUE, + AVERAGE_ACTIVE_POWER_IMPORT_L3_VALUE, + AVERAGE_ACTIVE_POWER_EXPORT_L1_VALUE, + AVERAGE_ACTIVE_POWER_EXPORT_L2_VALUE, + AVERAGE_ACTIVE_POWER_EXPORT_L3_VALUE, + AVERAGE_REACTIVE_POWER_IMPORT_L1_VALUE, + AVERAGE_REACTIVE_POWER_IMPORT_L2_VALUE, + AVERAGE_REACTIVE_POWER_IMPORT_L3_VALUE, + AVERAGE_REACTIVE_POWER_EXPORT_L1_VALUE, + AVERAGE_REACTIVE_POWER_EXPORT_L2_VALUE, + AVERAGE_REACTIVE_POWER_EXPORT_L3_VALUE, + NUMBER_OF_LONG_POWER_FAILURES_IN_ANY_PHASE_VALUE, + NUMBER_OF_POWER_FAILURES_IN_ANY_PHASE_VALUE, + NUMBER_OF_VOLTAGE_SAGS_IN_PHASE_L1_VALUE, + NUMBER_OF_VOLTAGE_SWELLS_IN_PHASE_L1_VALUE, + NUMBER_OF_VOLTAGE_SAGS_IN_PHASE_L2_VALUE, + NUMBER_OF_VOLTAGE_SWELLS_IN_PHASE_L2_VALUE, + NUMBER_OF_VOLTAGE_SAGS_IN_PHASE_L3_VALUE, + NUMBER_OF_VOLTAGE_SWELLS_IN_PHASE_L3_VALUE, + INSTANTANEOUS_CURRENT_L1_VALUE, + INSTANTANEOUS_CURRENT_VALUE); + + @Bean + @Profile("!smr43") + public DefinableLoadProfile definableLoadProfile( + final Calendar cal, final DynamicValues dynamicValues) { + final Integer classId = InterfaceClass.PROFILE_GENERIC.id(); + final ObisCode obisCode = new ObisCode(0, 1, 94, 31, 6, 255); + dynamicValues.setDefaultAttributeValue( + classId, + obisCode, + ProfileGenericAttribute.CAPTURE_PERIOD.attributeId(), + DataObject.newUInteger32Data(300)); + dynamicValues.setDefaultAttributeValue( + classId, + obisCode, + ProfileGenericAttribute.PROFILE_ENTRIES.attributeId(), + DataObject.newUInteger32Data(960)); + + return new DefinableLoadProfile(dynamicValues, cal, null, DEFAULT_CAPTURE_OBJECTS); + } +} diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/server/profile/Smr43Profile.java b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/server/profile/Smr43Profile.java index d22a2921eb8..f4a62acb2a7 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/server/profile/Smr43Profile.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/server/profile/Smr43Profile.java @@ -4,18 +4,60 @@ package org.opensmartgridplatform.simulator.protocol.dlms.server.profile; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.AVERAGE_ACTIVE_POWER_EXPORT_L1_VALUE; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.AVERAGE_ACTIVE_POWER_EXPORT_L2_VALUE; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.AVERAGE_ACTIVE_POWER_EXPORT_L3_VALUE; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.AVERAGE_ACTIVE_POWER_IMPORT_L1_VALUE; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.AVERAGE_ACTIVE_POWER_IMPORT_L2_VALUE; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.AVERAGE_ACTIVE_POWER_IMPORT_L3_VALUE; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.AVERAGE_CURRENT_L1_VALUE; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.AVERAGE_REACTIVE_POWER_EXPORT_L1_VALUE; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.AVERAGE_REACTIVE_POWER_EXPORT_L2_VALUE; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.AVERAGE_REACTIVE_POWER_EXPORT_L3_VALUE; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.AVERAGE_REACTIVE_POWER_IMPORT_L1_VALUE; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.AVERAGE_REACTIVE_POWER_IMPORT_L2_VALUE; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.AVERAGE_REACTIVE_POWER_IMPORT_L3_VALUE; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.AVERAGE_VOLTAGE_L1_VALUE; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.AVERAGE_VOLTAGE_L2_VALUE; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.AVERAGE_VOLTAGE_L3_VALUE; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.CDMA_DIAGNOSTIC_SIGNAL_QUALITY; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.CLOCK_TIME; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.INSTANTANEOUS_ACTIVE_POWER_EXPORT_L1_VALUE; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.INSTANTANEOUS_ACTIVE_POWER_IMPORT_L1_VALUE; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.INSTANTANEOUS_CURRENT_L1_VALUE; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.INSTANTANEOUS_CURRENT_VALUE; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.INSTANTANEOUS_VOLTAGE_L1_VALUE; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.INSTANTANEOUS_VOLTAGE_L2_VALUE; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.INSTANTANEOUS_VOLTAGE_L3_VALUE; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.NUMBER_OF_LONG_POWER_FAILURES_IN_ANY_PHASE_VALUE; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.NUMBER_OF_POWER_FAILURES_IN_ANY_PHASE_VALUE; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.NUMBER_OF_VOLTAGE_SAGS_IN_PHASE_L1_VALUE; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.NUMBER_OF_VOLTAGE_SAGS_IN_PHASE_L2_VALUE; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.NUMBER_OF_VOLTAGE_SAGS_IN_PHASE_L3_VALUE; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.NUMBER_OF_VOLTAGE_SWELLS_IN_PHASE_L1_VALUE; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.NUMBER_OF_VOLTAGE_SWELLS_IN_PHASE_L2_VALUE; +import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile.NUMBER_OF_VOLTAGE_SWELLS_IN_PHASE_L3_VALUE; + +import java.util.Arrays; import java.util.Calendar; import java.util.List; import java.util.stream.Collectors; import java.util.stream.IntStream; +import org.openmuc.jdlms.ObisCode; import org.openmuc.jdlms.datatypes.CosemDateTime; import org.openmuc.jdlms.datatypes.CosemDateTime.ClockStatus; +import org.openmuc.jdlms.datatypes.DataObject; +import org.opensmartgridplatform.dlms.interfaceclass.InterfaceClass; +import org.opensmartgridplatform.dlms.interfaceclass.attribute.ProfileGenericAttribute; import org.opensmartgridplatform.simulator.protocol.dlms.cosem.AuxiliaryEventLog; +import org.opensmartgridplatform.simulator.protocol.dlms.cosem.CaptureObject; +import org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile; import org.opensmartgridplatform.simulator.protocol.dlms.cosem.GsmDiagnostic; import org.opensmartgridplatform.simulator.protocol.dlms.cosem.GsmDiagnostic.AdjacentCellInfo; import org.opensmartgridplatform.simulator.protocol.dlms.cosem.GsmDiagnostic.CellInfo; import org.opensmartgridplatform.simulator.protocol.dlms.cosem.MBusClearStatusMask; import org.opensmartgridplatform.simulator.protocol.dlms.cosem.MBusReadStatus; +import org.opensmartgridplatform.simulator.protocol.dlms.util.DynamicValues; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -24,74 +66,110 @@ @Configuration @Profile("smr43") public class Smr43Profile { - @Value("${gsmdiagnostic.operator}") - private String gsmDiagnosticOperator; - - @Value("${gsmdiagnostic.status}") - private int gsmDiagnosticStatus; - - @Value("${gsmdiagnostic.csattachment}") - private int gsmDiagnosticCsAttachment; - - @Value("${gsmdiagnostic.psstatus}") - private int gsmDiagnosticPsStatus; - - @Value("${gsmdiagnostic.cellinfo.cellid}") - private int gsmDiagnosticCellInfoCellId; - - @Value("${gsmdiagnostic.cellinfo.locationid}") - private int gsmDiagnosticCellInfoLocationId; - - @Value("${gsmdiagnostic.cellinfo.signalquality}") - private short gsmDiagnosticCellInfoSignalQuality; - - @Value("${gsmdiagnostic.cellinfo.ber}") - private short gsmDiagnosticCellInfoBer; - - @Value("${gsmdiagnostic.cellinfo.mcc}") - private int gsmDiagnosticCellInfoMcc; - - @Value("${gsmdiagnostic.cellinfo.mnc}") - private int gsmDiagnosticCellInfoMnc; - - @Value("${gsmdiagnostic.cellinfo.channelnumber}") - private int gsmDiagnosticCellInfoChannelNumber; - - @Value("#{'${gsmdiagnostic.adjacentcells.cellids}'.split(',')}") - private List gsmDiagnosticAdjacentCellsCellIds; - - @Value("#{'${gsmdiagnostic.adjacentcells.signalqualities}'.split(',')}") - private List gsmDiagnosticAdjacentCellsSignalQualities; - - @Value("${gsmdiagnostic.capturetime.year}") - private int gsmDiagnosticYear; - - @Value("${gsmdiagnostic.capturetime.month}") - private int gsmDiagnosticMonth; - - @Value("${gsmdiagnostic.capturetime.dayOfMonth}") - private int gsmDiagnosticDayOfMonth; - - @Value("${gsmdiagnostic.capturetime.dayOfWeek}") - private int gsmDiagnosticDayOfWeek; - - @Value("${gsmdiagnostic.capturetime.hour}") - private int gsmDiagnosticHour; - - @Value("${gsmdiagnostic.capturetime.minute}") - private int gsmDiagnosticMinute; - - @Value("${gsmdiagnostic.capturetime.second}") - private int gsmDiagnosticSecond; - - @Value("${gsmdiagnostic.capturetime.hundredths}") - private int gsmDiagnosticHundredths; - - @Value("${gsmdiagnostic.capturetime.deviation}") - private int gsmDiagnosticDeviation; - - @Value("${gsmdiagnostic.capturetime.clockstatus}") - private byte gsmDiagnosticClockStatus; + private static final List DEFAULT_CAPTURE_OBJECTS = + Arrays.asList( + CLOCK_TIME, + CDMA_DIAGNOSTIC_SIGNAL_QUALITY, + INSTANTANEOUS_VOLTAGE_L1_VALUE, + INSTANTANEOUS_VOLTAGE_L2_VALUE, + INSTANTANEOUS_VOLTAGE_L3_VALUE, + AVERAGE_VOLTAGE_L1_VALUE, + AVERAGE_VOLTAGE_L2_VALUE, + AVERAGE_VOLTAGE_L3_VALUE, + INSTANTANEOUS_ACTIVE_POWER_IMPORT_L1_VALUE, + INSTANTANEOUS_ACTIVE_POWER_EXPORT_L1_VALUE, + AVERAGE_CURRENT_L1_VALUE, + AVERAGE_ACTIVE_POWER_IMPORT_L1_VALUE, + AVERAGE_ACTIVE_POWER_IMPORT_L2_VALUE, + AVERAGE_ACTIVE_POWER_IMPORT_L3_VALUE, + AVERAGE_ACTIVE_POWER_EXPORT_L1_VALUE, + AVERAGE_ACTIVE_POWER_EXPORT_L2_VALUE, + AVERAGE_ACTIVE_POWER_EXPORT_L3_VALUE, + AVERAGE_REACTIVE_POWER_IMPORT_L1_VALUE, + AVERAGE_REACTIVE_POWER_IMPORT_L2_VALUE, + AVERAGE_REACTIVE_POWER_IMPORT_L3_VALUE, + AVERAGE_REACTIVE_POWER_EXPORT_L1_VALUE, + AVERAGE_REACTIVE_POWER_EXPORT_L2_VALUE, + AVERAGE_REACTIVE_POWER_EXPORT_L3_VALUE, + NUMBER_OF_LONG_POWER_FAILURES_IN_ANY_PHASE_VALUE, + NUMBER_OF_POWER_FAILURES_IN_ANY_PHASE_VALUE, + NUMBER_OF_VOLTAGE_SAGS_IN_PHASE_L1_VALUE, + NUMBER_OF_VOLTAGE_SWELLS_IN_PHASE_L1_VALUE, + NUMBER_OF_VOLTAGE_SAGS_IN_PHASE_L2_VALUE, + NUMBER_OF_VOLTAGE_SWELLS_IN_PHASE_L2_VALUE, + NUMBER_OF_VOLTAGE_SAGS_IN_PHASE_L3_VALUE, + NUMBER_OF_VOLTAGE_SWELLS_IN_PHASE_L3_VALUE, + INSTANTANEOUS_CURRENT_L1_VALUE, + INSTANTANEOUS_CURRENT_VALUE); + + @Value("${cdmadiagnostic.operator}") + private String cdmaDiagnosticOperator; + + @Value("${cdmadiagnostic.status}") + private int cdmaDiagnosticStatus; + + @Value("${cdmadiagnostic.csattachment}") + private int cdmaDiagnosticCsAttachment; + + @Value("${cdmadiagnostic.psstatus}") + private int cdmaDiagnosticPsStatus; + + @Value("${cdmadiagnostic.cellinfo.cellid}") + private int cdmaDiagnosticCellInfoCellId; + + @Value("${cdmadiagnostic.cellinfo.locationid}") + private int cdmaDiagnosticCellInfoLocationId; + + @Value("${cdmadiagnostic.cellinfo.signalquality}") + private short cdmaDiagnosticCellInfoSignalQuality; + + @Value("${cdmadiagnostic.cellinfo.ber}") + private short cdmaDiagnosticCellInfoBer; + + @Value("${cdmadiagnostic.cellinfo.mcc}") + private int cdmaDiagnosticCellInfoMcc; + + @Value("${cdmadiagnostic.cellinfo.mnc}") + private int cdmaDiagnosticCellInfoMnc; + + @Value("${cdmadiagnostic.cellinfo.channelnumber}") + private int cdmaDiagnosticCellInfoChannelNumber; + + @Value("#{'${cdmadiagnostic.adjacentcells.cellids}'.split(',')}") + private List cdmaDiagnosticAdjacentCellsCellIds; + + @Value("#{'${cdmadiagnostic.adjacentcells.signalqualities}'.split(',')}") + private List cdmaDiagnosticAdjacentCellsSignalQualities; + + @Value("${cdmadiagnostic.capturetime.year}") + private int cdmaDiagnosticYear; + + @Value("${cdmadiagnostic.capturetime.month}") + private int cdmaDiagnosticMonth; + + @Value("${cdmadiagnostic.capturetime.dayOfMonth}") + private int cdmaDiagnosticDayOfMonth; + + @Value("${cdmadiagnostic.capturetime.dayOfWeek}") + private int cdmaDiagnosticDayOfWeek; + + @Value("${cdmadiagnostic.capturetime.hour}") + private int cdmaDiagnosticHour; + + @Value("${cdmadiagnostic.capturetime.minute}") + private int cdmaDiagnosticMinute; + + @Value("${cdmadiagnostic.capturetime.second}") + private int cdmaDiagnosticSecond; + + @Value("${cdmadiagnostic.capturetime.hundredths}") + private int cdmaDiagnosticHundredths; + + @Value("${cdmadiagnostic.capturetime.deviation}") + private int cdmaDiagnosticDeviation; + + @Value("${cdmadiagnostic.capturetime.clockstatus}") + private byte cdmaDiagnosticClockStatus; @Value("${clear.status.mask.mbus1}") private long clearStatusMaskMBus1; @@ -105,45 +183,65 @@ public class Smr43Profile { @Value("${clear.status.mask.mbus4}") private long clearStatusMaskMBus4; + @Bean + public DefinableLoadProfile definableLoadProfile( + final Calendar cal, final DynamicValues dynamicValues) { + final Integer classId = InterfaceClass.PROFILE_GENERIC.id(); + final ObisCode obisCode = new ObisCode(0, 1, 94, 31, 6, 255); + dynamicValues.setDefaultAttributeValue( + classId, + obisCode, + ProfileGenericAttribute.CAPTURE_PERIOD.attributeId(), + DataObject.newUInteger32Data(300)); + dynamicValues.setDefaultAttributeValue( + classId, + obisCode, + ProfileGenericAttribute.PROFILE_ENTRIES.attributeId(), + DataObject.newUInteger32Data(960)); + + return new DefinableLoadProfile(dynamicValues, cal, null, DEFAULT_CAPTURE_OBJECTS); + } + @Bean public GsmDiagnostic gsmCdmaDiagnostic() { final CellInfo cellInfo = new CellInfo( - this.gsmDiagnosticCellInfoCellId, - this.gsmDiagnosticCellInfoLocationId, - this.gsmDiagnosticCellInfoSignalQuality, - this.gsmDiagnosticCellInfoBer, - this.gsmDiagnosticCellInfoMcc, - this.gsmDiagnosticCellInfoMnc, - this.gsmDiagnosticCellInfoChannelNumber); + this.cdmaDiagnosticCellInfoCellId, + this.cdmaDiagnosticCellInfoLocationId, + this.cdmaDiagnosticCellInfoSignalQuality, + this.cdmaDiagnosticCellInfoBer, + this.cdmaDiagnosticCellInfoMcc, + this.cdmaDiagnosticCellInfoMnc, + this.cdmaDiagnosticCellInfoChannelNumber); final List adjacentCellInfos = - IntStream.range(0, this.gsmDiagnosticAdjacentCellsCellIds.size()) + IntStream.range(0, this.cdmaDiagnosticAdjacentCellsCellIds.size()) .mapToObj( i -> new AdjacentCellInfo( - this.gsmDiagnosticAdjacentCellsCellIds.get(i), - this.gsmDiagnosticAdjacentCellsSignalQualities.get(i))) + this.cdmaDiagnosticAdjacentCellsCellIds.get(i), + this.cdmaDiagnosticAdjacentCellsSignalQualities.get(i))) .collect(Collectors.toList()); final CosemDateTime captureTime = new CosemDateTime( - this.gsmDiagnosticYear, - this.gsmDiagnosticMonth, - this.gsmDiagnosticDayOfMonth, - this.gsmDiagnosticDayOfWeek, - this.gsmDiagnosticHour, - this.gsmDiagnosticMinute, - this.gsmDiagnosticSecond, - this.gsmDiagnosticHundredths, - this.gsmDiagnosticDeviation, - ClockStatus.clockStatusFrom(this.gsmDiagnosticClockStatus).toArray(new ClockStatus[0])); + this.cdmaDiagnosticYear, + this.cdmaDiagnosticMonth, + this.cdmaDiagnosticDayOfMonth, + this.cdmaDiagnosticDayOfWeek, + this.cdmaDiagnosticHour, + this.cdmaDiagnosticMinute, + this.cdmaDiagnosticSecond, + this.cdmaDiagnosticHundredths, + this.cdmaDiagnosticDeviation, + ClockStatus.clockStatusFrom(this.cdmaDiagnosticClockStatus) + .toArray(new ClockStatus[0])); return new GsmDiagnostic( "0.1.25.6.0.255", - this.gsmDiagnosticOperator, - this.gsmDiagnosticStatus, - this.gsmDiagnosticCsAttachment, - this.gsmDiagnosticPsStatus, + this.cdmaDiagnosticOperator, + this.cdmaDiagnosticStatus, + this.cdmaDiagnosticCsAttachment, + this.cdmaDiagnosticPsStatus, cellInfo, adjacentCellInfos, captureTime); diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/server/profile/Smr51Profile.java b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/server/profile/Smr51Profile.java index 98e74deb9d2..59d9f4cb6de 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/server/profile/Smr51Profile.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/server/profile/Smr51Profile.java @@ -5,15 +5,7 @@ package org.opensmartgridplatform.simulator.protocol.dlms.server.profile; import java.util.Calendar; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.IntStream; -import org.openmuc.jdlms.datatypes.CosemDateTime; -import org.openmuc.jdlms.datatypes.CosemDateTime.ClockStatus; import org.opensmartgridplatform.simulator.protocol.dlms.cosem.AuxiliaryEventLog; -import org.opensmartgridplatform.simulator.protocol.dlms.cosem.GsmDiagnostic; -import org.opensmartgridplatform.simulator.protocol.dlms.cosem.GsmDiagnostic.AdjacentCellInfo; -import org.opensmartgridplatform.simulator.protocol.dlms.cosem.GsmDiagnostic.CellInfo; import org.opensmartgridplatform.simulator.protocol.dlms.cosem.MBusClearStatusMask; import org.opensmartgridplatform.simulator.protocol.dlms.cosem.MBusReadStatus; import org.springframework.beans.factory.annotation.Value; @@ -24,74 +16,6 @@ @Configuration @Profile("smr51") public class Smr51Profile { - @Value("${gsmdiagnostic.operator}") - private String gsmDiagnosticOperator; - - @Value("${gsmdiagnostic.status}") - private int gsmDiagnosticStatus; - - @Value("${gsmdiagnostic.csattachment}") - private int gsmDiagnosticCsAttachment; - - @Value("${gsmdiagnostic.psstatus}") - private int gsmDiagnosticPsStatus; - - @Value("${gsmdiagnostic.cellinfo.cellid}") - private int gsmDiagnosticCellInfoCellId; - - @Value("${gsmdiagnostic.cellinfo.locationid}") - private int gsmDiagnosticCellInfoLocationId; - - @Value("${gsmdiagnostic.cellinfo.signalquality}") - private short gsmDiagnosticCellInfoSignalQuality; - - @Value("${gsmdiagnostic.cellinfo.ber}") - private short gsmDiagnosticCellInfoBer; - - @Value("${gsmdiagnostic.cellinfo.mcc}") - private int gsmDiagnosticCellInfoMcc; - - @Value("${gsmdiagnostic.cellinfo.mnc}") - private int gsmDiagnosticCellInfoMnc; - - @Value("${gsmdiagnostic.cellinfo.channelnumber}") - private int gsmDiagnosticCellInfoChannelNumber; - - @Value("#{'${gsmdiagnostic.adjacentcells.cellids}'.split(',')}") - private List gsmDiagnosticAdjacentCellsCellIds; - - @Value("#{'${gsmdiagnostic.adjacentcells.signalqualities}'.split(',')}") - private List gsmDiagnosticAdjacentCellsSignalQualities; - - @Value("${gsmdiagnostic.capturetime.year}") - private int gsmDiagnosticYear; - - @Value("${gsmdiagnostic.capturetime.month}") - private int gsmDiagnosticMonth; - - @Value("${gsmdiagnostic.capturetime.dayOfMonth}") - private int gsmDiagnosticDayOfMonth; - - @Value("${gsmdiagnostic.capturetime.dayOfWeek}") - private int gsmDiagnosticDayOfWeek; - - @Value("${gsmdiagnostic.capturetime.hour}") - private int gsmDiagnosticHour; - - @Value("${gsmdiagnostic.capturetime.minute}") - private int gsmDiagnosticMinute; - - @Value("${gsmdiagnostic.capturetime.second}") - private int gsmDiagnosticSecond; - - @Value("${gsmdiagnostic.capturetime.hundredths}") - private int gsmDiagnosticHundredths; - - @Value("${gsmdiagnostic.capturetime.deviation}") - private int gsmDiagnosticDeviation; - - @Value("${gsmdiagnostic.capturetime.clockstatus}") - private byte gsmDiagnosticClockStatus; @Value("${clear.status.mask.mbus1}") private long clearStatusMaskMBus1; @@ -105,51 +29,6 @@ public class Smr51Profile { @Value("${clear.status.mask.mbus4}") private long clearStatusMaskMBus4; - @Bean - public GsmDiagnostic gsmGprsDiagnostic() { - final CellInfo cellInfo = - new CellInfo( - this.gsmDiagnosticCellInfoCellId, - this.gsmDiagnosticCellInfoLocationId, - this.gsmDiagnosticCellInfoSignalQuality, - this.gsmDiagnosticCellInfoBer, - this.gsmDiagnosticCellInfoMcc, - this.gsmDiagnosticCellInfoMnc, - this.gsmDiagnosticCellInfoChannelNumber); - - final List adjacentCellInfos = - IntStream.range(0, this.gsmDiagnosticAdjacentCellsCellIds.size()) - .mapToObj( - i -> - new AdjacentCellInfo( - this.gsmDiagnosticAdjacentCellsCellIds.get(i), - this.gsmDiagnosticAdjacentCellsSignalQualities.get(i))) - .collect(Collectors.toList()); - - final CosemDateTime captureTime = - new CosemDateTime( - this.gsmDiagnosticYear, - this.gsmDiagnosticMonth, - this.gsmDiagnosticDayOfMonth, - this.gsmDiagnosticDayOfWeek, - this.gsmDiagnosticHour, - this.gsmDiagnosticMinute, - this.gsmDiagnosticSecond, - this.gsmDiagnosticHundredths, - this.gsmDiagnosticDeviation, - ClockStatus.clockStatusFrom(this.gsmDiagnosticClockStatus).toArray(new ClockStatus[0])); - - return new GsmDiagnostic( - "0.0.25.6.0.255", - this.gsmDiagnosticOperator, - this.gsmDiagnosticStatus, - this.gsmDiagnosticCsAttachment, - this.gsmDiagnosticPsStatus, - cellInfo, - adjacentCellInfos, - captureTime); - } - @Bean public AuxiliaryEventLog auxiliaryEventLog(final Calendar cal) { return new AuxiliaryEventLog(cal); diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/server/profile/Smr52Profile.java b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/server/profile/Smr52Profile.java index ba05c5a00da..e3f7313c936 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/server/profile/Smr52Profile.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/server/profile/Smr52Profile.java @@ -7,12 +7,20 @@ import static org.opensmartgridplatform.simulator.protocol.dlms.cosem.AlarmObject.ALARM_OBJECT_2; import java.util.Calendar; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; import org.openmuc.jdlms.ObisCode; +import org.openmuc.jdlms.datatypes.CosemDateTime; +import org.openmuc.jdlms.datatypes.CosemDateTime.ClockStatus; import org.openmuc.jdlms.datatypes.DataObject; import org.opensmartgridplatform.dlms.interfaceclass.InterfaceClass; import org.opensmartgridplatform.dlms.interfaceclass.attribute.DataAttribute; import org.opensmartgridplatform.simulator.protocol.dlms.cosem.AlarmFilter; import org.opensmartgridplatform.simulator.protocol.dlms.cosem.AlarmObject; +import org.opensmartgridplatform.simulator.protocol.dlms.cosem.GsmDiagnostic; +import org.opensmartgridplatform.simulator.protocol.dlms.cosem.GsmDiagnostic.AdjacentCellInfo; +import org.opensmartgridplatform.simulator.protocol.dlms.cosem.GsmDiagnostic.CellInfo; import org.opensmartgridplatform.simulator.protocol.dlms.cosem.PowerQualityExtendedEventLog; import org.opensmartgridplatform.simulator.protocol.dlms.util.DynamicValues; import org.springframework.beans.factory.annotation.Value; @@ -29,6 +37,75 @@ public class Smr52Profile { @Value("${alarmfilter2.value}") private int alarmFilter2Value; + @Value("${ltediagnostic.operator}") + private String lteDiagnosticOperator; + + @Value("${ltediagnostic.status}") + private int lteDiagnosticStatus; + + @Value("${ltediagnostic.csattachment}") + private int lteDiagnosticCsAttachment; + + @Value("${ltediagnostic.psstatus}") + private int lteDiagnosticPsStatus; + + @Value("${ltediagnostic.cellinfo.cellid}") + private int lteDiagnosticCellInfoCellId; + + @Value("${ltediagnostic.cellinfo.locationid}") + private int lteDiagnosticCellInfoLocationId; + + @Value("${ltediagnostic.cellinfo.signalquality}") + private short lteDiagnosticCellInfoSignalQuality; + + @Value("${ltediagnostic.cellinfo.ber}") + private short lteDiagnosticCellInfoBer; + + @Value("${ltediagnostic.cellinfo.mcc}") + private int lteDiagnosticCellInfoMcc; + + @Value("${ltediagnostic.cellinfo.mnc}") + private int lteDiagnosticCellInfoMnc; + + @Value("${ltediagnostic.cellinfo.channelnumber}") + private int lteDiagnosticCellInfoChannelNumber; + + @Value("#{'${ltediagnostic.adjacentcells.cellids}'.split(',')}") + private List lteDiagnosticAdjacentCellsCellIds; + + @Value("#{'${ltediagnostic.adjacentcells.signalqualities}'.split(',')}") + private List lteDiagnosticAdjacentCellsSignalQualities; + + @Value("${ltediagnostic.capturetime.year}") + private int lteDiagnosticYear; + + @Value("${ltediagnostic.capturetime.month}") + private int lteDiagnosticMonth; + + @Value("${ltediagnostic.capturetime.dayOfMonth}") + private int lteDiagnosticDayOfMonth; + + @Value("${ltediagnostic.capturetime.dayOfWeek}") + private int lteDiagnosticDayOfWeek; + + @Value("${ltediagnostic.capturetime.hour}") + private int lteDiagnosticHour; + + @Value("${ltediagnostic.capturetime.minute}") + private int lteDiagnosticMinute; + + @Value("${ltediagnostic.capturetime.second}") + private int lteDiagnosticSecond; + + @Value("${ltediagnostic.capturetime.hundredths}") + private int lteDiagnosticHundredths; + + @Value("${ltediagnostic.capturetime.deviation}") + private int lteDiagnosticDeviation; + + @Value("${ltediagnostic.capturetime.clockstatus}") + private byte lteDiagnosticClockStatus; + @Bean public AlarmObject alarmObject2(final DynamicValues dynamicValues) { dynamicValues.setDefaultAttributeValue( @@ -48,4 +125,49 @@ public AlarmFilter alarmFilter2() { public PowerQualityExtendedEventLog powerQualityExtendedEventLog(final Calendar cal) { return new PowerQualityExtendedEventLog(cal); } + + @Bean + public GsmDiagnostic gsmLteDiagnostic() { + final CellInfo cellInfo = + new CellInfo( + this.lteDiagnosticCellInfoCellId, + this.lteDiagnosticCellInfoLocationId, + this.lteDiagnosticCellInfoSignalQuality, + this.lteDiagnosticCellInfoBer, + this.lteDiagnosticCellInfoMcc, + this.lteDiagnosticCellInfoMnc, + this.lteDiagnosticCellInfoChannelNumber); + + final List adjacentCellInfos = + IntStream.range(0, this.lteDiagnosticAdjacentCellsCellIds.size()) + .mapToObj( + i -> + new AdjacentCellInfo( + this.lteDiagnosticAdjacentCellsCellIds.get(i), + this.lteDiagnosticAdjacentCellsSignalQualities.get(i))) + .collect(Collectors.toList()); + + final CosemDateTime captureTime = + new CosemDateTime( + this.lteDiagnosticYear, + this.lteDiagnosticMonth, + this.lteDiagnosticDayOfMonth, + this.lteDiagnosticDayOfWeek, + this.lteDiagnosticHour, + this.lteDiagnosticMinute, + this.lteDiagnosticSecond, + this.lteDiagnosticHundredths, + this.lteDiagnosticDeviation, + ClockStatus.clockStatusFrom(this.lteDiagnosticClockStatus).toArray(new ClockStatus[0])); + + return new GsmDiagnostic( + "0.2.25.6.0.255", + this.lteDiagnosticOperator, + this.lteDiagnosticStatus, + this.lteDiagnosticCsAttachment, + this.lteDiagnosticPsStatus, + cellInfo, + adjacentCellInfos, + captureTime); + } } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/server/profile/Smr5Profile.java b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/server/profile/Smr5Profile.java index e5f9843209d..875b67f86b2 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/server/profile/Smr5Profile.java +++ b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/java/org/opensmartgridplatform/simulator/protocol/dlms/server/profile/Smr5Profile.java @@ -4,8 +4,12 @@ package org.opensmartgridplatform.simulator.protocol.dlms.server.profile; +import java.util.Arrays; import java.util.Calendar; import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ArrayUtils; import org.bouncycastle.util.encoders.Hex; import org.openmuc.jdlms.ObisCode; @@ -14,9 +18,15 @@ import org.openmuc.jdlms.datatypes.CosemDateTime.ClockStatus; import org.openmuc.jdlms.datatypes.DataObject; import org.opensmartgridplatform.dlms.interfaceclass.InterfaceClass; +import org.opensmartgridplatform.dlms.interfaceclass.attribute.ProfileGenericAttribute; +import org.opensmartgridplatform.simulator.protocol.dlms.cosem.CaptureObject; import org.opensmartgridplatform.simulator.protocol.dlms.cosem.ConfigurationObject; +import org.opensmartgridplatform.simulator.protocol.dlms.cosem.DefinableLoadProfile; import org.opensmartgridplatform.simulator.protocol.dlms.cosem.DoubleLongUnsignedExtendedRegister; import org.opensmartgridplatform.simulator.protocol.dlms.cosem.EMonthlyBillingValuesPeriod1SMR5; +import org.opensmartgridplatform.simulator.protocol.dlms.cosem.GsmDiagnostic; +import org.opensmartgridplatform.simulator.protocol.dlms.cosem.GsmDiagnostic.AdjacentCellInfo; +import org.opensmartgridplatform.simulator.protocol.dlms.cosem.GsmDiagnostic.CellInfo; import org.opensmartgridplatform.simulator.protocol.dlms.cosem.MBusDailyBillingValuesPeriod1SMR5; import org.opensmartgridplatform.simulator.protocol.dlms.cosem.MBusDriverActiveFirmwareIdentifier; import org.opensmartgridplatform.simulator.protocol.dlms.cosem.MBusDriverActiveFirmwareSignature; @@ -38,7 +48,67 @@ @Configuration @Profile("smr5") +@Slf4j public class Smr5Profile { + + private static final int MAX_NUMBER_OF_CAPTURE_OBJECTS = 14; + private static final List POWER_QUALITY_1_CAPTURE_OBJECTS = + Arrays.asList( + PowerQualityProfile1.CLOCK_TIME, + PowerQualityProfile1.AVERAGE_ACTIVE_POWER_IMPORT_L1_VALUE, + PowerQualityProfile1.AVERAGE_ACTIVE_POWER_IMPORT_L2_VALUE, + PowerQualityProfile1.AVERAGE_ACTIVE_POWER_IMPORT_L3_VALUE, + PowerQualityProfile1.AVERAGE_ACTIVE_POWER_EXPORT_L1_VALUE, + PowerQualityProfile1.AVERAGE_ACTIVE_POWER_EXPORT_L2_VALUE, + PowerQualityProfile1.AVERAGE_ACTIVE_POWER_EXPORT_L3_VALUE, + PowerQualityProfile1.AVERAGE_REACTIVE_POWER_IMPORT_L1_VALUE, + PowerQualityProfile1.AVERAGE_REACTIVE_POWER_IMPORT_L2_VALUE, + PowerQualityProfile1.AVERAGE_REACTIVE_POWER_IMPORT_L3_VALUE, + PowerQualityProfile1.AVERAGE_REACTIVE_POWER_EXPORT_L1_VALUE, + PowerQualityProfile1.AVERAGE_REACTIVE_POWER_EXPORT_L2_VALUE, + PowerQualityProfile1.AVERAGE_REACTIVE_POWER_EXPORT_L3_VALUE); + + private static final List POWER_QUALITY_2_CAPTURE_OBJECTS = + Arrays.asList( + PowerQualityProfile2.CLOCK_TIME, + PowerQualityProfile2.AVERAGE_VOLTAGE_L1_VALUE, + PowerQualityProfile2.AVERAGE_VOLTAGE_L2_VALUE, + PowerQualityProfile2.AVERAGE_VOLTAGE_L3_VALUE, + PowerQualityProfile2.INSTANTANEOUS_VOLTAGE_L1_VALUE, + PowerQualityProfile2.AVERAGE_CURRENT_L1_VALUE, + PowerQualityProfile2.AVERAGE_CURRENT_L2_VALUE, + PowerQualityProfile2.AVERAGE_CURRENT_L3_VALUE, + PowerQualityProfile2.INSTANTANEOUS_CURRENT_L1_VALUE, + PowerQualityProfile2.INSTANTANEOUS_ACTIVE_POWER_IMPORT_VALUE, + PowerQualityProfile2.INSTANTANEOUS_ACTIVE_POWER_EXPORT_VALUE, + PowerQualityProfile2.INSTANTANEOUS_ACTIVE_POWER_IMPORT_L1_VALUE, + PowerQualityProfile2.INSTANTANEOUS_ACTIVE_POWER_IMPORT_L2_VALUE, + PowerQualityProfile2.INSTANTANEOUS_ACTIVE_POWER_IMPORT_L3_VALUE, + PowerQualityProfile2.INSTANTANEOUS_ACTIVE_POWER_EXPORT_L1_VALUE, + PowerQualityProfile2.INSTANTANEOUS_ACTIVE_POWER_EXPORT_L2_VALUE, + PowerQualityProfile2.INSTANTANEOUS_ACTIVE_POWER_EXPORT_L3_VALUE); + + private static final List DEFINABLE_LOAD_CAPTURE_OBJECTS = + Arrays.asList( + DefinableLoadProfile.CLOCK_TIME, + DefinableLoadProfile.CDMA_DIAGNOSTIC_SIGNAL_QUALITY, + DefinableLoadProfile.GPRS_DIAGNOSTIC_SIGNAL_QUALITY, + DefinableLoadProfile.CDMA_DIAGNOSTIC_BER, + DefinableLoadProfile.GPRS_DIAGNOSTIC_BER, + DefinableLoadProfile.MBUS_CLIENT_SETUP_CHN1_VALUE, + DefinableLoadProfile.MBUS_CLIENT_SETUP_CHN2_VALUE, + DefinableLoadProfile.MBUS_DIAGNOSTIC_RSSI_CHN1_VALUE, + DefinableLoadProfile.MBUS_DIAGNOSTIC_RSSI_CHN2_VALUE, + DefinableLoadProfile.MBUS_DIAGNOSTIC_FCS_NOK_CHN1_VALUE, + DefinableLoadProfile.MBUS_DIAGNOSTIC_FCS_NOK_CHN2_VALUE, + DefinableLoadProfile.NUMBER_OF_VOLTAGE_SAGS_IN_PHASE_L1_VALUE, + DefinableLoadProfile.NUMBER_OF_VOLTAGE_SAGS_IN_PHASE_L2_VALUE, + DefinableLoadProfile.NUMBER_OF_VOLTAGE_SAGS_IN_PHASE_L3_VALUE, + DefinableLoadProfile.NUMBER_OF_VOLTAGE_SWELLS_IN_PHASE_L1_VALUE, + DefinableLoadProfile.NUMBER_OF_VOLTAGE_SWELLS_IN_PHASE_L2_VALUE, + DefinableLoadProfile.NUMBER_OF_VOLTAGE_SWELLS_IN_PHASE_L3_VALUE, + DefinableLoadProfile.NUMBER_OF_POWER_FAILURES_IN_ANY_PHASE_VALUE); + @Value("${firmware.mbusdriver.active.identifier}") private String mBusDriverActiveFirmwareIdentifier; @@ -132,6 +202,144 @@ public class Smr5Profile { @Value("${command.hourlymeterreads.mbus.capturetime.clockstatus}") private byte mBusCaptureTimeStatus; + @Value("${cdmadiagnostic.operator}") + private String cdmaDiagnosticOperator; + + @Value("${cdmadiagnostic.status}") + private int cdmaDiagnosticStatus; + + @Value("${cdmadiagnostic.csattachment}") + private int cdmaDiagnosticCsAttachment; + + @Value("${cdmadiagnostic.psstatus}") + private int cdmaDiagnosticPsStatus; + + @Value("${cdmadiagnostic.cellinfo.cellid}") + private int cdmaDiagnosticCellInfoCellId; + + @Value("${cdmadiagnostic.cellinfo.locationid}") + private int cdmaDiagnosticCellInfoLocationId; + + @Value("${cdmadiagnostic.cellinfo.signalquality}") + private short cdmaDiagnosticCellInfoSignalQuality; + + @Value("${cdmadiagnostic.cellinfo.ber}") + private short cdmaDiagnosticCellInfoBer; + + @Value("${cdmadiagnostic.cellinfo.mcc}") + private int cdmaDiagnosticCellInfoMcc; + + @Value("${cdmadiagnostic.cellinfo.mnc}") + private int cdmaDiagnosticCellInfoMnc; + + @Value("${cdmadiagnostic.cellinfo.channelnumber}") + private int cdmaDiagnosticCellInfoChannelNumber; + + @Value("#{'${cdmadiagnostic.adjacentcells.cellids}'.split(',')}") + private List cdmaDiagnosticAdjacentCellsCellIds; + + @Value("#{'${cdmadiagnostic.adjacentcells.signalqualities}'.split(',')}") + private List cdmaDiagnosticAdjacentCellsSignalQualities; + + @Value("${cdmadiagnostic.capturetime.year}") + private int cdmaDiagnosticYear; + + @Value("${cdmadiagnostic.capturetime.month}") + private int cdmaDiagnosticMonth; + + @Value("${cdmadiagnostic.capturetime.dayOfMonth}") + private int cdmaDiagnosticDayOfMonth; + + @Value("${cdmadiagnostic.capturetime.dayOfWeek}") + private int cdmaDiagnosticDayOfWeek; + + @Value("${cdmadiagnostic.capturetime.hour}") + private int cdmaDiagnosticHour; + + @Value("${cdmadiagnostic.capturetime.minute}") + private int cdmaDiagnosticMinute; + + @Value("${cdmadiagnostic.capturetime.second}") + private int cdmaDiagnosticSecond; + + @Value("${cdmadiagnostic.capturetime.hundredths}") + private int cdmaDiagnosticHundredths; + + @Value("${cdmadiagnostic.capturetime.deviation}") + private int cdmaDiagnosticDeviation; + + @Value("${cdmadiagnostic.capturetime.clockstatus}") + private byte cdmaDiagnosticClockStatus; + + @Value("${gprsdiagnostic.operator}") + private String gprsDiagnosticOperator; + + @Value("${gprsdiagnostic.status}") + private int gprsDiagnosticStatus; + + @Value("${gprsdiagnostic.csattachment}") + private int gprsDiagnosticCsAttachment; + + @Value("${gprsdiagnostic.psstatus}") + private int gprsDiagnosticPsStatus; + + @Value("${gprsdiagnostic.cellinfo.cellid}") + private int gprsDiagnosticCellInfoCellId; + + @Value("${gprsdiagnostic.cellinfo.locationid}") + private int gprsDiagnosticCellInfoLocationId; + + @Value("${gprsdiagnostic.cellinfo.signalquality}") + private short gprsDiagnosticCellInfoSignalQuality; + + @Value("${gprsdiagnostic.cellinfo.ber}") + private short gprsDiagnosticCellInfoBer; + + @Value("${gprsdiagnostic.cellinfo.mcc}") + private int gprsDiagnosticCellInfoMcc; + + @Value("${gprsdiagnostic.cellinfo.mnc}") + private int gprsDiagnosticCellInfoMnc; + + @Value("${gprsdiagnostic.cellinfo.channelnumber}") + private int gprsDiagnosticCellInfoChannelNumber; + + @Value("#{'${gprsdiagnostic.adjacentcells.cellids}'.split(',')}") + private List gprsDiagnosticAdjacentCellsCellIds; + + @Value("#{'${gprsdiagnostic.adjacentcells.signalqualities}'.split(',')}") + private List gprsDiagnosticAdjacentCellsSignalQualities; + + @Value("${gprsdiagnostic.capturetime.year}") + private int gprsDiagnosticYear; + + @Value("${gprsdiagnostic.capturetime.month}") + private int gprsDiagnosticMonth; + + @Value("${gprsdiagnostic.capturetime.dayOfMonth}") + private int gprsDiagnosticDayOfMonth; + + @Value("${gprsdiagnostic.capturetime.dayOfWeek}") + private int gprsDiagnosticDayOfWeek; + + @Value("${gprsdiagnostic.capturetime.hour}") + private int gprsDiagnosticHour; + + @Value("${gprsdiagnostic.capturetime.minute}") + private int gprsDiagnosticMinute; + + @Value("${gprsdiagnostic.capturetime.second}") + private int gprsDiagnosticSecond; + + @Value("${gprsdiagnostic.capturetime.hundredths}") + private int gprsDiagnosticHundredths; + + @Value("${gprsdiagnostic.capturetime.deviation}") + private int gprsDiagnosticDeviation; + + @Value("${gprsdiagnostic.capturetime.clockstatus}") + private byte gprsDiagnosticClockStatus; + @Bean public InvocationCounter invocationCounter() { return new InvocationCounter(this.invocationCounter); @@ -155,13 +363,42 @@ public PowerQualityEventLog powerQualityEventLog(final Calendar cal) { } @Bean - public PowerQualityProfile1 powerQualityProfile1(final Calendar cal) { - return new PowerQualityProfile1(cal); + public PowerQualityProfile1 powerQualityProfile1( + final DynamicValues dynamicValues, final Calendar cal) { + final Integer classId = InterfaceClass.PROFILE_GENERIC.id(); + final ObisCode obisCode = new ObisCode(PowerQualityProfile1.LOGICAL_NAME); + dynamicValues.setDefaultAttributeValue( + classId, + obisCode, + ProfileGenericAttribute.CAPTURE_PERIOD.attributeId(), + DataObject.newUInteger32Data(PowerQualityProfile1.CAPTURE_PERIOD)); + dynamicValues.setDefaultAttributeValue( + classId, + obisCode, + ProfileGenericAttribute.PROFILE_ENTRIES.attributeId(), + DataObject.newUInteger32Data(PowerQualityProfile1.PROFILE_ENTRIES)); + return new PowerQualityProfile1( + dynamicValues, cal, MAX_NUMBER_OF_CAPTURE_OBJECTS, POWER_QUALITY_1_CAPTURE_OBJECTS); } @Bean - public PowerQualityProfile2 powerQualityProfile2(final Calendar cal) { - return new PowerQualityProfile2(cal); + public PowerQualityProfile2 powerQualityProfile2( + final DynamicValues dynamicValues, final Calendar cal) { + log.info("------------ Create bean powerQualityProfile2"); + final Integer classId = InterfaceClass.PROFILE_GENERIC.id(); + final ObisCode obisCode = new ObisCode(PowerQualityProfile2.LOGICAL_NAME); + dynamicValues.setDefaultAttributeValue( + classId, + obisCode, + ProfileGenericAttribute.CAPTURE_PERIOD.attributeId(), + DataObject.newUInteger32Data(PowerQualityProfile2.CAPTURE_PERIOD)); + dynamicValues.setDefaultAttributeValue( + classId, + obisCode, + ProfileGenericAttribute.PROFILE_ENTRIES.attributeId(), + DataObject.newUInteger32Data(PowerQualityProfile2.PROFILE_ENTRIES)); + return new PowerQualityProfile2( + dynamicValues, cal, MAX_NUMBER_OF_CAPTURE_OBJECTS, POWER_QUALITY_2_CAPTURE_OBJECTS); } @Bean @@ -365,4 +602,114 @@ public EMonthlyBillingValuesPeriod1SMR5 eMonthlyBillingValuesPeriod1SMR5(final C SingleActionScheduler phaseOutageTestScheduler() { return new SingleActionScheduler("0.0.15.1.4.255"); } + + @Bean + public DefinableLoadProfile definableLoadProfile( + final Calendar cal, final DynamicValues dynamicValues) { + final Integer classId = InterfaceClass.PROFILE_GENERIC.id(); + final ObisCode obisCode = new ObisCode(0, 1, 94, 31, 6, 255); + dynamicValues.setDefaultAttributeValue( + classId, + obisCode, + ProfileGenericAttribute.CAPTURE_PERIOD.attributeId(), + DataObject.newUInteger32Data(300)); + dynamicValues.setDefaultAttributeValue( + classId, + obisCode, + ProfileGenericAttribute.PROFILE_ENTRIES.attributeId(), + DataObject.newUInteger32Data(960)); + + return new DefinableLoadProfile( + dynamicValues, cal, MAX_NUMBER_OF_CAPTURE_OBJECTS, DEFINABLE_LOAD_CAPTURE_OBJECTS); + } + + @Bean + public GsmDiagnostic gsmCdmaDiagnostic() { + final CellInfo cellInfo = + new CellInfo( + this.cdmaDiagnosticCellInfoCellId, + this.cdmaDiagnosticCellInfoLocationId, + this.cdmaDiagnosticCellInfoSignalQuality, + this.cdmaDiagnosticCellInfoBer, + this.cdmaDiagnosticCellInfoMcc, + this.cdmaDiagnosticCellInfoMnc, + this.cdmaDiagnosticCellInfoChannelNumber); + + final List adjacentCellInfos = + IntStream.range(0, this.cdmaDiagnosticAdjacentCellsCellIds.size()) + .mapToObj( + i -> + new AdjacentCellInfo( + this.cdmaDiagnosticAdjacentCellsCellIds.get(i), + this.cdmaDiagnosticAdjacentCellsSignalQualities.get(i))) + .collect(Collectors.toList()); + + final CosemDateTime captureTime = + new CosemDateTime( + this.cdmaDiagnosticYear, + this.cdmaDiagnosticMonth, + this.cdmaDiagnosticDayOfMonth, + this.cdmaDiagnosticDayOfWeek, + this.cdmaDiagnosticHour, + this.cdmaDiagnosticMinute, + this.cdmaDiagnosticSecond, + this.cdmaDiagnosticHundredths, + this.cdmaDiagnosticDeviation, + ClockStatus.clockStatusFrom(this.cdmaDiagnosticClockStatus) + .toArray(new ClockStatus[0])); + return new GsmDiagnostic( + "0.1.25.6.0.255", + this.cdmaDiagnosticOperator, + this.cdmaDiagnosticStatus, + this.cdmaDiagnosticCsAttachment, + this.cdmaDiagnosticPsStatus, + cellInfo, + adjacentCellInfos, + captureTime); + } + + @Bean + public GsmDiagnostic gsmGprsDiagnostic() { + final CellInfo cellInfo = + new CellInfo( + this.gprsDiagnosticCellInfoCellId, + this.gprsDiagnosticCellInfoLocationId, + this.gprsDiagnosticCellInfoSignalQuality, + this.gprsDiagnosticCellInfoBer, + this.gprsDiagnosticCellInfoMcc, + this.gprsDiagnosticCellInfoMnc, + this.gprsDiagnosticCellInfoChannelNumber); + + final List adjacentCellInfos = + IntStream.range(0, this.gprsDiagnosticAdjacentCellsCellIds.size()) + .mapToObj( + i -> + new AdjacentCellInfo( + this.gprsDiagnosticAdjacentCellsCellIds.get(i), + this.gprsDiagnosticAdjacentCellsSignalQualities.get(i))) + .collect(Collectors.toList()); + + final CosemDateTime captureTime = + new CosemDateTime( + this.gprsDiagnosticYear, + this.gprsDiagnosticMonth, + this.gprsDiagnosticDayOfMonth, + this.gprsDiagnosticDayOfWeek, + this.gprsDiagnosticHour, + this.gprsDiagnosticMinute, + this.gprsDiagnosticSecond, + this.gprsDiagnosticHundredths, + this.gprsDiagnosticDeviation, + ClockStatus.clockStatusFrom(this.gprsDiagnosticClockStatus) + .toArray(new ClockStatus[0])); + return new GsmDiagnostic( + "0.0.25.6.0.255", + this.gprsDiagnosticOperator, + this.gprsDiagnosticStatus, + this.gprsDiagnosticCsAttachment, + this.gprsDiagnosticPsStatus, + cellInfo, + adjacentCellInfos, + captureTime); + } } diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/resources/application-smr43.properties b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/resources/application-smr43.properties index 1027b348564..e27212fc50a 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/resources/application-smr43.properties +++ b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/resources/application-smr43.properties @@ -1,26 +1,26 @@ -gsmdiagnostic.operator=Utility Connect -gsmdiagnostic.status=5 -gsmdiagnostic.csattachment=0 -gsmdiagnostic.psstatus=6 -gsmdiagnostic.cellinfo.cellid=77 -gsmdiagnostic.cellinfo.locationid=2230 -gsmdiagnostic.cellinfo.signalquality=13 -gsmdiagnostic.cellinfo.ber=6 -gsmdiagnostic.cellinfo.mnc=204 -gsmdiagnostic.cellinfo.mcc=66 -gsmdiagnostic.cellinfo.channelnumber=107 -gsmdiagnostic.adjacentcells.cellids=93,94 -gsmdiagnostic.adjacentcells.signalqualities=11,12 -gsmdiagnostic.capturetime.year=2021 -gsmdiagnostic.capturetime.month=4 -gsmdiagnostic.capturetime.dayOfMonth=13 -gsmdiagnostic.capturetime.dayOfWeek=1 -gsmdiagnostic.capturetime.hour=8 -gsmdiagnostic.capturetime.minute=45 -gsmdiagnostic.capturetime.second=0 -gsmdiagnostic.capturetime.hundredths=0 -gsmdiagnostic.capturetime.deviation=-60 -gsmdiagnostic.capturetime.clockstatus=0 +cdmadiagnostic.operator=Utility Connect +cdmadiagnostic.status=5 +cdmadiagnostic.csattachment=0 +cdmadiagnostic.psstatus=6 +cdmadiagnostic.cellinfo.cellid=77 +cdmadiagnostic.cellinfo.locationid=2230 +cdmadiagnostic.cellinfo.signalquality=13 +cdmadiagnostic.cellinfo.ber=6 +cdmadiagnostic.cellinfo.mnc=204 +cdmadiagnostic.cellinfo.mcc=66 +cdmadiagnostic.cellinfo.channelnumber=107 +cdmadiagnostic.adjacentcells.cellids=93,94 +cdmadiagnostic.adjacentcells.signalqualities=11,12 +cdmadiagnostic.capturetime.year=2021 +cdmadiagnostic.capturetime.month=4 +cdmadiagnostic.capturetime.dayOfMonth=13 +cdmadiagnostic.capturetime.dayOfWeek=1 +cdmadiagnostic.capturetime.hour=8 +cdmadiagnostic.capturetime.minute=45 +cdmadiagnostic.capturetime.second=0 +cdmadiagnostic.capturetime.hundredths=0 +cdmadiagnostic.capturetime.deviation=-60 +cdmadiagnostic.capturetime.clockstatus=0 clear.status.mask.mbus1=1 clear.status.mask.mbus2=2 diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/resources/application-smr5.properties b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/resources/application-smr5.properties index 4b43a80144f..5664d198895 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/resources/application-smr5.properties +++ b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/resources/application-smr5.properties @@ -29,4 +29,52 @@ command.hourlymeterreads.mbus.capturetime.minute=0 command.hourlymeterreads.mbus.capturetime.second=0 command.hourlymeterreads.mbus.capturetime.hundredths=0 command.hourlymeterreads.mbus.capturetime.deviation=-60 -command.hourlymeterreads.mbus.capturetime.clockstatus=0 \ No newline at end of file +command.hourlymeterreads.mbus.capturetime.clockstatus=0 + +gprsdiagnostic.operator=Utility Connect +gprsdiagnostic.status=5 +gprsdiagnostic.csattachment=0 +gprsdiagnostic.psstatus=1 +gprsdiagnostic.cellinfo.cellid=77 +gprsdiagnostic.cellinfo.locationid=2230 +gprsdiagnostic.cellinfo.signalquality=13 +gprsdiagnostic.cellinfo.ber=6 +gprsdiagnostic.cellinfo.mnc=204 +gprsdiagnostic.cellinfo.mcc=66 +gprsdiagnostic.cellinfo.channelnumber=107 +gprsdiagnostic.adjacentcells.cellids=93,94 +gprsdiagnostic.adjacentcells.signalqualities=11,12 +gprsdiagnostic.capturetime.year=2021 +gprsdiagnostic.capturetime.month=4 +gprsdiagnostic.capturetime.dayOfMonth=13 +gprsdiagnostic.capturetime.dayOfWeek=1 +gprsdiagnostic.capturetime.hour=8 +gprsdiagnostic.capturetime.minute=45 +gprsdiagnostic.capturetime.second=0 +gprsdiagnostic.capturetime.hundredths=0 +gprsdiagnostic.capturetime.deviation=-60 +gprsdiagnostic.capturetime.clockstatus=0 + +cdmadiagnostic.operator=Utility Connect +cdmadiagnostic.status=5 +cdmadiagnostic.csattachment=0 +cdmadiagnostic.psstatus=6 +cdmadiagnostic.cellinfo.cellid=77 +cdmadiagnostic.cellinfo.locationid=2230 +cdmadiagnostic.cellinfo.signalquality=13 +cdmadiagnostic.cellinfo.ber=6 +cdmadiagnostic.cellinfo.mnc=204 +cdmadiagnostic.cellinfo.mcc=66 +cdmadiagnostic.cellinfo.channelnumber=107 +cdmadiagnostic.adjacentcells.cellids=93,94 +cdmadiagnostic.adjacentcells.signalqualities=11,12 +cdmadiagnostic.capturetime.year=2021 +cdmadiagnostic.capturetime.month=4 +cdmadiagnostic.capturetime.dayOfMonth=13 +cdmadiagnostic.capturetime.dayOfWeek=1 +cdmadiagnostic.capturetime.hour=8 +cdmadiagnostic.capturetime.minute=45 +cdmadiagnostic.capturetime.second=0 +cdmadiagnostic.capturetime.hundredths=0 +cdmadiagnostic.capturetime.deviation=-60 +cdmadiagnostic.capturetime.clockstatus=0 diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/resources/application-smr51.properties b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/resources/application-smr51.properties index 9fca91d3a9a..611f59e9992 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/resources/application-smr51.properties +++ b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/resources/application-smr51.properties @@ -1,27 +1,3 @@ -gsmdiagnostic.operator=Utility Connect -gsmdiagnostic.status=5 -gsmdiagnostic.csattachment=0 -gsmdiagnostic.psstatus=1 -gsmdiagnostic.cellinfo.cellid=77 -gsmdiagnostic.cellinfo.locationid=2230 -gsmdiagnostic.cellinfo.signalquality=13 -gsmdiagnostic.cellinfo.ber=6 -gsmdiagnostic.cellinfo.mnc=204 -gsmdiagnostic.cellinfo.mcc=66 -gsmdiagnostic.cellinfo.channelnumber=107 -gsmdiagnostic.adjacentcells.cellids=93,94 -gsmdiagnostic.adjacentcells.signalqualities=11,12 -gsmdiagnostic.capturetime.year=2021 -gsmdiagnostic.capturetime.month=4 -gsmdiagnostic.capturetime.dayOfMonth=13 -gsmdiagnostic.capturetime.dayOfWeek=1 -gsmdiagnostic.capturetime.hour=8 -gsmdiagnostic.capturetime.minute=45 -gsmdiagnostic.capturetime.second=0 -gsmdiagnostic.capturetime.hundredths=0 -gsmdiagnostic.capturetime.deviation=-60 -gsmdiagnostic.capturetime.clockstatus=0 - clear.status.mask.mbus1=1 clear.status.mask.mbus2=2 clear.status.mask.mbus3=3 diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/resources/application-smr52.properties b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/resources/application-smr52.properties index f567c4f784d..10dccfdad14 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/resources/application-smr52.properties +++ b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/resources/application-smr52.properties @@ -1,2 +1,26 @@ -alarmobject.register2.value=33693956 +alarmobject.register2.value=3 alarmfilter2.value=0 + +ltediagnostic.operator=Utility Connect +ltediagnostic.status=5 +ltediagnostic.csattachment=0 +ltediagnostic.psstatus=5 +ltediagnostic.cellinfo.cellid=77 +ltediagnostic.cellinfo.locationid=2230 +ltediagnostic.cellinfo.signalquality=13 +ltediagnostic.cellinfo.ber=6 +ltediagnostic.cellinfo.mnc=204 +ltediagnostic.cellinfo.mcc=66 +ltediagnostic.cellinfo.channelnumber=107 +ltediagnostic.adjacentcells.cellids=93,94 +ltediagnostic.adjacentcells.signalqualities=11,12 +ltediagnostic.capturetime.year=2021 +ltediagnostic.capturetime.month=4 +ltediagnostic.capturetime.dayOfMonth=13 +ltediagnostic.capturetime.dayOfWeek=1 +ltediagnostic.capturetime.hour=8 +ltediagnostic.capturetime.minute=45 +ltediagnostic.capturetime.second=0 +ltediagnostic.capturetime.hundredths=0 +ltediagnostic.capturetime.deviation=-60 +ltediagnostic.capturetime.clockstatus=0 diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/resources/application-smr55.properties b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/resources/application-smr55.properties index 2daffaa9a5c..a011dc461ca 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/resources/application-smr55.properties +++ b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/dlms-device-simulator/src/main/resources/application-smr55.properties @@ -1,2 +1,2 @@ -alarmobject.register3.value=33693956 +alarmobject.register3.value=3 alarmfilter3.value=0 \ No newline at end of file diff --git a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/pom.xml b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/pom.xml index 21d05ddc9bc..7041900cf06 100644 --- a/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/pom.xml +++ b/osgp/protocol-adapter-dlms/osgp-protocol-simulator-dlms/simulator/pom.xml @@ -16,7 +16,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-pa-dlms - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../../parent-pa-dlms/pom.xml @@ -56,7 +56,7 @@ SPDX-License-Identifier: Apache-2.0 - 2.2.2.RELEASE + 2.7.18 diff --git a/osgp/protocol-adapter-dlms/parent-pa-dlms/pom.xml b/osgp/protocol-adapter-dlms/parent-pa-dlms/pom.xml index d8c2eceb809..ab8abbede41 100644 --- a/osgp/protocol-adapter-dlms/parent-pa-dlms/pom.xml +++ b/osgp/protocol-adapter-dlms/parent-pa-dlms/pom.xml @@ -17,7 +17,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform super-osgp - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../../../super/pom.xml diff --git a/osgp/protocol-adapter-dlms/pom.xml b/osgp/protocol-adapter-dlms/pom.xml index 1fba1995bea..87135b1dc33 100644 --- a/osgp/protocol-adapter-dlms/pom.xml +++ b/osgp/protocol-adapter-dlms/pom.xml @@ -10,7 +10,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform protocol-adapter-dlms - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT pom diff --git a/osgp/protocol-adapter-iec60870/osgp-iec60870/pom.xml b/osgp/protocol-adapter-iec60870/osgp-iec60870/pom.xml index 85510e8391b..06ee8cb389e 100644 --- a/osgp/protocol-adapter-iec60870/osgp-iec60870/pom.xml +++ b/osgp/protocol-adapter-iec60870/osgp-iec60870/pom.xml @@ -11,7 +11,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-pa-iec60870 - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-pa-iec60870/pom.xml diff --git a/osgp/protocol-adapter-iec60870/osgp-protocol-adapter-iec60870/pom.xml b/osgp/protocol-adapter-iec60870/osgp-protocol-adapter-iec60870/pom.xml index a72a265dad1..49f67d4fc84 100644 --- a/osgp/protocol-adapter-iec60870/osgp-protocol-adapter-iec60870/pom.xml +++ b/osgp/protocol-adapter-iec60870/osgp-protocol-adapter-iec60870/pom.xml @@ -13,7 +13,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-pa-iec60870 - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-pa-iec60870/pom.xml diff --git a/osgp/protocol-adapter-iec60870/osgp-protocol-adapter-iec60870/src/main/java/org/opensmartgridplatform/adapter/protocol/iec60870/application/services/LightSensorDeviceResponseService.java b/osgp/protocol-adapter-iec60870/osgp-protocol-adapter-iec60870/src/main/java/org/opensmartgridplatform/adapter/protocol/iec60870/application/services/LightSensorDeviceResponseService.java index 683474cf127..88a7044fbc7 100644 --- a/osgp/protocol-adapter-iec60870/osgp-protocol-adapter-iec60870/src/main/java/org/opensmartgridplatform/adapter/protocol/iec60870/application/services/LightSensorDeviceResponseService.java +++ b/osgp/protocol-adapter-iec60870/osgp-protocol-adapter-iec60870/src/main/java/org/opensmartgridplatform/adapter/protocol/iec60870/application/services/LightSensorDeviceResponseService.java @@ -4,10 +4,12 @@ package org.opensmartgridplatform.adapter.protocol.iec60870.application.services; +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.util.Optional; import java.util.function.Consumer; import java.util.function.Predicate; -import org.joda.time.DateTime; import org.opensmartgridplatform.adapter.protocol.iec60870.domain.entities.Iec60870Device; import org.opensmartgridplatform.adapter.protocol.iec60870.domain.repositories.Iec60870DeviceRepository; import org.opensmartgridplatform.adapter.protocol.iec60870.domain.services.LightMeasurementService; @@ -342,7 +344,7 @@ private Optional findEventNotification( device.getDeviceIdentification()); } - final DateTime dateTime = this.findTimeValue(measurementGroup).orElse(null); + final ZonedDateTime dateTime = this.findTimeValue(measurementGroup).orElse(null); if (dateTime == null) { LOGGER.warn( "Unable to determine the time for event notification for device {}", @@ -367,12 +369,13 @@ private Optional findSensorValue(final MeasurementGroupDto measurementG .findFirst(); } - private Optional findTimeValue(final MeasurementGroupDto measurementGroup) { + private Optional findTimeValue(final MeasurementGroupDto measurementGroup) { return measurementGroup.getMeasurements().stream() .flatMap(measurement -> measurement.getMeasurementElements().stream()) .filter(element -> element instanceof TimestampMeasurementElementDto) .map(element -> ((TimestampMeasurementElementDto) element).getValue()) - .map(DateTime::new) + .map( + millis -> ZonedDateTime.ofInstant(Instant.ofEpochMilli(millis), ZoneId.systemDefault())) .findFirst(); } } diff --git a/osgp/protocol-adapter-iec60870/osgp-protocol-adapter-iec60870/src/main/java/org/opensmartgridplatform/adapter/protocol/iec60870/domain/valueobjects/RequestMetadata.java b/osgp/protocol-adapter-iec60870/osgp-protocol-adapter-iec60870/src/main/java/org/opensmartgridplatform/adapter/protocol/iec60870/domain/valueobjects/RequestMetadata.java index 55602bdbadd..283c2987220 100644 --- a/osgp/protocol-adapter-iec60870/osgp-protocol-adapter-iec60870/src/main/java/org/opensmartgridplatform/adapter/protocol/iec60870/domain/valueobjects/RequestMetadata.java +++ b/osgp/protocol-adapter-iec60870/osgp-protocol-adapter-iec60870/src/main/java/org/opensmartgridplatform/adapter/protocol/iec60870/domain/valueobjects/RequestMetadata.java @@ -60,7 +60,7 @@ public Builder messageMetadata(final MessageMetadata messageMetadata) { this.correlationUid = messageMetadata.getCorrelationUid(); this.organisationIdentification = messageMetadata.getOrganisationIdentification(); this.deviceIdentification = messageMetadata.getDeviceIdentification(); - this.ipAddress = messageMetadata.getIpAddress(); + this.ipAddress = messageMetadata.getNetworkAddress(); return this; } diff --git a/osgp/protocol-adapter-iec60870/osgp-protocol-simulator-iec60870/pom.xml b/osgp/protocol-adapter-iec60870/osgp-protocol-simulator-iec60870/pom.xml index 70927b7caef..c2942e8010b 100644 --- a/osgp/protocol-adapter-iec60870/osgp-protocol-simulator-iec60870/pom.xml +++ b/osgp/protocol-adapter-iec60870/osgp-protocol-simulator-iec60870/pom.xml @@ -16,13 +16,13 @@ SPDX-License-Identifier: Apache-2.0 org.springframework.boot spring-boot-starter-parent - 2.7.2 + 2.7.18 org.opensmartgridplatform osgp-protocol-simulator-iec60870 - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT war osgp-protocol-simulator-iec60870 Simulator for IEC60870-5-104 protocol diff --git a/osgp/protocol-adapter-iec60870/parent-pa-iec60870/pom.xml b/osgp/protocol-adapter-iec60870/parent-pa-iec60870/pom.xml index 49796a48bec..2d7302a3b3d 100644 --- a/osgp/protocol-adapter-iec60870/parent-pa-iec60870/pom.xml +++ b/osgp/protocol-adapter-iec60870/parent-pa-iec60870/pom.xml @@ -13,7 +13,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform super-osgp - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../../../super/pom.xml diff --git a/osgp/protocol-adapter-iec60870/pom.xml b/osgp/protocol-adapter-iec60870/pom.xml index b48794ba3bb..30dfe89aa6e 100644 --- a/osgp/protocol-adapter-iec60870/pom.xml +++ b/osgp/protocol-adapter-iec60870/pom.xml @@ -12,7 +12,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform protocol-adapter-iec60870 - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT pom protocol-adapter-iec60870 diff --git a/osgp/protocol-adapter-iec61850/osgp-core-db-api-iec61850/pom.xml b/osgp/protocol-adapter-iec61850/osgp-core-db-api-iec61850/pom.xml index ff19b07fdb1..021539c0ab9 100644 --- a/osgp/protocol-adapter-iec61850/osgp-core-db-api-iec61850/pom.xml +++ b/osgp/protocol-adapter-iec61850/osgp-core-db-api-iec61850/pom.xml @@ -18,7 +18,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-pa-iec61850 - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-pa-iec61850/pom.xml diff --git a/osgp/protocol-adapter-iec61850/osgp-core-db-api-iec61850/src/main/java/org/opensmartgridplatform/core/db/api/iec61850/entities/Device.java b/osgp/protocol-adapter-iec61850/osgp-core-db-api-iec61850/src/main/java/org/opensmartgridplatform/core/db/api/iec61850/entities/Device.java index 17ceb916a6c..5ac90972f22 100644 --- a/osgp/protocol-adapter-iec61850/osgp-core-db-api-iec61850/src/main/java/org/opensmartgridplatform/core/db/api/iec61850/entities/Device.java +++ b/osgp/protocol-adapter-iec61850/osgp-core-db-api-iec61850/src/main/java/org/opensmartgridplatform/core/db/api/iec61850/entities/Device.java @@ -5,7 +5,7 @@ package org.opensmartgridplatform.core.db.api.iec61850.entities; import java.io.Serializable; -import java.util.Date; +import java.time.Instant; import java.util.Objects; import javax.persistence.Column; import javax.persistence.Entity; @@ -36,11 +36,11 @@ public class Device implements Serializable { /** Creation time of this entity. This field is set by { @see this.prePersist() }. */ @Column(nullable = false) - protected Date creationTime = new Date(); + protected Instant creationTime = Instant.now(); /** Modification time of this entity. This field is set by { @see this.preUpdate() }. */ @Column(nullable = false) - protected Date modificationTime = new Date(); + protected Instant modificationTime = Instant.now(); /** Version of this entity. */ @Version private Long version = -1L; @@ -83,8 +83,8 @@ public boolean equals(final Object o) { return Objects.equals(this.deviceIdentification, device.deviceIdentification); } - public Date getCreationTime() { - return (Date) this.creationTime.clone(); + public Instant getCreationTime() { + return this.creationTime; } public String getDeviceIdentification() { @@ -103,8 +103,8 @@ public Long getId() { return this.id; } - public Date getModificationTime() { - return (Date) this.modificationTime.clone(); + public Instant getModificationTime() { + return this.modificationTime; } public Long getVersion() { @@ -119,7 +119,7 @@ public int hashCode() { /** Method for actions to be taken before inserting. */ @PrePersist private void prePersist() { - final Date now = new Date(); + final Instant now = Instant.now(); this.creationTime = now; this.modificationTime = now; } @@ -127,7 +127,7 @@ private void prePersist() { /** Method for actions to be taken before updating. */ @PreUpdate private void preUpdate() { - this.modificationTime = new Date(); + this.modificationTime = Instant.now(); } public void setVersion(final Long newVersion) { diff --git a/osgp/protocol-adapter-iec61850/osgp-iec61850/pom.xml b/osgp/protocol-adapter-iec61850/osgp-iec61850/pom.xml index fde98221128..fd7ea63b5e8 100644 --- a/osgp/protocol-adapter-iec61850/osgp-iec61850/pom.xml +++ b/osgp/protocol-adapter-iec61850/osgp-iec61850/pom.xml @@ -16,7 +16,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-pa-iec61850 - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-pa-iec61850/pom.xml diff --git a/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/pom.xml b/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/pom.xml index e183904621a..847fb40f6d1 100644 --- a/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/pom.xml +++ b/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/pom.xml @@ -17,7 +17,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-pa-iec61850 - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-pa-iec61850/pom.xml diff --git a/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/application/services/DeviceRegistrationService.java b/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/application/services/DeviceRegistrationService.java index 148ff04be47..0e56386065c 100644 --- a/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/application/services/DeviceRegistrationService.java +++ b/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/application/services/DeviceRegistrationService.java @@ -69,7 +69,7 @@ public void disableRegistration( final DeviceConnectionParameters deviceConnectionParameters = DeviceConnectionParameters.newBuilder() - .ipAddress(ipAddress.getHostAddress()) + .networkAddress(ipAddress.getHostAddress()) .deviceIdentification(deviceIdentification) .ied(ied) .serverName(serverName) diff --git a/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/device/DeviceRequest.java b/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/device/DeviceRequest.java index 0c596719679..324c34ed839 100644 --- a/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/device/DeviceRequest.java +++ b/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/device/DeviceRequest.java @@ -16,7 +16,7 @@ public class DeviceRequest { private final String domainVersion; private final String messageType; private final int messagePriority; - private final String ipAddress; + private final String networkAddress; private final int retryCount; private final boolean isScheduled; @@ -28,7 +28,7 @@ public DeviceRequest(final Builder builder) { this.domainVersion = builder.domainVersion; this.messageType = builder.messageType; this.messagePriority = builder.messagePriority; - this.ipAddress = builder.ipAddress; + this.networkAddress = builder.networkAddress; this.retryCount = builder.retryCount; this.isScheduled = builder.isScheduled; } @@ -41,7 +41,7 @@ public static class Builder { private String domainVersion = null; private String messageType = null; private int messagePriority = MessagePriorityEnum.DEFAULT.getPriority(); - private String ipAddress = null; + private String networkAddress = null; private int retryCount = 0; private boolean isScheduled = false; @@ -53,7 +53,7 @@ public Builder messageMetaData(final MessageMetadata messageMetadata) { this.domainVersion = messageMetadata.getDomainVersion(); this.messageType = messageMetadata.getMessageType(); this.messagePriority = messageMetadata.getMessagePriority(); - this.ipAddress = messageMetadata.getIpAddress(); + this.networkAddress = messageMetadata.getNetworkAddress(); this.retryCount = messageMetadata.getRetryCount(); this.isScheduled = messageMetadata.isScheduled(); return this; @@ -94,8 +94,8 @@ public Builder messagePriority(final int messagePriority) { return this; } - public Builder ipAddress(final String ipAddress) { - this.ipAddress = ipAddress; + public Builder networkAddress(final String ipAddress) { + this.networkAddress = ipAddress; return this; } @@ -146,8 +146,8 @@ public int getMessagePriority() { return this.messagePriority; } - public String getIpAddress() { - return this.ipAddress; + public String getNetworkAddress() { + return this.networkAddress; } public int getRetryCount() { diff --git a/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/domain/valueobjects/DaylightSavingTimeTransition.java b/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/domain/valueobjects/DaylightSavingTimeTransition.java index 7eb1b0b6621..060fc28ab3e 100644 --- a/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/domain/valueobjects/DaylightSavingTimeTransition.java +++ b/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/domain/valueobjects/DaylightSavingTimeTransition.java @@ -4,10 +4,10 @@ package org.opensmartgridplatform.adapter.protocol.iec61850.domain.valueobjects; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.GregorianCalendar; import java.util.Objects; -import org.joda.time.DateTime; -import org.joda.time.DateTimeConstants; -import org.joda.time.DateTimeZone; /** * Class for handling representations of the start (when DST goes into effect) or end time (when @@ -23,6 +23,8 @@ * @see http://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html */ public class DaylightSavingTimeTransition { + public static final int SUNDAY = 7; + public static final int MARCH = 3; public enum DstTransitionFormat { /** @@ -61,11 +63,12 @@ public boolean isValid(final String transition) { } @Override - public DaylightSavingTimeTransition getDaylightSavingTimeTransition(final DateTime dateTime) { + public DaylightSavingTimeTransition getDaylightSavingTimeTransition( + final ZonedDateTime dateTime) { final int dayOfYear = dateTime.getDayOfYear(); final int n; - if (dateTime.getMonthOfYear() < DateTimeConstants.MARCH - || !dateTime.toGregorianCalendar().isLeapYear(dateTime.getYear())) { + if (dateTime.getMonthValue() < MARCH + || !GregorianCalendar.from(dateTime).isLeapYear(dateTime.getYear())) { n = dayOfYear; } else { /* @@ -74,7 +77,7 @@ public DaylightSavingTimeTransition getDaylightSavingTimeTransition(final DateTi */ n = dayOfYear - 1; } - final int hours = dateTime.getHourOfDay(); + final int hours = dateTime.getHour(); final String transition; if (hours == 0) { transition = "J" + n; @@ -85,8 +88,8 @@ public DaylightSavingTimeTransition getDaylightSavingTimeTransition(final DateTi } @Override - public DateTime getDateTime( - final DateTimeZone dateTimeZone, final String transition, final int year) { + public ZonedDateTime getDateTime( + final ZoneId dateTimeZone, final String transition, final int year) { final int timeSeparatorPos = transition.indexOf('/'); final int n; if (timeSeparatorPos == -1) { @@ -95,11 +98,12 @@ public DateTime getDateTime( n = Integer.parseInt(transition.substring(1, timeSeparatorPos)); } - final DateTime candidate = new DateTime(year, 1, 1, 0, 0, 0, 0, dateTimeZone).plusDays(n); + final ZonedDateTime candidate = + ZonedDateTime.of(year, 1, 1, 0, 0, 0, 0, dateTimeZone).plusDays(n); final boolean subtractOne = - !candidate.toGregorianCalendar().isLeapYear(year) - || candidate.getMonthOfYear() < DateTimeConstants.MARCH; + !GregorianCalendar.from(candidate).isLeapYear(year) + || candidate.getMonthValue() < MARCH; if (subtractOne) { return candidate.minusDays(1).plusHours(this.getTime(transition)); @@ -144,9 +148,10 @@ public boolean isValid(final String transition) { } @Override - public DaylightSavingTimeTransition getDaylightSavingTimeTransition(final DateTime dateTime) { + public DaylightSavingTimeTransition getDaylightSavingTimeTransition( + final ZonedDateTime dateTime) { final int n = dateTime.getDayOfYear() - 1; - final int hours = dateTime.getHourOfDay(); + final int hours = dateTime.getHour(); final String transition; if (hours == 0) { transition = String.valueOf(n); @@ -157,8 +162,8 @@ public DaylightSavingTimeTransition getDaylightSavingTimeTransition(final DateTi } @Override - public DateTime getDateTime( - final DateTimeZone dateTimeZone, final String transition, final int year) { + public ZonedDateTime getDateTime( + final ZoneId dateTimeZone, final String transition, final int year) { final int timeSeparatorPos = transition.indexOf('/'); final int n; if (timeSeparatorPos == -1) { @@ -166,7 +171,7 @@ public DateTime getDateTime( } else { n = Integer.parseInt(transition.substring(0, timeSeparatorPos)); } - return new DateTime(year, 1, 1, 0, 0, 0, 0, dateTimeZone) + return ZonedDateTime.of(year, 1, 1, 0, 0, 0, 0, dateTimeZone) .plusDays(n) .plusHours(this.getTime(transition)); } @@ -234,19 +239,20 @@ private boolean checkTransitionTime( } @Override - public DaylightSavingTimeTransition getDaylightSavingTimeTransition(final DateTime dateTime) { - final int m = dateTime.getMonthOfYear(); - final boolean lastDayOfWeekForTheMonth = dateTime.plusDays(7).getMonthOfYear() > m; + public DaylightSavingTimeTransition getDaylightSavingTimeTransition( + final ZonedDateTime dateTime) { + final int m = dateTime.getMonthValue(); + final boolean lastDayOfWeekForTheMonth = dateTime.plusDays(7).getMonthValue() > m; final int w = lastDayOfWeekForTheMonth ? 5 : 1 + ((dateTime.getDayOfMonth() - 1) / 7); - final int d = dateTime.getDayOfWeek() % 7; - final int time = dateTime.getHourOfDay(); + final int d = dateTime.getDayOfWeek().getValue() % 7; + final int time = dateTime.getHour(); final String transition = "M" + m + "." + w + "." + d + (time == 0 ? "" : "/" + time); return new DaylightSavingTimeTransition(dateTime.getZone(), transition); } @Override - public DateTime getDateTime( - final DateTimeZone dateTimeZone, final String transition, final int year) { + public ZonedDateTime getDateTime( + final ZoneId dateTimeZone, final String transition, final int year) { final int dotAfterM = transition.indexOf('.', 1); final int m = Integer.parseInt(transition.substring(1, dotAfterM)); final int dotAfterW = transition.indexOf('.', dotAfterM + 1); @@ -258,11 +264,12 @@ public DateTime getDateTime( } else { d = Integer.parseInt(transition.substring(dotAfterW + 1, timeSeparatorPos)); } - final int dayOfWeek = d == 0 ? DateTimeConstants.SUNDAY : d; + final int dayOfWeek = d == 0 ? SUNDAY : d; final int startAtDate = w == 5 ? 22 : (w - 1) * 7 + 1; - final DateTime firstAttempt = new DateTime(year, m, startAtDate, 0, 0, 0, 0, dateTimeZone); - final int dayDiff = dayOfWeek - firstAttempt.getDayOfWeek(); - final DateTime secondAttempt; + final ZonedDateTime firstAttempt = + ZonedDateTime.of(year, m, startAtDate, 0, 0, 0, 0, dateTimeZone); + final int dayDiff = dayOfWeek - firstAttempt.getDayOfWeek().getValue(); + final ZonedDateTime secondAttempt; if (dayDiff == 0) { secondAttempt = firstAttempt; } else { @@ -271,8 +278,8 @@ public DateTime getDateTime( if (w < 5) { return secondAttempt.plusHours(this.getTime(transition)); } - final DateTime thirdAttempt = secondAttempt.plusDays(7); - if (thirdAttempt.getMonthOfYear() > secondAttempt.getMonthOfYear()) { + final ZonedDateTime thirdAttempt = secondAttempt.plusDays(7); + if (thirdAttempt.getMonthValue() > secondAttempt.getMonthValue()) { return secondAttempt.plusHours(this.getTime(transition)); } return thirdAttempt.plusHours(this.getTime(transition)); @@ -281,9 +288,10 @@ public DateTime getDateTime( public abstract boolean isValid(String transition); - public abstract DaylightSavingTimeTransition getDaylightSavingTimeTransition(DateTime dateTime); + public abstract DaylightSavingTimeTransition getDaylightSavingTimeTransition( + ZonedDateTime dateTime); - public abstract DateTime getDateTime(DateTimeZone dateTimeZone, String transition, int year); + public abstract ZonedDateTime getDateTime(ZoneId dateTimeZone, String transition, int year); public boolean isValidTime(final String time) { if (time == null) { @@ -325,14 +333,14 @@ public int getTime(final String transition) { } } - private static final DateTimeZone TIME_ZONE_AMSTERDAM = DateTimeZone.forID("Europe/Amsterdam"); + private static final ZoneId TIME_ZONE_AMSTERDAM = ZoneId.of("Europe/Amsterdam"); private final DstTransitionFormat format; private final String transition; - private final DateTimeZone dateTimeZone; + private final ZoneId dateTimeZone; public static DaylightSavingTimeTransition forDateTimeAccordingToFormat( - final DateTime dateTime, final DstTransitionFormat format) { + final ZonedDateTime dateTime, final DstTransitionFormat format) { Objects.requireNonNull(dateTime, "dateTime must not be null"); Objects.requireNonNull(format, "format must not be null"); @@ -348,7 +356,7 @@ public static DaylightSavingTimeTransition forDateTimeAccordingToFormat( * @param transition the formatted representation of when Daylight Saving Time goes into effect or * when the change is made back to standard time. */ - public DaylightSavingTimeTransition(final DateTimeZone dateTimeZone, final String transition) { + public DaylightSavingTimeTransition(final ZoneId dateTimeZone, final String transition) { Objects.requireNonNull(dateTimeZone, "dateTimeZone must not be null"); Objects.requireNonNull(transition, "transition must not be null"); this.dateTimeZone = dateTimeZone; @@ -370,26 +378,26 @@ public DaylightSavingTimeTransition(final DateTimeZone dateTimeZone, final Strin /** * Creates a {@link DaylightSavingTimeTransition} for time zone "Europe/Amsterdam". * - * @see #DaylightSavingTimeTransition(DateTimeZone, String) + * @see #DaylightSavingTimeTransition(ZoneId, String) */ public DaylightSavingTimeTransition(final String transition) { this(TIME_ZONE_AMSTERDAM, transition); } - public DateTime getDateTimeForYear(final int year) { + public ZonedDateTime getDateTimeForYear(final int year) { return this.format.getDateTime(this.dateTimeZone, this.transition, year); } - public DateTime getDateTimeForCurrentYear() { - return this.getDateTimeForYear(DateTime.now(this.dateTimeZone).getYear()); + public ZonedDateTime getDateTimeForCurrentYear() { + return this.getDateTimeForYear(ZonedDateTime.now(this.dateTimeZone).getYear()); } - public DateTime getDateTimeForNextTransition() { - return this.getDateTimeForNextTransition(DateTime.now(this.dateTimeZone)); + public ZonedDateTime getDateTimeForNextTransition() { + return this.getDateTimeForNextTransition(ZonedDateTime.now(this.dateTimeZone)); } - public DateTime getDateTimeForNextTransition(final DateTime dateTime) { - final DateTime thisYearsTransition = this.getDateTimeForYear(dateTime.getYear()); + public ZonedDateTime getDateTimeForNextTransition(final ZonedDateTime dateTime) { + final ZonedDateTime thisYearsTransition = this.getDateTimeForYear(dateTime.getYear()); if (dateTime.isAfter(thisYearsTransition)) { return this.getDateTimeForYear(dateTime.getYear() + 1); } @@ -404,7 +412,7 @@ public String getTransition() { return this.transition; } - public DateTimeZone getDateTimeZone() { + public ZoneId getDateTimeZone() { return this.dateTimeZone; } diff --git a/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/domain/valueobjects/DeviceConnectionParameters.java b/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/domain/valueobjects/DeviceConnectionParameters.java index c87460d3a94..b51ebc60637 100644 --- a/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/domain/valueobjects/DeviceConnectionParameters.java +++ b/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/domain/valueobjects/DeviceConnectionParameters.java @@ -8,14 +8,14 @@ public class DeviceConnectionParameters { - final String ipAddress; + final String networkAddress; final String deviceIdentification; final IED ied; final String serverName; final String logicalDevice; public DeviceConnectionParameters(final Builder builder) { - this.ipAddress = builder.ipAddress; + this.networkAddress = builder.ipAddress; this.deviceIdentification = builder.deviceIdentification; this.ied = builder.ied; this.serverName = builder.serverName; @@ -29,7 +29,7 @@ public static class Builder { private String serverName = null; private String logicalDevice = null; - public Builder ipAddress(final String ipAddress) { + public Builder networkAddress(final String ipAddress) { this.ipAddress = ipAddress; return this; } @@ -63,8 +63,8 @@ public static Builder newBuilder() { return new Builder(); } - public String getIpAddress() { - return this.ipAddress; + public String getNetworkAddress() { + return this.networkAddress; } public String getDeviceIdentification() { diff --git a/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/helper/Iec61850SetConfigurationFunction.java b/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/helper/Iec61850SetConfigurationFunction.java index e7c9b3a3264..d9351a9eb9f 100644 --- a/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/helper/Iec61850SetConfigurationFunction.java +++ b/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/helper/Iec61850SetConfigurationFunction.java @@ -6,8 +6,8 @@ import com.beanit.openiec61850.BdaInt8; import com.beanit.openiec61850.Fc; +import java.time.ZonedDateTime; import java.util.List; -import org.joda.time.DateTime; import org.opensmartgridplatform.adapter.protocol.iec61850.domain.valueobjects.DaylightSavingTimeTransition; import org.opensmartgridplatform.adapter.protocol.iec61850.domain.valueobjects.DeviceMessageLog; import org.opensmartgridplatform.adapter.protocol.iec61850.exceptions.NodeException; @@ -319,8 +319,8 @@ private void setClockConfiguration( */ final DaylightSavingTimeTransition.DstTransitionFormat dstFormatMwd = DaylightSavingTimeTransition.DstTransitionFormat.DAY_OF_WEEK_OF_MONTH; - final DateTime summerTimeDetails = configuration.getSummerTimeDetails(); - final DateTime winterTimeDetails = configuration.getWinterTimeDetails(); + final ZonedDateTime summerTimeDetails = configuration.getSummerTimeDetails(); + final ZonedDateTime winterTimeDetails = configuration.getWinterTimeDetails(); if (summerTimeDetails != null) { final String mwdValueForBeginOfDst = diff --git a/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/helper/RequestMessageData.java b/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/helper/RequestMessageData.java index 990ad2a5d1d..fd48d022e11 100644 --- a/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/helper/RequestMessageData.java +++ b/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/helper/RequestMessageData.java @@ -66,7 +66,7 @@ public Builder messageMetadata(final MessageMetadata messageMetadata) { this.correlationUid = messageMetadata.getCorrelationUid(); this.organisationIdentification = messageMetadata.getOrganisationIdentification(); this.deviceIdentification = messageMetadata.getDeviceIdentification(); - this.ipAddress = messageMetadata.getIpAddress(); + this.ipAddress = messageMetadata.getNetworkAddress(); this.messagePriority = messageMetadata.getMessagePriority(); this.scheduleTime = messageMetadata.getScheduleTime(); return this; diff --git a/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/reporting/Iec61850ClientLMDEventListener.java b/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/reporting/Iec61850ClientLMDEventListener.java index bea64eb3560..c2a984d8248 100644 --- a/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/reporting/Iec61850ClientLMDEventListener.java +++ b/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/reporting/Iec61850ClientLMDEventListener.java @@ -8,12 +8,13 @@ import com.beanit.openiec61850.FcModelNode; import com.beanit.openiec61850.Report; import java.io.IOException; +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; import org.opensmartgridplatform.adapter.protocol.iec61850.application.services.DeviceManagementService; import org.opensmartgridplatform.adapter.protocol.iec61850.exceptions.ProtocolAdapterException; import org.opensmartgridplatform.adapter.protocol.iec61850.infra.networking.helper.LogicalNode; @@ -34,7 +35,7 @@ public Iec61850ClientLMDEventListener( @Override public void newReport(final Report report) { - final DateTime timeOfEntry = this.getTimeOfEntry(report); + final ZonedDateTime timeOfEntry = this.getTimeOfEntry(report); final String reportDescription = this.getReportDescription(report, timeOfEntry); @@ -107,13 +108,15 @@ private Map processReportedDataForLightMeas return result; } - private DateTime getTimeOfEntry(final Report report) { + private ZonedDateTime getTimeOfEntry(final Report report) { return report.getTimeOfEntry() == null - ? DateTime.now(DateTimeZone.UTC) - : new DateTime(report.getTimeOfEntry().getTimestampValue()); + ? ZonedDateTime.now(ZoneId.of("UTC")) + : ZonedDateTime.ofInstant( + Instant.ofEpochMilli(report.getTimeOfEntry().getTimestampValue()), + ZoneId.systemDefault()); } - private String getReportDescription(final Report report, final DateTime timeOfEntry) { + private String getReportDescription(final Report report, final ZonedDateTime timeOfEntry) { return String.format( "reportId: %s, timeOfEntry: %s, sqNum: %s%s%s", report.getRptId(), @@ -125,11 +128,11 @@ private String getReportDescription(final Report report, final DateTime timeOfEn private EventNotificationDto getEventNotificationForReportedData( final FcModelNode evnRpn, - final DateTime timeOfEntry, + final ZonedDateTime timeOfEntry, final String reportDescription, final String deviceIdentification, final Integer index) { - EventTypeDto eventType; + final EventTypeDto eventType; final boolean lightSensorValue = this.determineLightSensorValue(evnRpn, reportDescription); /* * 0 -> false -> NIGHT_DAY --> LIGHT_SENSOR_REPORTS_LIGHT diff --git a/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/reporting/Iec61850ClientSSLDEventListener.java b/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/reporting/Iec61850ClientSSLDEventListener.java index 10706c0b4a6..5864dd728d3 100644 --- a/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/reporting/Iec61850ClientSSLDEventListener.java +++ b/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/reporting/Iec61850ClientSSLDEventListener.java @@ -14,6 +14,9 @@ import com.beanit.openiec61850.FcModelNode; import com.beanit.openiec61850.Report; import java.io.IOException; +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -64,7 +67,7 @@ public class Iec61850ClientSSLDEventListener extends Iec61850ClientBaseEventList TRG_TYPE_DESCRIPTION_PER_CODE.put((short) 4, "autonomous trigger"); } - private DeviceMessageLoggingService loggingService; + private final DeviceMessageLoggingService loggingService; private final String organizationIdentification; private final List eventNotifications = new ArrayList<>(); private final Map externalIndexByInternalIndex = new TreeMap<>(); @@ -106,7 +109,7 @@ private Map buildExternalByInternalIndexMap( @Override public void newReport(final Report report) { - final DateTime timeOfEntry = this.getTimeOfEntry(report); + final ZonedDateTime timeOfEntry = this.getTimeOfEntry(report); final String reportDescription = this.getReportDescription(report, timeOfEntry); @@ -161,13 +164,15 @@ public void newReport(final Report report) { } } - private DateTime getTimeOfEntry(final Report report) { + private ZonedDateTime getTimeOfEntry(final Report report) { return report.getTimeOfEntry() == null ? null - : new DateTime(report.getTimeOfEntry().getTimestampValue()); + : ZonedDateTime.ofInstant( + Instant.ofEpochMilli(report.getTimeOfEntry().getTimestampValue()), + ZoneId.systemDefault()); } - private String getReportDescription(final Report report, final DateTime timeOfEntry) { + private String getReportDescription(final Report report, final ZonedDateTime timeOfEntry) { return String.format( "device: %s, reportId: %s, timeOfEntry: %s, sqNum: %s%s%s", this.deviceIdentification, @@ -179,12 +184,12 @@ private String getReportDescription(final Report report, final DateTime timeOfEn } private void addEventNotificationForReportedData( - final FcModelNode evnRpn, final DateTime timeOfEntry, final String reportDescription) { + final FcModelNode evnRpn, final ZonedDateTime timeOfEntry, final String reportDescription) { final EventTypeDto eventType = this.determineEventType(evnRpn, reportDescription); final Integer index = this.determineRelayIndex(evnRpn, reportDescription); final String description = this.determineDescription(evnRpn); - final DateTime dateTime = this.determineDateTime(evnRpn, timeOfEntry); + final ZonedDateTime dateTime = this.determineDateTime(evnRpn, timeOfEntry); final EventNotificationDto eventNotification = new EventNotificationDto( @@ -293,11 +298,12 @@ private String determineRemarkNode(final FcModelNode evnRpn) { return EMPTY; } - private DateTime determineDateTime(final FcModelNode evnRpn, final DateTime timeOfEntry) { + private ZonedDateTime determineDateTime( + final FcModelNode evnRpn, final ZonedDateTime timeOfEntry) { final BdaTimestamp trgTimeNode = (BdaTimestamp) evnRpn.getChild(EVENT_NODE_TRIGGER_TIME); if (trgTimeNode != null && trgTimeNode.getDate() != null) { - return new DateTime(trgTimeNode.getDate()); + return ZonedDateTime.ofInstant(trgTimeNode.getDate().toInstant(), ZoneId.systemDefault()); } if (timeOfEntry != null) { @@ -314,7 +320,7 @@ private DateTime determineDateTime(final FcModelNode evnRpn, final DateTime time * No time of entry or trigger time available for the report. As a * fallback use the time the report is processed here as event time. */ - return DateTime.now(); + return ZonedDateTime.now(); } private IllegalArgumentException childNodeNotAvailableException( diff --git a/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/services/Iec61850DaRtuDeviceService.java b/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/services/Iec61850DaRtuDeviceService.java index fd88c629017..83d3f9c7663 100644 --- a/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/services/Iec61850DaRtuDeviceService.java +++ b/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/services/Iec61850DaRtuDeviceService.java @@ -99,7 +99,7 @@ private ServerModel connectAndRetrieveServerModel( final DeviceConnectionParameters deviceConnectionParameters = DeviceConnectionParameters.newBuilder() - .ipAddress(deviceRequest.getIpAddress()) + .networkAddress(deviceRequest.getNetworkAddress()) .deviceIdentification(deviceRequest.getDeviceIdentification()) .ied(IED.DA_RTU) .serverName(serverName) diff --git a/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/services/Iec61850DeviceConnectionService.java b/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/services/Iec61850DeviceConnectionService.java index 18ca38b6d22..c469464e910 100644 --- a/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/services/Iec61850DeviceConnectionService.java +++ b/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/services/Iec61850DeviceConnectionService.java @@ -52,7 +52,8 @@ public class Iec61850DeviceConnectionService { private static final Logger LOGGER = LoggerFactory.getLogger(Iec61850DeviceConnectionService.class); - private static ConcurrentHashMap cache = new ConcurrentHashMap<>(); + private static final ConcurrentHashMap cache = + new ConcurrentHashMap<>(); @Autowired private Iec61850DeviceRepository iec61850DeviceRepository; @@ -119,13 +120,13 @@ public DeviceConnection connect( } final InetAddress inetAddress = - this.convertIpAddress(deviceConnectionParameters.getIpAddress()); + this.convertIpAddress(deviceConnectionParameters.getNetworkAddress()); // Connect to obtain ClientAssociation and ServerModel. LOGGER.info( "Trying to connect to deviceIdentification: {} at IP address {} using response time-out: {}", deviceIdentification, - deviceConnectionParameters.getIpAddress(), + deviceConnectionParameters.getNetworkAddress(), this.responseTimeout); final DateTime startTime = DateTime.now(); @@ -151,7 +152,7 @@ public DeviceConnection connect( // Set response time-out. clientAssociation.setResponseTimeout(this.responseTimeout); // Read the ServerModel, either from the device or from a SCL file. - ServerModel serverModel; + final ServerModel serverModel; try { serverModel = this.readServerModel(clientAssociation, deviceIdentification, iec61850Device); } catch (final ProtocolAdapterException e) { diff --git a/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/services/Iec61850LmdDeviceService.java b/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/services/Iec61850LmdDeviceService.java index 8b97bd4c543..771c6fcaf40 100644 --- a/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/services/Iec61850LmdDeviceService.java +++ b/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/services/Iec61850LmdDeviceService.java @@ -89,7 +89,7 @@ private DeviceConnection connectToDevice(final DeviceRequest deviceRequest) final DeviceConnectionParameters deviceConnectionParameters = DeviceConnectionParameters.newBuilder() - .ipAddress(deviceRequest.getIpAddress()) + .networkAddress(deviceRequest.getNetworkAddress()) .deviceIdentification(deviceRequest.getDeviceIdentification()) .ied(IED.ABB_RTU) .serverName(IED.ABB_RTU.getDescription()) diff --git a/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/services/Iec61850RtuDeviceService.java b/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/services/Iec61850RtuDeviceService.java index 2ae2e6ef2f7..c4ca0bc1200 100644 --- a/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/services/Iec61850RtuDeviceService.java +++ b/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/services/Iec61850RtuDeviceService.java @@ -152,7 +152,7 @@ private ServerModel connectAndRetrieveServerModel( final DeviceConnectionParameters deviceConnectionParameters = DeviceConnectionParameters.newBuilder() - .ipAddress(deviceRequest.getIpAddress()) + .networkAddress(deviceRequest.getNetworkAddress()) .deviceIdentification(deviceRequest.getDeviceIdentification()) .ied(IED.ZOWN_RTU) .serverName(serverName) diff --git a/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/services/Iec61850SsldDeviceService.java b/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/services/Iec61850SsldDeviceService.java index 55e6f1776fb..ba289388542 100644 --- a/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/services/Iec61850SsldDeviceService.java +++ b/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/services/Iec61850SsldDeviceService.java @@ -556,7 +556,7 @@ private DeviceConnection connectToDevice(final DeviceRequest deviceRequest) final DeviceConnectionParameters deviceConnectionParameters = DeviceConnectionParameters.newBuilder() - .ipAddress(deviceRequest.getIpAddress()) + .networkAddress(deviceRequest.getNetworkAddress()) .deviceIdentification(deviceRequest.getDeviceIdentification()) .ied(IED.FLEX_OVL) .serverName(IED.FLEX_OVL.getDescription()) diff --git a/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/services/commands/Iec61850GetConfigurationCommand.java b/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/services/commands/Iec61850GetConfigurationCommand.java index 157144af82b..64fae9ae1f6 100644 --- a/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/services/commands/Iec61850GetConfigurationCommand.java +++ b/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/services/commands/Iec61850GetConfigurationCommand.java @@ -5,10 +5,10 @@ package org.opensmartgridplatform.adapter.protocol.iec61850.infra.networking.services.commands; import com.beanit.openiec61850.Fc; +import java.time.ZoneId; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import org.joda.time.DateTimeZone; import org.opensmartgridplatform.adapter.protocol.iec61850.application.mapping.Iec61850Mapper; import org.opensmartgridplatform.adapter.protocol.iec61850.domain.valueobjects.DaylightSavingTimeTransition; import org.opensmartgridplatform.adapter.protocol.iec61850.domain.valueobjects.DeviceMessageLog; @@ -42,9 +42,9 @@ public class Iec61850GetConfigurationCommand { private static final int SWITCH_TYPE_TARIFF = 0; private static final int SWITCH_TYPE_LIGHT = 1; - private static final DateTimeZone TIME_ZONE_AMSTERDAM = DateTimeZone.forID("Europe/Amsterdam"); + private static final ZoneId TIME_ZONE_AMSTERDAM = ZoneId.of("Europe/Amsterdam"); - private DeviceMessageLoggingService loggingService; + private final DeviceMessageLoggingService loggingService; public Iec61850GetConfigurationCommand(final DeviceMessageLoggingService loggingService) { this.loggingService = loggingService; @@ -252,11 +252,11 @@ public ConfigurationDto apply(final DeviceMessageLog deviceMessageLog) configuration.setSummerTimeDetails( new DaylightSavingTimeTransition(TIME_ZONE_AMSTERDAM, summerTimeDetails) .getDateTimeForNextTransition() - .toDateTime(DateTimeZone.UTC)); + .withZoneSameInstant(ZoneId.of("UTC"))); configuration.setWinterTimeDetails( new DaylightSavingTimeTransition(TIME_ZONE_AMSTERDAM, winterTimeDetails) .getDateTimeForNextTransition() - .toDateTime(DateTimeZone.UTC)); + .withZoneSameInstant(ZoneId.of("UTC"))); configuration.setNtpHost(ntpHost); configuration.setNtpEnabled(ntpEnabled); configuration.setNtpSyncInterval(ntpSyncInterval); diff --git a/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/services/commands/Iec61850TransitionCommand.java b/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/services/commands/Iec61850TransitionCommand.java index 307c8617882..4da078394f5 100644 --- a/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/services/commands/Iec61850TransitionCommand.java +++ b/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/main/java/org/opensmartgridplatform/adapter/protocol/iec61850/infra/networking/services/commands/Iec61850TransitionCommand.java @@ -6,7 +6,7 @@ import com.beanit.openiec61850.BdaBoolean; import com.beanit.openiec61850.Fc; -import org.joda.time.DateTime; +import java.time.ZonedDateTime; import org.opensmartgridplatform.adapter.protocol.iec61850.domain.valueobjects.DeviceMessageLog; import org.opensmartgridplatform.adapter.protocol.iec61850.exceptions.ProtocolAdapterException; import org.opensmartgridplatform.adapter.protocol.iec61850.infra.networking.Iec61850Client; @@ -27,7 +27,7 @@ public class Iec61850TransitionCommand { private static final Logger LOGGER = LoggerFactory.getLogger(Iec61850TransitionCommand.class); - private DeviceMessageLoggingService loggingService; + private final DeviceMessageLoggingService loggingService; public Iec61850TransitionCommand(final DeviceMessageLoggingService loggingService) { this.loggingService = loggingService; @@ -43,7 +43,7 @@ public void transitionDevice( "device: {}, transition: {}", deviceConnection.getDeviceIdentification(), transitionType); final boolean controlValueForTransition = transitionType.equals(TransitionTypeDto.DAY_NIGHT); - final DateTime dateTime = transitionMessageDataContainer.getDateTime(); + final ZonedDateTime dateTime = transitionMessageDataContainer.getDateTime(); if (dateTime != null) { LOGGER.warn( "device: {}, setting date/time {} for transition {} not supported", diff --git a/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/test/java/org/opensmartgridplatform/adapter/protocol/iec61850/domain/valueobjects/DaylightSavingTimeTransitionTest.java b/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/test/java/org/opensmartgridplatform/adapter/protocol/iec61850/domain/valueobjects/DaylightSavingTimeTransitionTest.java index 4f38b4e97f6..f4475d200a9 100644 --- a/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/test/java/org/opensmartgridplatform/adapter/protocol/iec61850/domain/valueobjects/DaylightSavingTimeTransitionTest.java +++ b/osgp/protocol-adapter-iec61850/osgp-protocol-adapter-iec61850/src/test/java/org/opensmartgridplatform/adapter/protocol/iec61850/domain/valueobjects/DaylightSavingTimeTransitionTest.java @@ -7,12 +7,12 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; +import java.time.ZoneId; +import java.time.ZonedDateTime; import org.junit.jupiter.api.Test; public class DaylightSavingTimeTransitionTest { - public static final DateTimeZone amsterdamDTZ = DateTimeZone.forID("Europe/Amsterdam"); + public static final ZoneId amsterdamDTZ = ZoneId.of("Europe/Amsterdam"); public static final String DST_START_MWD_AMSTERDAM = "M3.5.0/2"; public static final String DST_END_MWD_AMSTERDAM = "M10.5.0/3"; @@ -29,21 +29,21 @@ public class DaylightSavingTimeTransitionTest { public static final String DST_START_J_IGNORING_FEB29_AMSTERDAM_2016 = "J86/2"; public static final String DST_END_J_IGNORING_FEB29_AMSTERDAM_2016 = "J303/3"; - public static final DateTime DST_START_DATE_TIME_AMSTERDAM_2015 = - DateTime.parse("2015-03-29T02:00:00.000+01:00"); - public static final DateTime DST_END_DATE_TIME_AMSTERDAM_2015 = - DateTime.parse("2015-10-25T03:00:00.000+02:00"); - public static final DateTime DST_START_DATE_TIME_AMSTERDAM_2016 = - DateTime.parse("2016-03-27T02:00:00.000+01:00"); - public static final DateTime DST_END_DATE_TIME_AMSTERDAM_2016 = - DateTime.parse("2016-10-30T03:00:00.000+02:00"); + public static final ZonedDateTime DST_START_DATE_TIME_AMSTERDAM_2015 = + ZonedDateTime.parse("2015-03-29T02:00:00.000+01:00"); + public static final ZonedDateTime DST_END_DATE_TIME_AMSTERDAM_2015 = + ZonedDateTime.parse("2015-10-25T03:00:00.000+02:00"); + public static final ZonedDateTime DST_START_DATE_TIME_AMSTERDAM_2016 = + ZonedDateTime.parse("2016-03-27T02:00:00.000+01:00"); + public static final ZonedDateTime DST_END_DATE_TIME_AMSTERDAM_2016 = + ZonedDateTime.parse("2016-10-30T03:00:00.000+02:00"); @Test public void testDaylightSavingTimeStartAmsterdam2015DayOfWeekOfMonth() { final DaylightSavingTimeTransition dstTransition = new DaylightSavingTimeTransition(DST_START_MWD_AMSTERDAM); - assertThat(dstTransition.getDateTimeForYear(2015).toDateTime(DateTimeZone.UTC)) - .isEqualTo(DST_START_DATE_TIME_AMSTERDAM_2015.toDateTime(DateTimeZone.UTC)); + assertThat(dstTransition.getDateTimeForYear(2015).withZoneSameInstant(ZoneId.of("UTC"))) + .isEqualTo(DST_START_DATE_TIME_AMSTERDAM_2015.withZoneSameInstant(ZoneId.of("UTC"))); assertThat( DaylightSavingTimeTransition.forDateTimeAccordingToFormat( @@ -57,8 +57,8 @@ public void testDaylightSavingTimeStartAmsterdam2015DayOfWeekOfMonth() { public void testDaylightSavingTimeEndAmsterdam2015DayOfWeekOfMonth() { final DaylightSavingTimeTransition dstTransition = new DaylightSavingTimeTransition(DST_END_MWD_AMSTERDAM); - assertThat(dstTransition.getDateTimeForYear(2015).toDateTime(DateTimeZone.UTC)) - .isEqualTo(DST_END_DATE_TIME_AMSTERDAM_2015.toDateTime(DateTimeZone.UTC)); + assertThat(dstTransition.getDateTimeForYear(2015).withZoneSameInstant(ZoneId.of("UTC"))) + .isEqualTo(DST_END_DATE_TIME_AMSTERDAM_2015.withZoneSameInstant(ZoneId.of("UTC"))); assertThat( DaylightSavingTimeTransition.forDateTimeAccordingToFormat( @@ -72,8 +72,8 @@ public void testDaylightSavingTimeEndAmsterdam2015DayOfWeekOfMonth() { public void testDaylightSavingTimeStartAmsterdam2015JulianCountingFeb29() { final DaylightSavingTimeTransition dstTransition = new DaylightSavingTimeTransition(DST_START_J_COUNTING_FEB29_AMSTERDAM_2015); - assertThat(dstTransition.getDateTimeForYear(2015).toDateTime(DateTimeZone.UTC)) - .isEqualTo(DST_START_DATE_TIME_AMSTERDAM_2015.toDateTime(DateTimeZone.UTC)); + assertThat(dstTransition.getDateTimeForYear(2015).withZoneSameInstant(ZoneId.of("UTC"))) + .isEqualTo(DST_START_DATE_TIME_AMSTERDAM_2015.withZoneSameInstant(ZoneId.of("UTC"))); assertThat( DaylightSavingTimeTransition.forDateTimeAccordingToFormat( @@ -88,8 +88,8 @@ public void testDaylightSavingTimeStartAmsterdam2015JulianCountingFeb29() { public void testDaylightSavingTimeEndAmsterdam2015JulianCountingFeb29() { final DaylightSavingTimeTransition dstTransition = new DaylightSavingTimeTransition(DST_END_J_COUNTING_FEB29_AMSTERDAM_2015); - assertThat(dstTransition.getDateTimeForYear(2015).toDateTime(DateTimeZone.UTC)) - .isEqualTo(DST_END_DATE_TIME_AMSTERDAM_2015.toDateTime(DateTimeZone.UTC)); + assertThat(dstTransition.getDateTimeForYear(2015).withZoneSameInstant(ZoneId.of("UTC"))) + .isEqualTo(DST_END_DATE_TIME_AMSTERDAM_2015.withZoneSameInstant(ZoneId.of("UTC"))); assertThat( DaylightSavingTimeTransition.forDateTimeAccordingToFormat( @@ -104,8 +104,8 @@ public void testDaylightSavingTimeEndAmsterdam2015JulianCountingFeb29() { public void testDaylightSavingTimeStartAmsterdam2015JulianIgnoringFeb29() { final DaylightSavingTimeTransition dstTransition = new DaylightSavingTimeTransition(DST_START_J_IGNORING_FEB29_AMSTERDAM_2015); - assertThat(dstTransition.getDateTimeForYear(2015).toDateTime(DateTimeZone.UTC)) - .isEqualTo(DST_START_DATE_TIME_AMSTERDAM_2015.toDateTime(DateTimeZone.UTC)); + assertThat(dstTransition.getDateTimeForYear(2015).withZoneSameInstant(ZoneId.of("UTC"))) + .isEqualTo(DST_START_DATE_TIME_AMSTERDAM_2015.withZoneSameInstant(ZoneId.of("UTC"))); assertThat( DaylightSavingTimeTransition.forDateTimeAccordingToFormat( @@ -120,8 +120,8 @@ public void testDaylightSavingTimeStartAmsterdam2015JulianIgnoringFeb29() { public void testDaylightSavingTimeEndAmsterdam2015JulianIgnoringFeb29() { final DaylightSavingTimeTransition dstTransition = new DaylightSavingTimeTransition(DST_END_J_IGNORING_FEB29_AMSTERDAM_2015); - assertThat(dstTransition.getDateTimeForYear(2015).toDateTime(DateTimeZone.UTC)) - .isEqualTo(DST_END_DATE_TIME_AMSTERDAM_2015.toDateTime(DateTimeZone.UTC)); + assertThat(dstTransition.getDateTimeForYear(2015).withZoneSameInstant(ZoneId.of("UTC"))) + .isEqualTo(DST_END_DATE_TIME_AMSTERDAM_2015.withZoneSameInstant(ZoneId.of("UTC"))); assertThat( DaylightSavingTimeTransition.forDateTimeAccordingToFormat( @@ -136,8 +136,8 @@ public void testDaylightSavingTimeEndAmsterdam2015JulianIgnoringFeb29() { public void testDaylightSavingTimeStartAmsterdam2016DayOfWeekOfMonth() { final DaylightSavingTimeTransition dstTransition = new DaylightSavingTimeTransition(DST_START_MWD_AMSTERDAM); - assertThat(dstTransition.getDateTimeForYear(2016).toDateTime(DateTimeZone.UTC)) - .isEqualTo(DST_START_DATE_TIME_AMSTERDAM_2016.toDateTime(DateTimeZone.UTC)); + assertThat(dstTransition.getDateTimeForYear(2016).withZoneSameInstant(ZoneId.of("UTC"))) + .isEqualTo(DST_START_DATE_TIME_AMSTERDAM_2016.withZoneSameInstant(ZoneId.of("UTC"))); assertThat( DaylightSavingTimeTransition.forDateTimeAccordingToFormat( @@ -151,8 +151,8 @@ public void testDaylightSavingTimeStartAmsterdam2016DayOfWeekOfMonth() { public void testDaylightSavingTimeEndAmsterdam2016DayOfWeekOfMonth() { final DaylightSavingTimeTransition dstTransition = new DaylightSavingTimeTransition(DST_END_MWD_AMSTERDAM); - assertThat(dstTransition.getDateTimeForYear(2016).toDateTime(DateTimeZone.UTC)) - .isEqualTo(DST_END_DATE_TIME_AMSTERDAM_2016.toDateTime(DateTimeZone.UTC)); + assertThat(dstTransition.getDateTimeForYear(2016).withZoneSameInstant(ZoneId.of("UTC"))) + .isEqualTo(DST_END_DATE_TIME_AMSTERDAM_2016.withZoneSameInstant(ZoneId.of("UTC"))); assertThat( DaylightSavingTimeTransition.forDateTimeAccordingToFormat( @@ -166,8 +166,8 @@ public void testDaylightSavingTimeEndAmsterdam2016DayOfWeekOfMonth() { public void testDaylightSavingTimeStartAmsterdam2016JulianCountingFeb29() { final DaylightSavingTimeTransition dstTransition = new DaylightSavingTimeTransition(DST_START_J_COUNTING_FEB29_AMSTERDAM_2016); - assertThat(dstTransition.getDateTimeForYear(2016).toDateTime(DateTimeZone.UTC)) - .isEqualTo(DST_START_DATE_TIME_AMSTERDAM_2016.toDateTime(DateTimeZone.UTC)); + assertThat(dstTransition.getDateTimeForYear(2016).withZoneSameInstant(ZoneId.of("UTC"))) + .isEqualTo(DST_START_DATE_TIME_AMSTERDAM_2016.withZoneSameInstant(ZoneId.of("UTC"))); assertThat( DaylightSavingTimeTransition.forDateTimeAccordingToFormat( @@ -182,8 +182,8 @@ public void testDaylightSavingTimeStartAmsterdam2016JulianCountingFeb29() { public void testDaylightSavingTimeEndAmsterdam2016JulianCountingFeb29() { final DaylightSavingTimeTransition dstTransition = new DaylightSavingTimeTransition(DST_END_J_COUNTING_FEB29_AMSTERDAM_2016); - assertThat(dstTransition.getDateTimeForYear(2016).toDateTime(DateTimeZone.UTC)) - .isEqualTo(DST_END_DATE_TIME_AMSTERDAM_2016.toDateTime(DateTimeZone.UTC)); + assertThat(dstTransition.getDateTimeForYear(2016).withZoneSameInstant(ZoneId.of("UTC"))) + .isEqualTo(DST_END_DATE_TIME_AMSTERDAM_2016.withZoneSameInstant(ZoneId.of("UTC"))); assertThat( DaylightSavingTimeTransition.forDateTimeAccordingToFormat( @@ -198,8 +198,8 @@ public void testDaylightSavingTimeEndAmsterdam2016JulianCountingFeb29() { public void testDaylightSavingTimeStartAmsterdam2016JulianIgnoringFeb29() { final DaylightSavingTimeTransition dstTransition = new DaylightSavingTimeTransition(DST_START_J_IGNORING_FEB29_AMSTERDAM_2016); - assertThat(dstTransition.getDateTimeForYear(2016).toDateTime(DateTimeZone.UTC)) - .isEqualTo(DST_START_DATE_TIME_AMSTERDAM_2016.toDateTime(DateTimeZone.UTC)); + assertThat(dstTransition.getDateTimeForYear(2016).withZoneSameInstant(ZoneId.of("UTC"))) + .isEqualTo(DST_START_DATE_TIME_AMSTERDAM_2016.withZoneSameInstant(ZoneId.of("UTC"))); assertThat( DaylightSavingTimeTransition.forDateTimeAccordingToFormat( @@ -214,8 +214,8 @@ public void testDaylightSavingTimeStartAmsterdam2016JulianIgnoringFeb29() { public void testDaylightSavingTimeEndAmsterdam2016JulianIgnoringFeb29() { final DaylightSavingTimeTransition dstTransition = new DaylightSavingTimeTransition(DST_END_J_IGNORING_FEB29_AMSTERDAM_2016); - assertThat(dstTransition.getDateTimeForYear(2016).toDateTime(DateTimeZone.UTC)) - .isEqualTo(DST_END_DATE_TIME_AMSTERDAM_2016.toDateTime(DateTimeZone.UTC)); + assertThat(dstTransition.getDateTimeForYear(2016).withZoneSameInstant(ZoneId.of("UTC"))) + .isEqualTo(DST_END_DATE_TIME_AMSTERDAM_2016.withZoneSameInstant(ZoneId.of("UTC"))); assertThat( DaylightSavingTimeTransition.forDateTimeAccordingToFormat( @@ -438,38 +438,38 @@ public void testGetDateTime() { assertThat( DaylightSavingTimeTransition.DstTransitionFormat.JULIAN_DAY_IGNORING_FEBRUARY_29 .getDateTime(amsterdamDTZ, DST_START_J_IGNORING_FEB29_AMSTERDAM_2015, 2015)) - .isEqualByComparingTo(DST_START_DATE_TIME_AMSTERDAM_2015); + .isEqualTo(DST_START_DATE_TIME_AMSTERDAM_2015); assertThat( DaylightSavingTimeTransition.DstTransitionFormat.JULIAN_DAY_COUNTING_FEBRUARY_29 .getDateTime(amsterdamDTZ, DST_START_J_COUNTING_FEB29_AMSTERDAM_2015, 2015)) - .isEqualByComparingTo(DST_START_DATE_TIME_AMSTERDAM_2015); + .isEqualTo(DST_START_DATE_TIME_AMSTERDAM_2015); assertThat( DaylightSavingTimeTransition.DstTransitionFormat.DAY_OF_WEEK_OF_MONTH.getDateTime( amsterdamDTZ, DST_START_MWD_AMSTERDAM, 2015)) - .isEqualByComparingTo(DST_START_DATE_TIME_AMSTERDAM_2015); + .isEqualTo(DST_START_DATE_TIME_AMSTERDAM_2015); assertThat( DaylightSavingTimeTransition.DstTransitionFormat.JULIAN_DAY_IGNORING_FEBRUARY_29 .getDateTime(amsterdamDTZ, "J327", 2015)) - .isEqualByComparingTo(DateTime.parse("2015-11-23T00:00:00.000+01:00")); + .isEqualTo(ZonedDateTime.parse("2015-11-23T00:00:00.000+01:00")); assertThat( DaylightSavingTimeTransition.DstTransitionFormat.JULIAN_DAY_COUNTING_FEBRUARY_29 .getDateTime(amsterdamDTZ, "326", 2015)) - .isEqualByComparingTo(DateTime.parse("2015-11-23T00:00:00.000+01:00")); + .isEqualTo(ZonedDateTime.parse("2015-11-23T00:00:00.000+01:00")); assertThat( DaylightSavingTimeTransition.DstTransitionFormat.DAY_OF_WEEK_OF_MONTH.getDateTime( amsterdamDTZ, "M11.4.1", 2015)) - .isEqualByComparingTo(DateTime.parse("2015-11-23T00:00:00.000+01:00")); + .isEqualTo(ZonedDateTime.parse("2015-11-23T00:00:00.000+01:00")); assertThat( DaylightSavingTimeTransition.DstTransitionFormat.JULIAN_DAY_IGNORING_FEBRUARY_29 .getDateTime(amsterdamDTZ, "J1", 2016)) - .isEqualByComparingTo(DateTime.parse("2016-01-1T00:00:00.000+01:00")); + .isEqualTo(ZonedDateTime.parse("2016-01-01T00:00:00.000+01:00")); } @Test public void testGetDaylightSavingTimeTransition() { - final DateTime midNight = DateTime.parse("2015-01-1T00:00:00.000+01:00"); + final ZonedDateTime midNight = ZonedDateTime.parse("2015-01-01T00:00:00.000+01:00"); assertThat( DaylightSavingTimeTransition.DstTransitionFormat.JULIAN_DAY_IGNORING_FEBRUARY_29 .getDaylightSavingTimeTransition(midNight) @@ -541,18 +541,20 @@ public void testGetTime() { @Test public void testGetDateTimeForNextTransition() { - final DateTime dateTimeBeforeDay30 = DateTime.parse("2015-01-01T00:00:00.000+01:00"); - final DateTime dateTimeAfterDay30 = DateTime.parse("2015-06-01T00:00:00.000+01:00"); - final DateTime dateTimeOfDay30ThisYear = DateTime.parse("2015-01-31T00:00:00.000+01:00"); - final DateTime dateTimeOfDay30NextYear = DateTime.parse("2016-01-31T00:00:00.000+01:00"); + final ZonedDateTime dateTimeBeforeDay30 = ZonedDateTime.parse("2015-01-01T00:00:00.000+01:00"); + final ZonedDateTime dateTimeAfterDay30 = ZonedDateTime.parse("2015-06-01T00:00:00.000+01:00"); + final ZonedDateTime dateTimeOfDay30ThisYear = + ZonedDateTime.parse("2015-01-31T00:00:00.000+01:00"); + final ZonedDateTime dateTimeOfDay30NextYear = + ZonedDateTime.parse("2016-01-31T00:00:00.000+01:00"); assertThat( (new DaylightSavingTimeTransition("30")) .getDateTimeForNextTransition(dateTimeBeforeDay30)) - .isEqualByComparingTo(dateTimeOfDay30ThisYear); + .isEqualTo(dateTimeOfDay30ThisYear); assertThat( (new DaylightSavingTimeTransition("30")) .getDateTimeForNextTransition(dateTimeAfterDay30)) - .isEqualByComparingTo(dateTimeOfDay30NextYear); + .isEqualTo(dateTimeOfDay30NextYear); } } diff --git a/osgp/protocol-adapter-iec61850/parent-pa-iec61850/pom.xml b/osgp/protocol-adapter-iec61850/parent-pa-iec61850/pom.xml index 64a6b0cd5bd..7d836316091 100644 --- a/osgp/protocol-adapter-iec61850/parent-pa-iec61850/pom.xml +++ b/osgp/protocol-adapter-iec61850/parent-pa-iec61850/pom.xml @@ -18,7 +18,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform super-osgp - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../../../super/pom.xml diff --git a/osgp/protocol-adapter-iec61850/pom.xml b/osgp/protocol-adapter-iec61850/pom.xml index f0fd7a2d079..6e0509962a4 100644 --- a/osgp/protocol-adapter-iec61850/pom.xml +++ b/osgp/protocol-adapter-iec61850/pom.xml @@ -12,7 +12,7 @@ SPDX-License-Identifier: Apache-2.0 protocol-adapter-iec61850 org.opensmartgridplatform - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT pom protocol-adapter-iec61850 diff --git a/osgp/protocol-adapter-iec61850/protocol-simulator-iec61850/pom.xml b/osgp/protocol-adapter-iec61850/protocol-simulator-iec61850/pom.xml index 232831ae84d..85575897fdf 100644 --- a/osgp/protocol-adapter-iec61850/protocol-simulator-iec61850/pom.xml +++ b/osgp/protocol-adapter-iec61850/protocol-simulator-iec61850/pom.xml @@ -38,12 +38,12 @@ SPDX-License-Identifier: Apache-2.0 ${maven.site.distributionManagement.site.url} - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT org.springframework.boot spring-boot-starter-parent - 2.7.2 + 2.7.18 @@ -52,7 +52,7 @@ SPDX-License-Identifier: Apache-2.0 UTF-8 17 - 2.1.3.RELEASE + 2.7.18 1.8.0 3.0.0 diff --git a/osgp/protocol-adapter-mqtt/osgp-protocol-adapter-mqtt/pom.xml b/osgp/protocol-adapter-mqtt/osgp-protocol-adapter-mqtt/pom.xml index 85c60644149..293a0a74c90 100644 --- a/osgp/protocol-adapter-mqtt/osgp-protocol-adapter-mqtt/pom.xml +++ b/osgp/protocol-adapter-mqtt/osgp-protocol-adapter-mqtt/pom.xml @@ -13,7 +13,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-pa-mqtt - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-pa-mqtt/pom.xml diff --git a/osgp/protocol-adapter-mqtt/osgp-protocol-adapter-mqtt/src/main/java/org/opensmartgridplatform/adapter/protocol/mqtt/application/config/ApplicationContext.java b/osgp/protocol-adapter-mqtt/osgp-protocol-adapter-mqtt/src/main/java/org/opensmartgridplatform/adapter/protocol/mqtt/application/config/ApplicationContext.java index a73c7c27bf7..08c2fb655f5 100644 --- a/osgp/protocol-adapter-mqtt/osgp-protocol-adapter-mqtt/src/main/java/org/opensmartgridplatform/adapter/protocol/mqtt/application/config/ApplicationContext.java +++ b/osgp/protocol-adapter-mqtt/osgp-protocol-adapter-mqtt/src/main/java/org/opensmartgridplatform/adapter/protocol/mqtt/application/config/ApplicationContext.java @@ -4,9 +4,8 @@ package org.opensmartgridplatform.adapter.protocol.mqtt.application.config; -import org.joda.time.DateTime; -import org.joda.time.DateTimeConstants; -import org.joda.time.DateTimeZone; +import java.time.Instant; +import java.time.ZoneId; import org.opensmartgridplatform.shared.application.config.AbstractConfig; import org.opensmartgridplatform.shared.config.MetricsConfig; import org.opensmartgridplatform.shared.domain.services.CorrelationIdProviderService; @@ -28,11 +27,13 @@ public class ApplicationContext extends AbstractConfig { private static final String LOCAL_TIME_ZONE_IDENTIFIER = "Europe/Paris"; - private static final DateTimeZone LOCAL_TIME_ZONE = - DateTimeZone.forID(LOCAL_TIME_ZONE_IDENTIFIER); + private static final ZoneId LOCAL_TIME_ZONE = ZoneId.of(LOCAL_TIME_ZONE_IDENTIFIER); + + public static final int SECONDS_PER_MINUTE = 60; + private static final int TIME_ZONE_OFFSET_MINUTES = - LOCAL_TIME_ZONE.getStandardOffset(new DateTime().getMillis()) - / DateTimeConstants.MILLIS_PER_MINUTE; + LOCAL_TIME_ZONE.getRules().getStandardOffset(Instant.now()).getTotalSeconds() + / SECONDS_PER_MINUTE; @Bean public String localTimeZoneIdentifier() { @@ -40,7 +41,7 @@ public String localTimeZoneIdentifier() { } @Bean - public DateTimeZone localTimeZone() { + public ZoneId localTimeZone() { return LOCAL_TIME_ZONE; } diff --git a/osgp/protocol-adapter-mqtt/osgp-protocol-simulator-mqtt/pom.xml b/osgp/protocol-adapter-mqtt/osgp-protocol-simulator-mqtt/pom.xml index 3a2e755185e..87f99687167 100644 --- a/osgp/protocol-adapter-mqtt/osgp-protocol-simulator-mqtt/pom.xml +++ b/osgp/protocol-adapter-mqtt/osgp-protocol-simulator-mqtt/pom.xml @@ -14,13 +14,13 @@ SPDX-License-Identifier: Apache-2.0 org.springframework.boot spring-boot-starter-parent - 2.7.2 + 2.7.18 org.opensmartgridplatform osgp-protocol-simulator-mqtt - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT war osgp-protocol-simulator-mqtt Simulator for MQTT Protocol. diff --git a/osgp/protocol-adapter-mqtt/parent-pa-mqtt/pom.xml b/osgp/protocol-adapter-mqtt/parent-pa-mqtt/pom.xml index d1f6d191298..91195864733 100644 --- a/osgp/protocol-adapter-mqtt/parent-pa-mqtt/pom.xml +++ b/osgp/protocol-adapter-mqtt/parent-pa-mqtt/pom.xml @@ -13,7 +13,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform super-osgp - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../../../super/pom.xml diff --git a/osgp/protocol-adapter-mqtt/pom.xml b/osgp/protocol-adapter-mqtt/pom.xml index e0d27555131..ffaaf95c32b 100644 --- a/osgp/protocol-adapter-mqtt/pom.xml +++ b/osgp/protocol-adapter-mqtt/pom.xml @@ -12,7 +12,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform protocol-adapter-mqtt - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT pom protocol-adapter-mqtt diff --git a/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/pom.xml b/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/pom.xml index a2ba245b8bb..3c819f520bd 100644 --- a/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/pom.xml +++ b/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/pom.xml @@ -17,7 +17,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-pa-oslp - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-pa-oslp/pom.xml diff --git a/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/application/config/ApplicationContext.java b/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/application/config/ApplicationContext.java index 0d40857c518..73a334e3a38 100644 --- a/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/application/config/ApplicationContext.java +++ b/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/application/config/ApplicationContext.java @@ -10,9 +10,8 @@ import io.micrometer.jmx.JmxMeterRegistry; import io.netty.util.internal.logging.InternalLoggerFactory; import io.netty.util.internal.logging.Slf4JLoggerFactory; -import org.joda.time.DateTime; -import org.joda.time.DateTimeConstants; -import org.joda.time.DateTimeZone; +import java.time.Instant; +import java.time.ZoneId; import org.opensmartgridplatform.adapter.protocol.oslp.elster.device.FirmwareLocation; import org.opensmartgridplatform.shared.application.config.AbstractConfig; import org.opensmartgridplatform.shared.application.config.PagingSettings; @@ -44,11 +43,10 @@ public class ApplicationContext extends AbstractConfig { private static final String PROPERTY_NAME_FIRMWARE_PATH = "firmware.path"; private static final String PROPERTY_NAME_PAGING_MAXIMUM_PAGE_SIZE = "paging.maximum.pagesize"; private static final String PROPERTY_NAME_PAGING_DEFAULT_PAGE_SIZE = "paging.default.pagesize"; - private static final String PROPERTY_NAME_LOCAL_TIME_ZONE_IDENTIFIER = "local.time.zone"; - private static final String PROPERTY_NAME_DEVICE_PENDINGSETSCHEDULEREQUEST_EXPIRES_IN_MINUTES = "device.pendingsetschedulerequest.expires_in_minutes"; + public static final int SECONDS_PER_MINUTE = 60; public ApplicationContext() { InternalLoggerFactory.setDefaultFactory(Slf4JLoggerFactory.INSTANCE); @@ -97,13 +95,13 @@ public String localTimeZoneIdentifier() { } @Bean - public DateTimeZone localTimeZone() { - return DateTimeZone.forID(this.localTimeZoneIdentifier()); + public ZoneId localTimeZone() { + return ZoneId.of(this.localTimeZoneIdentifier()); } @Bean public Integer timeZoneOffsetMinutes() { - return this.localTimeZone().getStandardOffset(new DateTime().getMillis()) - / DateTimeConstants.MILLIS_PER_MINUTE; + return this.localTimeZone().getRules().getStandardOffset(Instant.now()).getTotalSeconds() + / SECONDS_PER_MINUTE; } } diff --git a/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/application/mapping/ConfigurationToOslpSetConfigurationRequestConverter.java b/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/application/mapping/ConfigurationToOslpSetConfigurationRequestConverter.java index ff655b57db9..5bb88158d3f 100644 --- a/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/application/mapping/ConfigurationToOslpSetConfigurationRequestConverter.java +++ b/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/application/mapping/ConfigurationToOslpSetConfigurationRequestConverter.java @@ -7,10 +7,10 @@ import com.google.protobuf.ByteString; import java.net.InetAddress; import java.net.UnknownHostException; +import java.time.ZonedDateTime; import ma.glasnost.orika.CustomConverter; import ma.glasnost.orika.MappingContext; import ma.glasnost.orika.metadata.Type; -import org.joda.time.DateTime; import org.opensmartgridplatform.dto.valueobjects.ConfigurationDto; import org.opensmartgridplatform.oslp.Oslp; import org.opensmartgridplatform.oslp.Oslp.SetConfigurationRequest; @@ -273,14 +273,14 @@ private ByteString convertTextualIpAddressToByteString(final String ipAddress) { * Default value for summer time: 0360100 Default value for summer time: * 1060200 */ - private String convertSummerTimeWinterTimeDetails(final DateTime dateTime) { + private String convertSummerTimeWinterTimeDetails(final ZonedDateTime dateTime) { LOGGER.info("dateTime: {}", dateTime); final String formattedTimeDetails = - String.format("%02d", dateTime.getMonthOfYear()) - + (dateTime.getDayOfWeek() - 1) - + String.format("%02d", dateTime.getHourOfDay()) - + String.format("%02d", dateTime.getMinuteOfHour()); + String.format("%02d", dateTime.getMonthValue()) + + (dateTime.getDayOfWeek().getValue() - 1) + + String.format("%02d", dateTime.getHour()) + + String.format("%02d", dateTime.getMinute()); LOGGER.info("formattedTimeDetails: {}", formattedTimeDetails); diff --git a/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/application/mapping/OslpGetConfigurationResponseToConfigurationConverter.java b/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/application/mapping/OslpGetConfigurationResponseToConfigurationConverter.java index 04953ff35ff..3e57657dafc 100644 --- a/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/application/mapping/OslpGetConfigurationResponseToConfigurationConverter.java +++ b/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/application/mapping/OslpGetConfigurationResponseToConfigurationConverter.java @@ -5,6 +5,8 @@ package org.opensmartgridplatform.adapter.protocol.oslp.elster.application.mapping; import com.google.protobuf.ByteString; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.util.ArrayList; import ma.glasnost.orika.CustomConverter; import ma.glasnost.orika.MappingContext; @@ -70,10 +72,10 @@ public ConfigurationDto convert( this.setRelayLinking(source, configuration); configuration.setRelayRefreshing(source.getRelayRefreshing()); - final DateTime summerTimeDetails = + final ZonedDateTime summerTimeDetails = this.convertSummerTimeWinterTimeDetails(source.getSummerTimeDetails()); configuration.setSummerTimeDetails(summerTimeDetails); - final DateTime winterTimeDetails = + final ZonedDateTime winterTimeDetails = this.convertSummerTimeWinterTimeDetails(source.getWinterTimeDetails()); configuration.setWinterTimeDetails(winterTimeDetails); @@ -166,7 +168,7 @@ private String convertIpAddress(final ByteString byteString) { * Default value for summer time: 0360100 Default value for summer time: * 1060200 */ - private DateTime convertSummerTimeWinterTimeDetails(final String timeDetails) { + private ZonedDateTime convertSummerTimeWinterTimeDetails(final String timeDetails) { final int month = Integer.parseInt(timeDetails.substring(0, 2)); final int day = Integer.parseInt(timeDetails.substring(2, 3)); final int hour = Integer.parseInt(timeDetails.substring(3, 5)); @@ -176,7 +178,8 @@ private DateTime convertSummerTimeWinterTimeDetails(final String timeDetails) { final int year = DateTime.now().getYear(); final int dayOfMonth = this.getLastDayOfMonth(month, day); - final DateTime dateTime = new DateTime(year, month, dayOfMonth, hour, minutes); + final ZonedDateTime dateTime = + ZonedDateTime.of(year, month, dayOfMonth, hour, minutes, 0, 0, ZoneId.systemDefault()); LOGGER.info("dateTime: {}", dateTime); diff --git a/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/application/services/DeviceManagementService.java b/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/application/services/DeviceManagementService.java index 4fe6a2b0b5b..e419efc14dd 100644 --- a/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/application/services/DeviceManagementService.java +++ b/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/application/services/DeviceManagementService.java @@ -4,13 +4,12 @@ package org.opensmartgridplatform.adapter.protocol.oslp.elster.application.services; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; import org.apache.commons.lang3.StringUtils; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.joda.time.format.DateTimeFormat; -import org.joda.time.format.DateTimeFormatter; import org.opensmartgridplatform.adapter.protocol.oslp.elster.application.services.oslp.OslpDeviceSettingsService; import org.opensmartgridplatform.adapter.protocol.oslp.elster.application.services.oslp.PendingSetScheduleRequestService; import org.opensmartgridplatform.adapter.protocol.oslp.elster.device.DeviceRequest; @@ -48,6 +47,8 @@ public class DeviceManagementService { private static final Logger LOGGER = LoggerFactory.getLogger(DeviceManagementService.class); + public static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyyMMddHHmmss Z"); + @Autowired private OslpDeviceSettingsService oslpDeviceSettingsService; @Autowired private OsgpRequestMessageSender osgpRequestMessageSender; @@ -93,13 +94,12 @@ private EventNotificationDto createEventNotificationDto( timestamp); // Convert timestamp to DateTime. - final DateTime dateTime; + final ZonedDateTime dateTime; if (StringUtils.isEmpty(timestamp)) { - dateTime = DateTime.now(); + dateTime = ZonedDateTime.now(); LOGGER.info("timestamp is empty, using DateTime.now(): {}", dateTime); } else { - final DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyyyMMddHHmmss Z"); - dateTime = dateTimeFormatter.withOffsetParsed().parseDateTime(timestamp.concat(" +0000")); + dateTime = ZonedDateTime.parse(timestamp.concat(" +0000"), FORMATTER); LOGGER.info("parsed timestamp from string: {} to DateTime: {}", timestamp, dateTime); } @@ -130,8 +130,8 @@ public void addEventNotifications( // Hack for faulty firmware version. RTC_NOT_SET event can contain // illegal timestamp value of 20000000xxxxxx. if (!StringUtils.isEmpty(timestamp) && timestamp.startsWith("20000000")) { - final DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyyyMMddHHmmss"); - timestamp = DateTime.now().withZone(DateTimeZone.UTC).toString(dateTimeFormatter); + final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); + timestamp = dateTimeFormatter.format(ZonedDateTime.now(ZoneId.of("UTC"))); LOGGER.info("Using DateTime.now() instead of '20000000xxxxxx', value is: {}", timestamp); } final EventNotificationDto dto = @@ -291,7 +291,7 @@ private MessageMetadata getMessageMetadataFromDeviceRequest(final DeviceRequest .withMessageType(deviceRequest.getMessageType()) .withDomain(deviceRequest.getDomain()) .withDomainVersion(deviceRequest.getDomainVersion()) - .withIpAddress(deviceRequest.getIpAddress()) + .withNetworkAddress(deviceRequest.getNetworkAddress()) .withMessagePriority(deviceRequest.getMessagePriority()) .withScheduled(deviceRequest.isScheduled()) .withRetryCount(deviceRequest.getRetryCount()) diff --git a/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/application/services/oslp/PendingSetScheduleRequestService.java b/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/application/services/oslp/PendingSetScheduleRequestService.java index ceb72074a4f..a608285bc99 100644 --- a/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/application/services/oslp/PendingSetScheduleRequestService.java +++ b/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/application/services/oslp/PendingSetScheduleRequestService.java @@ -4,8 +4,8 @@ package org.opensmartgridplatform.adapter.protocol.oslp.elster.application.services.oslp; +import java.time.Instant; import java.time.ZonedDateTime; -import java.util.Date; import java.util.List; import org.opensmartgridplatform.adapter.protocol.oslp.elster.domain.entities.PendingSetScheduleRequest; import org.opensmartgridplatform.adapter.protocol.oslp.elster.domain.repositories.PendingSetScheduleRequestRepository; @@ -49,7 +49,7 @@ public void remove(final PendingSetScheduleRequest pendingSetScheduleRequest) { public List getAllByDeviceIdentificationNotExpired( final String deviceIdentification) { - final Date currentDate = new Date(); + final Instant currentDate = Instant.now(); LOGGER.info( "get device by deviceIdentification {} and current time: {}", deviceIdentification, @@ -60,7 +60,7 @@ public List getAllByDeviceIdentificationNotExpired( } public List getAllByDeviceUidNotExpired(final String deviceUid) { - final Date currentDate = new Date(); + final Instant currentDate = Instant.now(); LOGGER.info("get device by deviceUid {} and current time: {}", deviceUid, currentDate); return this.pendingSetScheduleRequestRepository.findAllByDeviceUidAndExpiredAtIsAfter( @@ -74,11 +74,10 @@ public List getAll() { } public void removeExpiredPendingSetScheduleRequestRecords(final String deviceIdentification) { - final Date expireDateTime = - Date.from( - ZonedDateTime.now() - .minusMinutes(this.pendingSetScheduleRequestExpiresInMinutes) - .toInstant()); + final Instant expireDateTime = + ZonedDateTime.now() + .minusMinutes(this.pendingSetScheduleRequestExpiresInMinutes) + .toInstant(); LOGGER.info( "remove PendingSetScheduleRequest(s) for device {} and older than time: {}", diff --git a/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/device/DeviceRequest.java b/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/device/DeviceRequest.java index 2db06202ea2..c271b4091f9 100644 --- a/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/device/DeviceRequest.java +++ b/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/device/DeviceRequest.java @@ -4,12 +4,15 @@ package org.opensmartgridplatform.adapter.protocol.oslp.elster.device; +import java.io.Serial; import java.io.Serializable; import org.opensmartgridplatform.shared.infra.jms.MessageMetadata; import org.opensmartgridplatform.shared.wsheaderattribute.priority.MessagePriorityEnum; public class DeviceRequest implements Serializable { + @Serial private static final long serialVersionUID = -9137084878269344459L; + private final String organisationIdentification; private final String deviceIdentification; private final String correlationUid; @@ -17,7 +20,7 @@ public class DeviceRequest implements Serializable { private String domainVersion = null; private String messageType = null; private final int messagePriority; - private String ipAddress = null; + private String networkAddress = null; private int retryCount = 0; private boolean isScheduled = false; @@ -40,7 +43,7 @@ public DeviceRequest(final Builder builder) { this.domainVersion = builder.domainVersion; this.messageType = builder.messageType; this.messagePriority = builder.messagePriority; - this.ipAddress = builder.ipAddress; + this.networkAddress = builder.ipAddress; this.retryCount = builder.retryCount; this.isScheduled = builder.isScheduled; } @@ -65,7 +68,7 @@ public Builder messageMetaData(final MessageMetadata messageMetadata) { this.domainVersion = messageMetadata.getDomainVersion(); this.messageType = messageMetadata.getMessageType(); this.messagePriority = messageMetadata.getMessagePriority(); - this.ipAddress = messageMetadata.getIpAddress(); + this.ipAddress = messageMetadata.getNetworkAddress(); this.retryCount = messageMetadata.getRetryCount(); this.isScheduled = messageMetadata.isScheduled(); return this; @@ -158,8 +161,8 @@ public int getMessagePriority() { return this.messagePriority; } - public String getIpAddress() { - return this.ipAddress; + public String getNetworkAddress() { + return this.networkAddress; } public int getRetryCount() { diff --git a/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/domain/entities/PendingSetScheduleRequest.java b/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/domain/entities/PendingSetScheduleRequest.java index 92c5e3dd1a7..3a0c58872b9 100644 --- a/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/domain/entities/PendingSetScheduleRequest.java +++ b/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/domain/entities/PendingSetScheduleRequest.java @@ -4,7 +4,7 @@ package org.opensmartgridplatform.adapter.protocol.oslp.elster.domain.entities; -import java.util.Date; +import java.time.Instant; import javax.persistence.Column; import javax.persistence.Entity; import lombok.AllArgsConstructor; @@ -33,7 +33,7 @@ public class PendingSetScheduleRequest extends AbstractEntity { @Column(nullable = false) @Getter - private Date expiredAt; + private Instant expiredAt; @Column(nullable = false) @Getter diff --git a/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/domain/repositories/PendingSetScheduleRequestRepository.java b/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/domain/repositories/PendingSetScheduleRequestRepository.java index 3115c2cbbc2..786024f05b9 100644 --- a/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/domain/repositories/PendingSetScheduleRequestRepository.java +++ b/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/domain/repositories/PendingSetScheduleRequestRepository.java @@ -4,7 +4,7 @@ package org.opensmartgridplatform.adapter.protocol.oslp.elster.domain.repositories; -import java.util.Date; +import java.time.Instant; import java.util.List; import org.opensmartgridplatform.adapter.protocol.oslp.elster.domain.entities.PendingSetScheduleRequest; import org.springframework.data.jpa.repository.JpaRepository; @@ -15,11 +15,11 @@ public interface PendingSetScheduleRequestRepository extends JpaRepository { List findAllByDeviceIdentificationAndExpiredAtIsAfter( - String deviceIdentification, Date expiredAt); + String deviceIdentification, Instant expiredAt); List findAllByDeviceUidAndExpiredAtIsAfter( - String deviceUid, Date expiredAt); + String deviceUid, Instant expiredAt); void deleteAllByDeviceIdentificationAndExpiredAtIsBefore( - String deviceIdentification, Date expireDateTime); + String deviceIdentification, Instant expireDateTime); } diff --git a/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/infra/messaging/processors/PublicLightingSetScheduleRequestMessageProcessor.java b/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/infra/messaging/processors/PublicLightingSetScheduleRequestMessageProcessor.java index 626b106c5e0..93eff50bef8 100644 --- a/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/infra/messaging/processors/PublicLightingSetScheduleRequestMessageProcessor.java +++ b/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/infra/messaging/processors/PublicLightingSetScheduleRequestMessageProcessor.java @@ -5,8 +5,8 @@ package org.opensmartgridplatform.adapter.protocol.oslp.elster.infra.messaging.processors; import java.io.IOException; +import java.time.Instant; import java.time.ZonedDateTime; -import java.util.Date; import java.util.List; import javax.jms.JMSException; import javax.jms.ObjectMessage; @@ -337,11 +337,8 @@ private void handleSetScheduleSetRebootResponse(final SetScheduleDeviceRequest d this.oslpDeviceSettingsService.getDeviceByDeviceIdentification(deviceIdentification); final String deviceUid = oslpDevice.getDeviceUid(); - final Date expireDateTime = - Date.from( - ZonedDateTime.now() - .plusMinutes(this.pendingSetScheduleRequestExpiresInMinutes) - .toInstant()); + final Instant expireDateTime = + ZonedDateTime.now().plusMinutes(this.pendingSetScheduleRequestExpiresInMinutes).toInstant(); final PendingSetScheduleRequest pendingSetScheduleRequest = PendingSetScheduleRequest.builder() @@ -365,7 +362,7 @@ private static DeviceRequest.Builder createDeviceRequestBuilder( .domainVersion(deviceRequest.getDomainVersion()) .messageType(deviceRequest.getMessageType()) .messagePriority(deviceRequest.getMessagePriority()) - .ipAddress(deviceRequest.getIpAddress()) + .ipAddress(deviceRequest.getNetworkAddress()) .retryCount(deviceRequest.getRetryCount()) .isScheduled(deviceRequest.isScheduled()); } diff --git a/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/infra/networking/OslpDeviceService.java b/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/infra/networking/OslpDeviceService.java index b40b4238cb7..4fdfaaacdd1 100644 --- a/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/infra/networking/OslpDeviceService.java +++ b/osgp/protocol-adapter-oslp/osgp-adapter-protocol-oslp-elster/src/main/java/org/opensmartgridplatform/adapter/protocol/oslp/elster/infra/networking/OslpDeviceService.java @@ -11,6 +11,7 @@ import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.UnknownHostException; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -62,6 +63,7 @@ import org.opensmartgridplatform.oslp.OslpEnvelope; import org.opensmartgridplatform.shared.exceptionhandling.ComponentType; import org.opensmartgridplatform.shared.exceptionhandling.ConnectionFailureException; +import org.opensmartgridplatform.shared.utils.JavaTimeHelpers; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -1646,7 +1648,9 @@ private void buildOslpRequestSetTransition(final SetTransitionDeviceRequest devi org.opensmartgridplatform.oslp.Oslp.TransitionType.class)); if (deviceRequest.getTransitionTypeContainer().getDateTime() != null) { setTransitionBuilder.setTime( - deviceRequest.getTransitionTypeContainer().getDateTime().toString(TIME_FORMAT)); + JavaTimeHelpers.formatDate( + deviceRequest.getTransitionTypeContainer().getDateTime(), + DateTimeFormatter.ofPattern(DATE_FORMAT))); } this.buildAndSignEnvelope( @@ -2331,7 +2335,7 @@ private void buildAndSignEnvelope( final String deviceIdentification = deviceRequest.getDeviceIdentification(); final String organisationIdentification = deviceRequest.getOrganisationIdentification(); final String correlationUid = deviceRequest.getCorrelationUid(); - final String ipAddress = deviceRequest.getIpAddress(); + final String networkAddress = deviceRequest.getNetworkAddress(); final String domain = deviceRequest.getDomain(); final String domainVersion = deviceRequest.getDomainVersion(); final String messageType = deviceRequest.getMessageType(); @@ -2357,7 +2361,7 @@ private void buildAndSignEnvelope( correlationUid, deviceId, sequenceNumber, - ipAddress, + networkAddress, domain, domainVersion, messageType, diff --git a/osgp/protocol-adapter-oslp/osgp-core-db-api/pom.xml b/osgp/protocol-adapter-oslp/osgp-core-db-api/pom.xml index 23d0cd028fb..6b3f8b9f563 100644 --- a/osgp/protocol-adapter-oslp/osgp-core-db-api/pom.xml +++ b/osgp/protocol-adapter-oslp/osgp-core-db-api/pom.xml @@ -17,7 +17,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-pa-oslp - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-pa-oslp/pom.xml diff --git a/osgp/protocol-adapter-oslp/oslp/pom.xml b/osgp/protocol-adapter-oslp/oslp/pom.xml index 483ec23f575..af618ff0074 100644 --- a/osgp/protocol-adapter-oslp/oslp/pom.xml +++ b/osgp/protocol-adapter-oslp/oslp/pom.xml @@ -19,7 +19,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-pa-oslp - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-pa-oslp/pom.xml diff --git a/osgp/protocol-adapter-oslp/oslp/src/test/java/org/opensmartgridplatform/oslp/OslpEnvelopeEcDsaTest.java b/osgp/protocol-adapter-oslp/oslp/src/test/java/org/opensmartgridplatform/oslp/OslpEnvelopeEcDsaTest.java index f3d9b30fc51..26dd83cf500 100644 --- a/osgp/protocol-adapter-oslp/oslp/src/test/java/org/opensmartgridplatform/oslp/OslpEnvelopeEcDsaTest.java +++ b/osgp/protocol-adapter-oslp/oslp/src/test/java/org/opensmartgridplatform/oslp/OslpEnvelopeEcDsaTest.java @@ -11,10 +11,10 @@ import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.spec.InvalidKeySpecException; +import java.time.Instant; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; import org.apache.commons.lang3.ArrayUtils; -import org.joda.time.Instant; -import org.joda.time.format.DateTimeFormat; -import org.joda.time.format.DateTimeFormatter; import org.junit.jupiter.api.Test; import org.opensmartgridplatform.oslp.Oslp.Message; import org.opensmartgridplatform.oslp.Oslp.RegisterDeviceResponse; @@ -46,7 +46,8 @@ public class OslpEnvelopeEcDsaTest { private static final String SIGNATURE = "SHA256withECDSA"; private static final String PROVIDER = "SunEC"; - private static final DateTimeFormatter FORMAT = DateTimeFormat.forPattern("yyyyMMddHHmmss"); + private static final DateTimeFormatter FORMAT = + DateTimeFormatter.ofPattern("yyyyMMddHHmmss").withZone(ZoneId.of("UTC")); /** * Valid must pass when decryption succeeds using correct keys @@ -294,7 +295,7 @@ private Message buildRegisterResponse() { .setRegisterDeviceResponse( RegisterDeviceResponse.newBuilder() .setStatus(Oslp.Status.OK) - .setCurrentTime(Instant.now().toString(FORMAT)) + .setCurrentTime(FORMAT.format(Instant.now())) .setRandomDevice(randomDevice) .setRandomPlatform(randomPlatform)) .build(); diff --git a/osgp/protocol-adapter-oslp/parent-pa-oslp/pom.xml b/osgp/protocol-adapter-oslp/parent-pa-oslp/pom.xml index 2de13ad121c..ab0256f8ed6 100644 --- a/osgp/protocol-adapter-oslp/parent-pa-oslp/pom.xml +++ b/osgp/protocol-adapter-oslp/parent-pa-oslp/pom.xml @@ -18,7 +18,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform super-osgp - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../../../super/pom.xml diff --git a/osgp/protocol-adapter-oslp/pom.xml b/osgp/protocol-adapter-oslp/pom.xml index 802323c1c39..9d4179596b4 100644 --- a/osgp/protocol-adapter-oslp/pom.xml +++ b/osgp/protocol-adapter-oslp/pom.xml @@ -12,7 +12,7 @@ SPDX-License-Identifier: Apache-2.0 protocol-adapter-oslp org.opensmartgridplatform - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT pom diff --git a/osgp/protocol-adapter-oslp/signing-server/pom.xml b/osgp/protocol-adapter-oslp/signing-server/pom.xml index 10fbbd497f0..b8a11162da7 100644 --- a/osgp/protocol-adapter-oslp/signing-server/pom.xml +++ b/osgp/protocol-adapter-oslp/signing-server/pom.xml @@ -17,7 +17,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-pa-oslp - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-pa-oslp/pom.xml diff --git a/osgp/protocol-adapter-oslp/web-device-simulator/pom.xml b/osgp/protocol-adapter-oslp/web-device-simulator/pom.xml index 19c0a5c6213..f93f69cad01 100644 --- a/osgp/protocol-adapter-oslp/web-device-simulator/pom.xml +++ b/osgp/protocol-adapter-oslp/web-device-simulator/pom.xml @@ -20,7 +20,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-pa-oslp - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-pa-oslp/pom.xml diff --git a/osgp/protocol-adapter-oslp/web-device-simulator/src/main/java/org/opensmartgridplatform/webdevicesimulator/service/OslpChannelHandler.java b/osgp/protocol-adapter-oslp/web-device-simulator/src/main/java/org/opensmartgridplatform/webdevicesimulator/service/OslpChannelHandler.java index 73e6a41057f..3e943767fd0 100644 --- a/osgp/protocol-adapter-oslp/web-device-simulator/src/main/java/org/opensmartgridplatform/webdevicesimulator/service/OslpChannelHandler.java +++ b/osgp/protocol-adapter-oslp/web-device-simulator/src/main/java/org/opensmartgridplatform/webdevicesimulator/service/OslpChannelHandler.java @@ -14,6 +14,7 @@ import java.net.InetAddress; import java.net.InetSocketAddress; import java.security.PrivateKey; +import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -32,7 +33,6 @@ import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import org.apache.commons.codec.binary.Base64; -import org.joda.time.DateTime; import org.opensmartgridplatform.oslp.Oslp; import org.opensmartgridplatform.oslp.Oslp.ConfirmRegisterDeviceResponse; import org.opensmartgridplatform.oslp.Oslp.DaliConfiguration; @@ -518,7 +518,7 @@ private Oslp.Message handleRequest(final OslpEnvelope message, final int sequenc if (Math.abs(expectedSequenceNumber - sequenceNumber) > this.sequenceNumberWindow) { this.outOfSequenceList.add( new OutOfSequenceEvent( - device.getId(), message.getPayloadMessage().toString(), DateTime.now())); + device.getId(), message.getPayloadMessage().toString(), ZonedDateTime.now())); throw new DeviceSimulatorException( "SequenceNumber incorrect for device: " @@ -1128,9 +1128,10 @@ void handle(final OslpEnvelope response) { public static class OutOfSequenceEvent { private final Long deviceId; private final String request; - private final DateTime timestamp; + private final ZonedDateTime timestamp; - public OutOfSequenceEvent(final Long deviceId, final String request, final DateTime timestamp) { + public OutOfSequenceEvent( + final Long deviceId, final String request, final ZonedDateTime timestamp) { this.deviceId = deviceId; this.request = request; this.timestamp = timestamp; @@ -1144,7 +1145,7 @@ public String getRequest() { return this.request; } - public DateTime getTimestamp() { + public ZonedDateTime getTimestamp() { return this.timestamp; } } diff --git a/osgp/shared/osgp-dto/pom.xml b/osgp/shared/osgp-dto/pom.xml index 98b09f6783d..7c971a43bf8 100644 --- a/osgp/shared/osgp-dto/pom.xml +++ b/osgp/shared/osgp-dto/pom.xml @@ -19,7 +19,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-shared - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-shared/pom.xml diff --git a/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/ConfigurationDto.java b/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/ConfigurationDto.java index d3f9dc8dd98..c800caf068c 100644 --- a/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/ConfigurationDto.java +++ b/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/ConfigurationDto.java @@ -5,8 +5,8 @@ package org.opensmartgridplatform.dto.valueobjects; import java.io.Serializable; +import java.time.ZonedDateTime; import java.util.List; -import org.joda.time.DateTime; public class ConfigurationDto implements Serializable { @@ -63,9 +63,9 @@ public class ConfigurationDto implements Serializable { private Boolean relayRefreshing; - private DateTime summerTimeDetails; + private ZonedDateTime summerTimeDetails; - private DateTime winterTimeDetails; + private ZonedDateTime winterTimeDetails; private ConfigurationDto(final Builder builder) { this.lightType = builder.lightType; @@ -300,19 +300,19 @@ public List getRelayLinking() { return this.relayLinking; } - public DateTime getSummerTimeDetails() { + public ZonedDateTime getSummerTimeDetails() { return this.summerTimeDetails; } - public void setSummerTimeDetails(final DateTime summerTimeDetails) { + public void setSummerTimeDetails(final ZonedDateTime summerTimeDetails) { this.summerTimeDetails = summerTimeDetails; } - public DateTime getWinterTimeDetails() { + public ZonedDateTime getWinterTimeDetails() { return this.winterTimeDetails; } - public void setWinterTimeDetails(final DateTime winterTimeDetails) { + public void setWinterTimeDetails(final ZonedDateTime winterTimeDetails) { this.winterTimeDetails = winterTimeDetails; } } diff --git a/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/EventNotificationDto.java b/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/EventNotificationDto.java index c4fcac1932a..49ebd0ffcac 100644 --- a/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/EventNotificationDto.java +++ b/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/EventNotificationDto.java @@ -5,7 +5,7 @@ package org.opensmartgridplatform.dto.valueobjects; import java.io.Serializable; -import org.joda.time.DateTime; +import java.time.ZonedDateTime; public class EventNotificationDto implements Serializable { @@ -13,14 +13,14 @@ public class EventNotificationDto implements Serializable { private static final long serialVersionUID = 5665838352689024852L; private final String deviceUid; - private final DateTime dateTime; + private final ZonedDateTime dateTime; private final EventTypeDto eventType; private final String description; private final Integer index; public EventNotificationDto( final String deviceUid, - final DateTime dateTime, + final ZonedDateTime dateTime, final EventTypeDto eventType, final String description, final Integer index) { @@ -42,7 +42,7 @@ public String getDeviceUid() { return this.deviceUid; } - public DateTime getDateTime() { + public ZonedDateTime getDateTime() { return this.dateTime; } diff --git a/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/TransitionMessageDataContainerDto.java b/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/TransitionMessageDataContainerDto.java index 9ea9a15b30e..0eef0b7e738 100644 --- a/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/TransitionMessageDataContainerDto.java +++ b/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/TransitionMessageDataContainerDto.java @@ -5,18 +5,18 @@ package org.opensmartgridplatform.dto.valueobjects; import java.io.Serializable; -import org.joda.time.DateTime; +import java.time.ZonedDateTime; public class TransitionMessageDataContainerDto implements Serializable { /** Serial Version UID. */ private static final long serialVersionUID = 5491018613060059335L; - private TransitionTypeDto transitionType; - private DateTime dateTime; + private final TransitionTypeDto transitionType; + private final ZonedDateTime dateTime; public TransitionMessageDataContainerDto( - final TransitionTypeDto transitionType, final DateTime dateTime) { + final TransitionTypeDto transitionType, final ZonedDateTime dateTime) { this.transitionType = transitionType; this.dateTime = dateTime; } @@ -25,7 +25,7 @@ public TransitionTypeDto getTransitionType() { return this.transitionType; } - public DateTime getDateTime() { + public ZonedDateTime getDateTime() { return this.dateTime; } } diff --git a/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/smartmetering/BitErrorRateDto.java b/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/smartmetering/BitErrorRateDto.java deleted file mode 100644 index 80fc57ed95d..00000000000 --- a/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/smartmetering/BitErrorRateDto.java +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-FileCopyrightText: Copyright Contributors to the GXF project -// -// SPDX-License-Identifier: Apache-2.0 - -package org.opensmartgridplatform.dto.valueobjects.smartmetering; - -public enum BitErrorRateDto { - RXQUAL_0(0), - RXQUAL_1(1), - RXQUAL_2(2), - RXQUAL_3(3), - RXQUAL_4(4), - RXQUAL_5(5), - RXQUAL_6(6), - RXQUAL_7(7), - NOT_KNOWN_OR_NOT_DETECTABLE(99); - - private final int index; - - private BitErrorRateDto(final int index) { - this.index = index; - } - - public int getIndex() { - return this.index; - } - - public static BitErrorRateDto fromIndexValue(final int value) { - for (final BitErrorRateDto status : BitErrorRateDto.values()) { - if (status.index == value) { - return status; - } - } - throw new IllegalArgumentException("IndexValue " + value + " not found for BitErrorRateDto"); - } - - public String value() { - return this.name(); - } - - public static BitErrorRateDto fromValue(final String v) { - return valueOf(v); - } -} diff --git a/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/smartmetering/CellInfoDto.java b/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/smartmetering/CellInfoDto.java index 73d9dd8bc4b..3e7a9ec110e 100644 --- a/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/smartmetering/CellInfoDto.java +++ b/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/smartmetering/CellInfoDto.java @@ -13,7 +13,7 @@ public class CellInfoDto implements Serializable { private final long cellId; private final int locationId; private final SignalQualityDto signalQuality; - private final BitErrorRateDto bitErrorRate; + private final int bitErrorRate; private final int mobileCountryCode; private final int mobileNetworkCode; private final long channelNumber; @@ -22,7 +22,7 @@ public CellInfoDto( final long cellId, final int locationId, final SignalQualityDto signalQuality, - final BitErrorRateDto bitErrorRate, + final int bitErrorRate, final int mobileCountryCode, final int mobileNetworkCode, final long channelNumber) { @@ -47,7 +47,7 @@ public SignalQualityDto getSignalQuality() { return this.signalQuality; } - public BitErrorRateDto getBitErrorRate() { + public int getBitErrorRate() { return this.bitErrorRate; } diff --git a/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/smartmetering/ConfigurationFlagTypeDto.java b/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/smartmetering/ConfigurationFlagTypeDto.java index d215b7cd2a7..d5485ebf819 100644 --- a/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/smartmetering/ConfigurationFlagTypeDto.java +++ b/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/smartmetering/ConfigurationFlagTypeDto.java @@ -9,29 +9,34 @@ import java.util.Optional; public enum ConfigurationFlagTypeDto { - DISCOVER_ON_OPEN_COVER(0, null, false), - DISCOVER_ON_POWER_ON(1, null, false), - DYNAMIC_MBUS_ADDRESS(2, null, false), - PO_ENABLE(3, 3, false), - HLS_3_ON_P_3_ENABLE(4, null, false), - HLS_4_ON_P_3_ENABLE(5, null, false), - HLS_5_ON_P_3_ENABLE(6, 6, false), - HLS_3_ON_PO_ENABLE(7, null, false), - HLS_4_ON_PO_ENABLE(8, null, false), - HLS_5_ON_PO_ENABLE(9, 9, false), - DIRECT_ATTACH_AT_POWER_ON(null, 10, false), - HLS_6_ON_P3_ENABLE(null, 11, false), - HLS_7_ON_P3_ENABLE(null, 12, false), - HLS_6_ON_P0_ENABLE(null, 13, false), - HLS_7_ON_P0_ENABLE(null, 14, false); + DISCOVER_ON_OPEN_COVER(0, 0, null, false), + DISCOVER_ON_POWER_ON(1, 1, null, false), + DYNAMIC_MBUS_ADDRESS(2, 2, null, false), + PO_ENABLE(3, 3, 3, false), + HLS_3_ON_P3_ENABLE(4, 4, null, false), + HLS_4_ON_P3_ENABLE(5, 5, null, false), + HLS_5_ON_P3_ENABLE(6, 6, 6, false), + HLS_3_ON_P0_ENABLE(7, 7, null, false), + HLS_4_ON_P0_ENABLE(8, 8, null, false), + HLS_5_ON_P0_ENABLE(9, 9, 9, false), + DIRECT_ATTACH_AT_POWER_ON(null, 10, 10, false), + HLS_6_ON_P3_ENABLE(null, null, 11, false), + HLS_7_ON_P3_ENABLE(null, null, 12, false), + HLS_6_ON_P0_ENABLE(null, null, 13, false), + HLS_7_ON_P0_ENABLE(null, null, 14, false); private final Integer bitPositionDsmr4; + private final Integer bitPositionDsmr43; private final Integer bitPositionSmr5; private final boolean readOnly; ConfigurationFlagTypeDto( - final Integer bitPositionDsmr4, final Integer bitPositionSmr5, final boolean readOnly) { + final Integer bitPositionDsmr4, + final Integer bitPositionDsmr43, + final Integer bitPositionSmr5, + final boolean readOnly) { this.bitPositionDsmr4 = bitPositionDsmr4; + this.bitPositionDsmr43 = bitPositionDsmr43; this.bitPositionSmr5 = bitPositionSmr5; this.readOnly = readOnly; } @@ -44,6 +49,10 @@ public Optional getBitPositionDsmr4() { return Optional.ofNullable(this.bitPositionDsmr4); } + public Optional getBitPositionDsmr43() { + return Optional.ofNullable(this.bitPositionDsmr43); + } + public boolean isReadOnly() { return this.readOnly; } @@ -59,4 +68,10 @@ public static Optional getDsmr4FlagType(final Integer .filter(v -> Objects.equals(bitPosition, v.bitPositionDsmr4)) .findAny(); } + + public static Optional getDsmr43FlagType(final Integer bitPosition) { + return Arrays.stream(values()) + .filter(v -> Objects.equals(bitPosition, v.bitPositionDsmr43)) + .findAny(); + } } diff --git a/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/smartmetering/DlmsUnitTypeDto.java b/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/smartmetering/DlmsUnitTypeDto.java index e977abdbd63..25398b384dc 100644 --- a/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/smartmetering/DlmsUnitTypeDto.java +++ b/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/smartmetering/DlmsUnitTypeDto.java @@ -26,7 +26,7 @@ public enum DlmsUnitTypeDto { CURRENCY(10, "CURRENCY"), METER(11, "M"), METER_PER_SECOND(12, "METER_PER_SECOND"), - M3(13, "M_3"), // this underscore is needed because the xsd generates this! + M3(13, "M_3", "M3"), // this underscore is needed because the xsd generates this! M3_CORR(14, "M_3"), M3_FLUX(15, "M_3_FLUX"), M3_FLUX_CORR(16, "M_3_FLUX_CORR"), diff --git a/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/smartmetering/MeterReadsGasResponseDto.java b/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/smartmetering/MeterReadsGasResponseDto.java index 401c94d3be6..0bb4880903e 100644 --- a/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/smartmetering/MeterReadsGasResponseDto.java +++ b/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/smartmetering/MeterReadsGasResponseDto.java @@ -17,7 +17,11 @@ public class MeterReadsGasResponseDto extends ActionResponseDto { public MeterReadsGasResponseDto( final Date logTime, final DlmsMeterValueDto consumption, final Date captureTime) { this.logTime = new Date(logTime.getTime()); - this.captureTime = new Date(captureTime.getTime()); + if (captureTime != null) { + this.captureTime = new Date(captureTime.getTime()); + } else { + this.captureTime = null; + } this.consumption = consumption; } @@ -26,7 +30,11 @@ public Date getLogTime() { } public Date getCaptureTime() { - return new Date(this.captureTime.getTime()); + if (this.captureTime != null) { + return new Date(this.captureTime.getTime()); + } else { + return null; + } } public DlmsMeterValueDto getConsumption() { diff --git a/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/smartmetering/SmartMeteringDeviceDto.java b/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/smartmetering/SmartMeteringDeviceDto.java index c25411aae81..67d34fde857 100644 --- a/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/smartmetering/SmartMeteringDeviceDto.java +++ b/osgp/shared/osgp-dto/src/main/java/org/opensmartgridplatform/dto/valueobjects/smartmetering/SmartMeteringDeviceDto.java @@ -35,6 +35,8 @@ public class SmartMeteringDeviceDto implements Serializable { private String supplier; + private boolean lls1Active; + private boolean hls3Active; private boolean hls4Active; diff --git a/osgp/shared/osgp-dto/src/test/java/org/opensmartgridplatform/dto/valueobjects/smartmetering/SmartMeteringDeviceDtoBuilder.java b/osgp/shared/osgp-dto/src/test/java/org/opensmartgridplatform/dto/valueobjects/smartmetering/SmartMeteringDeviceDtoBuilder.java index adaf28bcc25..9beb2fcfb07 100644 --- a/osgp/shared/osgp-dto/src/test/java/org/opensmartgridplatform/dto/valueobjects/smartmetering/SmartMeteringDeviceDtoBuilder.java +++ b/osgp/shared/osgp-dto/src/test/java/org/opensmartgridplatform/dto/valueobjects/smartmetering/SmartMeteringDeviceDtoBuilder.java @@ -22,6 +22,7 @@ public SmartMeteringDeviceDto build() { dto.setProtocolName("protocolName" + counter); dto.setProtocolVersion("protocolVersion" + counter); dto.setGlobalEncryptionUnicastKey(("globalEncryptionUnicastKey" + counter).getBytes()); + dto.setLls1Active(true); dto.setHls3Active(true); dto.setHls4Active(true); dto.setHls5Active(true); diff --git a/osgp/shared/osgp-jasper-shared/pom.xml b/osgp/shared/osgp-jasper-shared/pom.xml new file mode 100644 index 00000000000..2a37cf38a72 --- /dev/null +++ b/osgp/shared/osgp-jasper-shared/pom.xml @@ -0,0 +1,69 @@ + + + 4.0.0 + + org.opensmartgridplatform + parent-shared + 5.49.0-SNAPSHOT + ../parent-shared/pom.xml + + + org.opensmartgridplatform + osgp-jasper-shared + jar + + + + + org.springframework + spring-core + + + org.springframework + spring-web + + + + org.projectlombok + lombok + provided + + + + com.fasterxml.jackson.core + jackson-annotations + + + com.fasterxml.jackson.core + jackson-core + + + com.fasterxml.jackson.core + jackson-databind + + + + + + + org.apache.maven.plugins + maven-jar-plugin + ${maven.jar.plugin.version} + + + maven-surefire-plugin + ${maven.surefire.plugin.version} + + + org.junit.jupiter + junit-jupiter-engine + ${junit.version} + + + + + + + \ No newline at end of file diff --git a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/rest/client/JasperWirelessRestClient.java b/osgp/shared/osgp-jasper-shared/src/main/java/org/opensmartgridplatform/jasper/client/JasperWirelessRestClient.java similarity index 78% rename from osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/rest/client/JasperWirelessRestClient.java rename to osgp/shared/osgp-jasper-shared/src/main/java/org/opensmartgridplatform/jasper/client/JasperWirelessRestClient.java index d61b7015404..3b7344b44a4 100644 --- a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/rest/client/JasperWirelessRestClient.java +++ b/osgp/shared/osgp-jasper-shared/src/main/java/org/opensmartgridplatform/jasper/client/JasperWirelessRestClient.java @@ -2,15 +2,15 @@ // // SPDX-License-Identifier: Apache-2.0 -package org.opensmartgridplatform.adapter.protocol.jasper.rest.client; +package org.opensmartgridplatform.jasper.client; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.Base64; -import org.opensmartgridplatform.adapter.protocol.jasper.config.JasperWirelessAccess; -import org.opensmartgridplatform.adapter.protocol.jasper.exceptions.OsgpJasperException; -import org.opensmartgridplatform.adapter.protocol.jasper.response.JasperErrorResponse; -import org.opensmartgridplatform.adapter.protocol.jasper.rest.JasperError; +import org.opensmartgridplatform.jasper.config.JasperWirelessAccess; +import org.opensmartgridplatform.jasper.exceptions.OsgpJasperException; +import org.opensmartgridplatform.jasper.response.JasperErrorResponse; +import org.opensmartgridplatform.jasper.rest.JasperError; import org.springframework.web.client.HttpStatusCodeException; public class JasperWirelessRestClient { diff --git a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/config/JasperWirelessAccess.java b/osgp/shared/osgp-jasper-shared/src/main/java/org/opensmartgridplatform/jasper/config/JasperWirelessAccess.java similarity index 69% rename from osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/config/JasperWirelessAccess.java rename to osgp/shared/osgp-jasper-shared/src/main/java/org/opensmartgridplatform/jasper/config/JasperWirelessAccess.java index 991e3a29f62..764665f2f5d 100644 --- a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/config/JasperWirelessAccess.java +++ b/osgp/shared/osgp-jasper-shared/src/main/java/org/opensmartgridplatform/jasper/config/JasperWirelessAccess.java @@ -2,20 +2,20 @@ // // SPDX-License-Identifier: Apache-2.0 -package org.opensmartgridplatform.adapter.protocol.jasper.config; +package org.opensmartgridplatform.jasper.config; import lombok.Getter; @Getter public class JasperWirelessAccess { - private String uri; - private String licenseKey; - private String apiKey; - private String username; - private String password; - private String apiVersion; - private String apiType; + private final String uri; + private final String licenseKey; + private final String apiKey; + private final String username; + private final String password; + private final String apiVersion; + private final String apiType; public JasperWirelessAccess( final String uri, diff --git a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/exceptions/OsgpJasperException.java b/osgp/shared/osgp-jasper-shared/src/main/java/org/opensmartgridplatform/jasper/exceptions/OsgpJasperException.java similarity index 84% rename from osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/exceptions/OsgpJasperException.java rename to osgp/shared/osgp-jasper-shared/src/main/java/org/opensmartgridplatform/jasper/exceptions/OsgpJasperException.java index 494c41590c1..421aaa78448 100644 --- a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/exceptions/OsgpJasperException.java +++ b/osgp/shared/osgp-jasper-shared/src/main/java/org/opensmartgridplatform/jasper/exceptions/OsgpJasperException.java @@ -2,9 +2,9 @@ // // SPDX-License-Identifier: Apache-2.0 -package org.opensmartgridplatform.adapter.protocol.jasper.exceptions; +package org.opensmartgridplatform.jasper.exceptions; -import org.opensmartgridplatform.adapter.protocol.jasper.rest.JasperError; +import org.opensmartgridplatform.jasper.rest.JasperError; public class OsgpJasperException extends Exception { diff --git a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/response/JasperErrorResponse.java b/osgp/shared/osgp-jasper-shared/src/main/java/org/opensmartgridplatform/jasper/response/JasperErrorResponse.java similarity index 86% rename from osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/response/JasperErrorResponse.java rename to osgp/shared/osgp-jasper-shared/src/main/java/org/opensmartgridplatform/jasper/response/JasperErrorResponse.java index 91882fec791..159f115dd3c 100644 --- a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/response/JasperErrorResponse.java +++ b/osgp/shared/osgp-jasper-shared/src/main/java/org/opensmartgridplatform/jasper/response/JasperErrorResponse.java @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: Apache-2.0 -package org.opensmartgridplatform.adapter.protocol.jasper.response; +package org.opensmartgridplatform.jasper.response; import lombok.Getter; diff --git a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/rest/JasperError.java b/osgp/shared/osgp-jasper-shared/src/main/java/org/opensmartgridplatform/jasper/rest/JasperError.java similarity index 97% rename from osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/rest/JasperError.java rename to osgp/shared/osgp-jasper-shared/src/main/java/org/opensmartgridplatform/jasper/rest/JasperError.java index e8591f9bb5a..4a6f92950d0 100644 --- a/osgp/protocol-adapter-dlms/osgp-jasper-interface/src/main/java/org/opensmartgridplatform/adapter/protocol/jasper/rest/JasperError.java +++ b/osgp/shared/osgp-jasper-shared/src/main/java/org/opensmartgridplatform/jasper/rest/JasperError.java @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: Apache-2.0 -package org.opensmartgridplatform.adapter.protocol.jasper.rest; +package org.opensmartgridplatform.jasper.rest; import java.util.Arrays; import lombok.Getter; diff --git a/osgp/shared/osgp-kafka-config/pom.xml b/osgp/shared/osgp-kafka-config/pom.xml index 4d5443140a3..810f970875d 100644 --- a/osgp/shared/osgp-kafka-config/pom.xml +++ b/osgp/shared/osgp-kafka-config/pom.xml @@ -11,7 +11,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-shared - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-shared/pom.xml diff --git a/osgp/shared/osgp-kafka-logger/pom.xml b/osgp/shared/osgp-kafka-logger/pom.xml index d7be4f51985..44d13e679e4 100644 --- a/osgp/shared/osgp-kafka-logger/pom.xml +++ b/osgp/shared/osgp-kafka-logger/pom.xml @@ -11,7 +11,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-shared - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-shared/pom.xml diff --git a/osgp/shared/osgp-throttling-api/pom.xml b/osgp/shared/osgp-throttling-api/pom.xml index b642a9c9985..a60bb849a6f 100644 --- a/osgp/shared/osgp-throttling-api/pom.xml +++ b/osgp/shared/osgp-throttling-api/pom.xml @@ -11,7 +11,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-shared - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-shared/pom.xml diff --git a/osgp/shared/osgp-throttling-api/src/main/java/org/opensmartgridplatform/throttling/api/Permit.java b/osgp/shared/osgp-throttling-api/src/main/java/org/opensmartgridplatform/throttling/api/Permit.java index 5dd84984473..61f3178cad3 100644 --- a/osgp/shared/osgp-throttling-api/src/main/java/org/opensmartgridplatform/throttling/api/Permit.java +++ b/osgp/shared/osgp-throttling-api/src/main/java/org/opensmartgridplatform/throttling/api/Permit.java @@ -28,8 +28,8 @@ public class Permit { public Permit() {} - public Permit(final short throttlingConfigId, final int clientId, final Integer requestId) { - this(throttlingConfigId, clientId, requestId, null, null, null); + public Permit(final Integer requestId) { + this((short) 0, 0, requestId, null, null, Instant.now()); } public Permit( diff --git a/osgp/shared/osgp-throttling-client/pom.xml b/osgp/shared/osgp-throttling-client/pom.xml index f0835cd0f74..42539841caa 100644 --- a/osgp/shared/osgp-throttling-client/pom.xml +++ b/osgp/shared/osgp-throttling-client/pom.xml @@ -11,7 +11,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-shared - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-shared/pom.xml diff --git a/osgp/shared/osgp-throttling-client/src/main/java/org/opensmartgridplatform/throttling/ThrottlingClient.java b/osgp/shared/osgp-throttling-client/src/main/java/org/opensmartgridplatform/throttling/ThrottlingClient.java index af00428e775..5230df7f581 100644 --- a/osgp/shared/osgp-throttling-client/src/main/java/org/opensmartgridplatform/throttling/ThrottlingClient.java +++ b/osgp/shared/osgp-throttling-client/src/main/java/org/opensmartgridplatform/throttling/ThrottlingClient.java @@ -186,22 +186,24 @@ public void unregister() { * * @param baseTransceiverStationId ID of the BTS * @param cellId Cell ID within the BTS + * @param priority Priority of the request * @return a permit granting access to a network or network segment * @throws ThrottlingPermitDeniedException if a permit is not granted */ public Permit requestPermitUsingNetworkSegmentIfIdsAreAvailable( - final Integer baseTransceiverStationId, final Integer cellId) { + final Integer baseTransceiverStationId, final Integer cellId, final Integer priority) { if (baseTransceiverStationId != null && cellId != null) { - return this.requestPermit(baseTransceiverStationId, cellId) + return this.requestPermit(baseTransceiverStationId, cellId, priority) .orElseThrow( () -> new ThrottlingPermitDeniedException( - this.throttlingConfig.getName(), baseTransceiverStationId, cellId)); + this.throttlingConfig.getName(), baseTransceiverStationId, cellId, priority)); } - return this.requestPermit() - .orElseThrow(() -> new ThrottlingPermitDeniedException(this.throttlingConfig.getName())); + return this.requestPermit(priority) + .orElseThrow( + () -> new ThrottlingPermitDeniedException(this.throttlingConfig.getName(), priority)); } /** @@ -214,16 +216,17 @@ public Permit requestPermitUsingNetworkSegmentIfIdsAreAvailable( * @return a permit granting access to the network, containing a locally (this client) unique * request ID, or an empty response if no permit was available. */ - public Optional requestPermit() { + public Optional requestPermit(final int priority) { final int requestId = this.requestIdCounter.incrementAndGet(); LOGGER.debug( - "Requesting permit using requestId {} for clientId {} on {}", + "Requesting permit using requestId {} with priority {} for clientId {} on {}", requestId, + priority, this.clientId, this.throttlingConfig); - final Integer numberOfGrantedPermits = this.numberOfGrantedPermits(requestId); + final Integer numberOfGrantedPermits = this.numberOfGrantedPermits(requestId, priority); if (numberOfGrantedPermits == null) { this.discardPermitLogExceptionOnFailure(requestId); @@ -251,22 +254,25 @@ public Optional requestPermit() { * * @param baseTransceiverStationId BTS for which a permit is requested * @param cellId Cell of the BTS for which a permit is requested + * @param priority Priority of request * @return a permit granting access to the given network and network segment, containing a locally * (this client) unique request ID, or an empty response if no permit was available. */ - public Optional requestPermit(final int baseTransceiverStationId, final int cellId) { + public Optional requestPermit( + final int baseTransceiverStationId, final int cellId, final int priority) { final int requestId = this.requestIdCounter.incrementAndGet(); LOGGER.debug( - "Requesting permit for network segment ({}, {}) using requestId {} for clientId {} on {}", + "Requesting permit for network segment ({}, {}) using requestId {} with priority {} for clientId {} on {}", baseTransceiverStationId, cellId, requestId, + priority, this.clientId, this.throttlingConfig); final Integer numberOfGrantedPermits = - this.numberOfGrantedPermits(requestId, baseTransceiverStationId, cellId); + this.numberOfGrantedPermits(requestId, baseTransceiverStationId, cellId, priority); if (numberOfGrantedPermits == null) { this.discardPermitLogExceptionOnFailure(requestId); @@ -290,7 +296,7 @@ public Optional requestPermit(final int baseTransceiverStationId, final : Optional.empty(); } - private Integer numberOfGrantedPermits(final int requestId) { + private Integer numberOfGrantedPermits(final int requestId, final int priority) { if (!this.register()) { LOGGER.error("Client is not registered when requesting permit using requestId {}", requestId); return null; @@ -298,11 +304,12 @@ private Integer numberOfGrantedPermits(final int requestId) { try { return this.restTemplate.postForObject( - "/permits/{throttlingConfigId}/{clientId}", + "/permits/{throttlingConfigId}/{clientId}?priority={priority}", requestId, Integer.class, this.throttlingConfig.getId(), - this.clientId); + this.clientId, + priority); } catch (final Exception e) { LOGGER.error( "Unexpected exception requesting permit using requestId {} for {} on {}", @@ -314,31 +321,37 @@ private Integer numberOfGrantedPermits(final int requestId) { } private Integer numberOfGrantedPermits( - final int requestId, final int baseTransceiverStationId, final int cellId) { + final int requestId, + final int baseTransceiverStationId, + final int cellId, + final int priority) { if (!this.register()) { LOGGER.error( - "Client is not registered when requesting permit for network segment ({}, {}) using requestId {}", + "Client is not registered when requesting permit for network segment ({}, {}) using requestId {} with priority {}", baseTransceiverStationId, cellId, - requestId); + requestId, + priority); return null; } try { return this.restTemplate.postForObject( - "/permits/{throttlingConfigId}/{clientId}/{baseTransceiverStationId}/{cellId}", + "/permits/{throttlingConfigId}/{clientId}/{baseTransceiverStationId}/{cellId}?priority={priority}", requestId, Integer.class, this.throttlingConfig.getId(), this.clientId, baseTransceiverStationId, - cellId); + cellId, + priority); } catch (final Exception e) { LOGGER.error( - "Unexpected exception requesting permit for network segment ({}, {}) using requestId {} for {} on {}", + "Unexpected exception requesting permit for network segment ({}, {}) using requestId {} with priority {} for {} on {}", baseTransceiverStationId, cellId, requestId, + priority, this.clientId, this.throttlingConfig, e); diff --git a/osgp/shared/osgp-throttling-client/src/main/java/org/opensmartgridplatform/throttling/ThrottlingPermitDeniedException.java b/osgp/shared/osgp-throttling-client/src/main/java/org/opensmartgridplatform/throttling/ThrottlingPermitDeniedException.java index d0e7e1604a8..a9760aa4325 100644 --- a/osgp/shared/osgp-throttling-client/src/main/java/org/opensmartgridplatform/throttling/ThrottlingPermitDeniedException.java +++ b/osgp/shared/osgp-throttling-client/src/main/java/org/opensmartgridplatform/throttling/ThrottlingPermitDeniedException.java @@ -12,23 +12,29 @@ public class ThrottlingPermitDeniedException extends RuntimeException { private final String configurationName; private final Integer baseTransceiverStationId; private final Integer cellId; + private final Integer priority; public ThrottlingPermitDeniedException( - final String configurationName, final int baseTransceiverStationId, final int cellId) { + final String configurationName, + final int baseTransceiverStationId, + final int cellId, + final int priority) { super( String.format( - "Permit denied for network segment (bts_id=%d, cell_id=%d) and configuration \"%s\"", - baseTransceiverStationId, cellId, configurationName)); + "Permit denied for network segment (bts_id=%d, cell_id=%d) with priority %d and configuration \"%s\"", + baseTransceiverStationId, cellId, priority, configurationName)); this.configurationName = configurationName; this.baseTransceiverStationId = baseTransceiverStationId; this.cellId = cellId; + this.priority = priority; } - public ThrottlingPermitDeniedException(final String configurationName) { + public ThrottlingPermitDeniedException(final String configurationName, final int priority) { super(String.format("Permit denied for network with configuration \"%s\"", configurationName)); this.configurationName = configurationName; + this.priority = priority; this.baseTransceiverStationId = null; this.cellId = null; } @@ -44,4 +50,8 @@ public Optional getBaseTransceiverStationId() { public Optional getCellId() { return Optional.ofNullable(this.cellId); } + + public Integer getPriority() { + return this.priority; + } } diff --git a/osgp/shared/osgp-throttling-client/src/test/java/org/opensmartgridplatform/throttling/ThrottlingClientTest.java b/osgp/shared/osgp-throttling-client/src/test/java/org/opensmartgridplatform/throttling/ThrottlingClientTest.java index dce115e2688..505eb1d1aee 100644 --- a/osgp/shared/osgp-throttling-client/src/test/java/org/opensmartgridplatform/throttling/ThrottlingClientTest.java +++ b/osgp/shared/osgp-throttling-client/src/test/java/org/opensmartgridplatform/throttling/ThrottlingClientTest.java @@ -145,17 +145,18 @@ void clientRequestsPermitByNetworkSegment() { final int baseTransceiverStationId = 983745; final int cellId = 2; final int requestId = 894; + final int priority = 8; this.whenTheThrottlingConfigIsIdentifiedById(throttlingConfigId); this.whenTheThrottlingClientHasRegisteredWithId(clientId); this.whenTheThrottlingClientUsesNextRequestId(requestId); this.whenTheThrottlingServiceGrantsTheRequestedPermit( - throttlingConfigId, clientId, baseTransceiverStationId, cellId, requestId); + throttlingConfigId, clientId, baseTransceiverStationId, cellId, requestId, priority); final Permit expectedPermit = new Permit(throttlingConfigId, clientId, requestId, baseTransceiverStationId, cellId, null); final Optional requestedPermit = - this.throttlingClient.requestPermit(baseTransceiverStationId, cellId); + this.throttlingClient.requestPermit(baseTransceiverStationId, cellId, priority); assertThat(requestedPermit) .usingRecursiveComparison() @@ -170,15 +171,16 @@ void unregisteredClientRequestsPermitByNetworkSegment() { final int baseTransceiverStationId = 983745; final int cellId = 2; final int requestId = 894; + final int priority = 7; this.whenTheThrottlingClientUsesNextRequestId(requestId); this.whenTheThrottlingServiceGrantsTheRequestedPermit( - throttlingConfigId, clientId, baseTransceiverStationId, cellId, requestId); + throttlingConfigId, clientId, baseTransceiverStationId, cellId, requestId, priority); final Permit expectedPermit = new Permit(throttlingConfigId, clientId, requestId, baseTransceiverStationId, cellId, null); final Optional requestedPermit = - this.throttlingClient.requestPermit(baseTransceiverStationId, cellId); + this.throttlingClient.requestPermit(baseTransceiverStationId, cellId, priority); assertThat(requestedPermit) .usingRecursiveComparison() @@ -190,10 +192,11 @@ void unregisteredClientRequestsPermitByNetworkSegment() { void registerFailureClientRequestsPermitByNetworkSegment() { final int baseTransceiverStationId = 983745; final int cellId = 2; + final int priority = 7; this.whenTheThrottlingServiceReturnsFailureOnRegistration(); final Optional requestedPermit = - this.throttlingClient.requestPermit(baseTransceiverStationId, cellId); + this.throttlingClient.requestPermit(baseTransceiverStationId, cellId, priority); assertThat(requestedPermit).isNotPresent(); } @@ -215,6 +218,24 @@ private boolean isPermitRequestForNetworkSegment( && method.equals(request.getMethod()); } + private boolean isPermitRequestForNetworkSegment( + final RecordedRequest request, + final String method, + final short throttlingConfigId, + final int clientId, + final int baseTransceiverStationId, + final int cellId, + final int requestId, + final int priority) { + + return String.format( + "/permits/%d/%d/%d/%d?priority=%d", + throttlingConfigId, clientId, baseTransceiverStationId, cellId, priority) + .equals(request.getPath()) + && requestId == Integer.parseInt(request.getBody().readUtf8()) + && method.equals(request.getMethod()); + } + private boolean isPermitRequestForUnknownNetworkSegment( final RecordedRequest request, final String method, @@ -227,12 +248,27 @@ private boolean isPermitRequestForUnknownNetworkSegment( && method.equals(request.getMethod()); } + private boolean isPermitRequestForUnknownNetworkSegment( + final RecordedRequest request, + final String method, + final short throttlingConfigId, + final int clientId, + final int requestId, + final int priority) { + + return String.format("/permits/%d/%d?priority=%d", throttlingConfigId, clientId, priority) + .equals(request.getPath()) + && requestId == Integer.parseInt(request.getBody().readUtf8()) + && method.equals(request.getMethod()); + } + private void whenTheThrottlingServiceGrantsTheRequestedPermit( final short throttlingConfigId, final int clientId, final int baseTransceiverStationId, final int cellId, - final int requestId) { + final int requestId, + final int priority) { this.mockWebServer.setDispatcher( new Dispatcher() { @@ -252,7 +288,8 @@ public MockResponse dispatch(final RecordedRequest request) { clientId, baseTransceiverStationId, cellId, - requestId)) { + requestId, + priority)) { return ThrottlingClientTest.this.permitRequestGrantedResponse(); } @@ -263,7 +300,7 @@ public MockResponse dispatch(final RecordedRequest request) { } private void whenTheThrottlingServiceGrantsTheRequestedPermit( - final short throttlingConfigId, final int clientId, final int requestId) { + final short throttlingConfigId, final int clientId, final int requestId, final int priority) { this.mockWebServer.setDispatcher( new Dispatcher() { @@ -277,7 +314,7 @@ public MockResponse dispatch(final RecordedRequest request) { } if (ThrottlingClientTest.this.isPermitRequestForUnknownNetworkSegment( - request, "POST", throttlingConfigId, clientId, requestId)) { + request, "POST", throttlingConfigId, clientId, requestId, priority)) { return ThrottlingClientTest.this.permitRequestGrantedResponse(); } @@ -299,15 +336,17 @@ void clientRequestsPermitForUnknownNetworkSegment() { final short throttlingConfigId = 5456; final int clientId = 573467; final int requestId = 946585809; + final int priority = 8; this.whenTheThrottlingConfigIsIdentifiedById(throttlingConfigId); this.whenTheThrottlingClientHasRegisteredWithId(clientId); this.whenTheThrottlingClientUsesNextRequestId(requestId); - this.whenTheThrottlingServiceGrantsTheRequestedPermit(throttlingConfigId, clientId, requestId); + this.whenTheThrottlingServiceGrantsTheRequestedPermit( + throttlingConfigId, clientId, requestId, priority); final Permit expectedPermit = new Permit(throttlingConfigId, clientId, requestId, null, null, null); - final Optional requestedPermit = this.throttlingClient.requestPermit(); + final Optional requestedPermit = this.throttlingClient.requestPermit(priority); assertThat(requestedPermit) .usingRecursiveComparison() @@ -320,13 +359,15 @@ void unregisteredClientRequestsPermitForUnknownNetworkSegment() { final short throttlingConfigId = 5456; final int clientId = 573467; final int requestId = 946585809; + final int priority = 4; this.whenTheThrottlingClientUsesNextRequestId(requestId); - this.whenTheThrottlingServiceGrantsTheRequestedPermit(throttlingConfigId, clientId, requestId); + this.whenTheThrottlingServiceGrantsTheRequestedPermit( + throttlingConfigId, clientId, requestId, priority); final Permit expectedPermit = new Permit(throttlingConfigId, clientId, requestId, null, null, null); - final Optional requestedPermit = this.throttlingClient.requestPermit(); + final Optional requestedPermit = this.throttlingClient.requestPermit(priority); assertThat(requestedPermit) .usingRecursiveComparison() @@ -336,9 +377,10 @@ void unregisteredClientRequestsPermitForUnknownNetworkSegment() { @Test void registerFailureClientRequestsPermitForUnknownNetworkSegment() { + final int priority = 8; this.whenTheThrottlingServiceReturnsFailureOnRegistration(); - final Optional requestedPermit = this.throttlingClient.requestPermit(); + final Optional requestedPermit = this.throttlingClient.requestPermit(priority); assertThat(requestedPermit).isNotPresent(); } @@ -350,14 +392,15 @@ void clientRequestsPermitWhichIsNotGranted() { final int baseTransceiverStationId = 3498; final int cellId = 3; final int requestId = 311; + final int priority = 8; this.whenTheThrottlingConfigIsIdentifiedById(throttlingConfigId); this.whenTheThrottlingClientHasRegisteredWithId(clientId); this.whenTheThrottlingClientUsesNextRequestId(requestId); this.whenTheThrottlingServiceRejectsTheRequestedPermit( - throttlingConfigId, clientId, baseTransceiverStationId, cellId, requestId); + throttlingConfigId, clientId, baseTransceiverStationId, cellId, requestId, priority); final Optional requestedPermit = - this.throttlingClient.requestPermit(baseTransceiverStationId, cellId); + this.throttlingClient.requestPermit(baseTransceiverStationId, cellId, priority); assertThat(requestedPermit).isEmpty(); } @@ -367,14 +410,18 @@ void anExceptionIsThrownWhenThePermitIsNotGrantedCallingTheMethodWithNullableIds final short throttlingConfigId = 32; final int clientId = 43; final int requestId = 54; + final int priority = 8; this.whenTheThrottlingConfigIsIdentifiedById(throttlingConfigId); this.whenTheThrottlingClientHasRegisteredWithId(clientId); this.whenTheThrottlingClientUsesNextRequestId(requestId); - this.whenTheThrottlingServiceRejectsTheRequestedPermit(throttlingConfigId, clientId, requestId); + this.whenTheThrottlingServiceRejectsTheRequestedPermit( + throttlingConfigId, clientId, requestId, priority); assertThrows( ThrottlingPermitDeniedException.class, - () -> this.throttlingClient.requestPermitUsingNetworkSegmentIfIdsAreAvailable(null, null)); + () -> + this.throttlingClient.requestPermitUsingNetworkSegmentIfIdsAreAvailable( + null, null, priority)); } private void whenTheThrottlingServiceRejectsTheRequestedPermit( @@ -382,7 +429,8 @@ private void whenTheThrottlingServiceRejectsTheRequestedPermit( final int clientId, final int baseTransceiverStationId, final int cellId, - final int requestId) { + final int requestId, + final int priority) { this.mockWebServer.setDispatcher( new Dispatcher() { @@ -396,7 +444,8 @@ public MockResponse dispatch(final RecordedRequest request) { clientId, baseTransceiverStationId, cellId, - requestId)) { + requestId, + priority)) { return ThrottlingClientTest.this.permitRequestRejectedResponse(); } @@ -407,7 +456,7 @@ public MockResponse dispatch(final RecordedRequest request) { } private void whenTheThrottlingServiceRejectsTheRequestedPermit( - final short throttlingConfigId, final int clientId, final int requestId) { + final short throttlingConfigId, final int clientId, final int requestId, final int priority) { this.mockWebServer.setDispatcher( new Dispatcher() { @@ -415,7 +464,7 @@ private void whenTheThrottlingServiceRejectsTheRequestedPermit( public MockResponse dispatch(final RecordedRequest request) { if (ThrottlingClientTest.this.isPermitRequestForUnknownNetworkSegment( - request, "POST", throttlingConfigId, clientId, requestId)) { + request, "POST", throttlingConfigId, clientId, requestId, priority)) { return ThrottlingClientTest.this.permitRequestRejectedResponse(); } @@ -439,6 +488,7 @@ void clientReleasesPermitForNetworkSegment() { final int baseTransceiverStationId = 10029; final int cellId = 1; final int requestId = 23938477; + final int priority = 4; this.whenTheThrottlingConfigIsIdentifiedById(throttlingConfigId); this.whenTheThrottlingClientHasRegisteredWithId(clientId); this.whenTheThrottlingServiceReleasesThePermit( @@ -465,6 +515,7 @@ void unregisteredClientReleasesPermitForNetworkSegment() { final int baseTransceiverStationId = 10029; final int cellId = 1; final int requestId = 23938477; + final int priority = 7; this.whenTheThrottlingServiceReleasesThePermit( throttlingConfigId, clientId, baseTransceiverStationId, cellId, requestId, true); @@ -509,9 +560,11 @@ void clientReleasesPermitThatIsNotHeldForUnknownNetworkSegment() { final short throttlingConfigId = 11; final int clientId = 18; final int requestId = 21; + final int priority = 4; this.whenTheThrottlingConfigIsIdentifiedById(throttlingConfigId); this.whenTheThrottlingClientHasRegisteredWithId(clientId); - this.whenTheThrottlingServiceReleasesThePermit(throttlingConfigId, clientId, requestId, false); + this.whenTheThrottlingServiceReleasesThePermit( + throttlingConfigId, clientId, requestId, priority, false); final Permit permitToBeReleased = new Permit( @@ -564,6 +617,7 @@ private void whenTheThrottlingServiceReleasesThePermit( final short throttlingConfigId, final int clientId, final int requestId, + final int priority, final boolean permitIsHeld) { this.mockWebServer.setDispatcher( diff --git a/osgp/shared/osgp-ws-admin/pom.xml b/osgp/shared/osgp-ws-admin/pom.xml index a79b6dcf9d2..0bd63e69679 100644 --- a/osgp/shared/osgp-ws-admin/pom.xml +++ b/osgp/shared/osgp-ws-admin/pom.xml @@ -12,7 +12,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-shared - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-shared/pom.xml diff --git a/osgp/shared/osgp-ws-core/pom.xml b/osgp/shared/osgp-ws-core/pom.xml index 99ff3a62704..b46d874e1de 100644 --- a/osgp/shared/osgp-ws-core/pom.xml +++ b/osgp/shared/osgp-ws-core/pom.xml @@ -12,7 +12,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-shared - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-shared/pom.xml diff --git a/osgp/shared/osgp-ws-distributionautomation/pom.xml b/osgp/shared/osgp-ws-distributionautomation/pom.xml index ddeae6cfa64..0fe4fb3a628 100644 --- a/osgp/shared/osgp-ws-distributionautomation/pom.xml +++ b/osgp/shared/osgp-ws-distributionautomation/pom.xml @@ -12,7 +12,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-shared - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-shared/pom.xml diff --git a/osgp/shared/osgp-ws-microgrids/pom.xml b/osgp/shared/osgp-ws-microgrids/pom.xml index f29b8524925..6c91da2fd34 100644 --- a/osgp/shared/osgp-ws-microgrids/pom.xml +++ b/osgp/shared/osgp-ws-microgrids/pom.xml @@ -12,7 +12,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-shared - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-shared/pom.xml diff --git a/osgp/shared/osgp-ws-publiclighting/pom.xml b/osgp/shared/osgp-ws-publiclighting/pom.xml index dd22083fb98..d3ae0f1c14d 100644 --- a/osgp/shared/osgp-ws-publiclighting/pom.xml +++ b/osgp/shared/osgp-ws-publiclighting/pom.xml @@ -12,7 +12,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-shared - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-shared/pom.xml diff --git a/osgp/shared/osgp-ws-secret-management/pom.xml b/osgp/shared/osgp-ws-secret-management/pom.xml index b1069a3fda0..b3b6178401d 100644 --- a/osgp/shared/osgp-ws-secret-management/pom.xml +++ b/osgp/shared/osgp-ws-secret-management/pom.xml @@ -12,7 +12,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-shared - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-shared/pom.xml diff --git a/osgp/shared/osgp-ws-smartmetering/pom.xml b/osgp/shared/osgp-ws-smartmetering/pom.xml index 48dac4bdae7..2c4faae8f09 100644 --- a/osgp/shared/osgp-ws-smartmetering/pom.xml +++ b/osgp/shared/osgp-ws-smartmetering/pom.xml @@ -12,7 +12,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-shared - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-shared/pom.xml diff --git a/osgp/shared/osgp-ws-smartmetering/src/main/resources/bindings/sm-configuration.xjb b/osgp/shared/osgp-ws-smartmetering/src/main/resources/bindings/sm-configuration.xjb index cf1904c9211..6ee7614a344 100644 --- a/osgp/shared/osgp-ws-smartmetering/src/main/resources/bindings/sm-configuration.xjb +++ b/osgp/shared/osgp-ws-smartmetering/src/main/resources/bindings/sm-configuration.xjb @@ -11,7 +11,36 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/osgp/shared/osgp-ws-smartmetering/src/main/resources/schemas/configuration-ws-smartmetering.xsd b/osgp/shared/osgp-ws-smartmetering/src/main/resources/schemas/configuration-ws-smartmetering.xsd index 571f022e1ab..69c657e5e52 100644 --- a/osgp/shared/osgp-ws-smartmetering/src/main/resources/schemas/configuration-ws-smartmetering.xsd +++ b/osgp/shared/osgp-ws-smartmetering/src/main/resources/schemas/configuration-ws-smartmetering.xsd @@ -1079,9 +1079,9 @@ - - - + + + diff --git a/osgp/shared/osgp-ws-smartmetering/src/main/resources/schemas/installation-ws-smartmetering.xsd b/osgp/shared/osgp-ws-smartmetering/src/main/resources/schemas/installation-ws-smartmetering.xsd index 36258904426..9f769a928d5 100644 --- a/osgp/shared/osgp-ws-smartmetering/src/main/resources/schemas/installation-ws-smartmetering.xsd +++ b/osgp/shared/osgp-ws-smartmetering/src/main/resources/schemas/installation-ws-smartmetering.xsd @@ -326,6 +326,8 @@ + - + @@ -1248,21 +1248,6 @@ - - - - - - - - - - - - - - - diff --git a/osgp/shared/osgp-ws-tariffswitching/pom.xml b/osgp/shared/osgp-ws-tariffswitching/pom.xml index 506af14ac5e..94c39e7342b 100644 --- a/osgp/shared/osgp-ws-tariffswitching/pom.xml +++ b/osgp/shared/osgp-ws-tariffswitching/pom.xml @@ -12,7 +12,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-shared - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-shared/pom.xml diff --git a/osgp/shared/parent-shared/pom.xml b/osgp/shared/parent-shared/pom.xml index dd658c8aedc..a924a93b4f0 100644 --- a/osgp/shared/parent-shared/pom.xml +++ b/osgp/shared/parent-shared/pom.xml @@ -21,7 +21,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform super-osgp - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../../../super/pom.xml diff --git a/osgp/shared/pom.xml b/osgp/shared/pom.xml index f9e4ec69f7f..2360a58eceb 100644 --- a/osgp/shared/pom.xml +++ b/osgp/shared/pom.xml @@ -11,7 +11,8 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform shared-components - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT + pom shared @@ -95,6 +96,7 @@ SPDX-License-Identifier: Apache-2.0 osgp-ws-admin osgp-throttling-api osgp-throttling-client + osgp-jasper-shared diff --git a/osgp/shared/shared/pom.xml b/osgp/shared/shared/pom.xml index b2c8efeded4..40e983cb2e4 100644 --- a/osgp/shared/shared/pom.xml +++ b/osgp/shared/shared/pom.xml @@ -15,7 +15,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform parent-shared - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT ../parent-shared/pom.xml diff --git a/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/domain/entities/AbstractEntity.java b/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/domain/entities/AbstractEntity.java index 3b51181f900..0cf44e91449 100644 --- a/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/domain/entities/AbstractEntity.java +++ b/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/domain/entities/AbstractEntity.java @@ -6,7 +6,6 @@ import java.io.Serializable; import java.time.Instant; -import java.util.Date; import javax.persistence.Column; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; @@ -31,10 +30,10 @@ public abstract class AbstractEntity implements Serializable { protected Long id; @Column(nullable = false) - private Date creationTime = new Date(); + protected Instant creationTime = Instant.now(); @Column(nullable = false) - private Date modificationTime = new Date(); + protected Instant modificationTime = Instant.now(); @Version private Long version = -1L; @@ -56,29 +55,29 @@ public Long getId() { /** * @return the creation time */ - public Date getCreationTime() { - return (Date) this.creationTime.clone(); + public Instant getCreationTime() { + return this.creationTime; } /** * @return the creation time */ public Instant getCreationTimeInstant() { - return this.creationTime.toInstant(); + return this.creationTime; } /** * @return the modification time */ - public Date getModificationTime() { - return (Date) this.modificationTime.clone(); + public Instant getModificationTime() { + return this.modificationTime; } /** * @return the modification time */ public Instant getModificationTimeInstant() { - return this.modificationTime.toInstant(); + return this.modificationTime; } /** @@ -99,7 +98,7 @@ public void setVersion(final Long newVersion) { /** Method for actions to be taken before inserting. */ @PrePersist private void prePersist() { - final Date now = new Date(); + final Instant now = Instant.now(); this.creationTime = now; this.modificationTime = now; } @@ -107,7 +106,7 @@ private void prePersist() { /** Method for actions to be taken before updating. */ @PreUpdate private void preUpdate() { - this.modificationTime = new Date(); + this.modificationTime = Instant.now(); } // === METHODS [END] === diff --git a/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/infra/jms/Constants.java b/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/infra/jms/Constants.java index 00e7d69994e..c1a0c9aa348 100644 --- a/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/infra/jms/Constants.java +++ b/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/infra/jms/Constants.java @@ -20,10 +20,11 @@ public class Constants { public static final String DEVICE_IDENTIFICATION = "DeviceIdentification"; /** JMS constant for message field: IPAddress. */ - public static final String IP_ADDRESS = "IPAddress"; + public static final String NETWORK_ADDRESS = "NetworkAddress"; /** JMS constant for message field: BtsId. */ public static final String BASE_TRANSCEIVER_STATION_ID = "BtsId"; + /** JMS constant for message field: CellId. */ public static final String CELL_ID = "CellId"; @@ -138,6 +139,9 @@ public class Constants { /** JMS constant for a topic associated with the message. */ public static final String TOPIC = "Topic"; + /** JMS constant for message field: DeviceModelCode. */ + public static final String DEVICE_MODEL_CODE = "DeviceModelCode"; + // === DEPRECATED === /** DEPRECATED JMS constant for message field: ErrorMessage. */ diff --git a/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/infra/jms/MessageMetadata.java b/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/infra/jms/MessageMetadata.java index a5ebc21fe53..a2fd529afa8 100644 --- a/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/infra/jms/MessageMetadata.java +++ b/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/infra/jms/MessageMetadata.java @@ -23,7 +23,7 @@ public class MessageMetadata implements Serializable { private String messageType; private String domain; private String domainVersion; - private String ipAddress; + private String networkAddress; private Integer baseTransceiverStationId; private Integer cellId; private int messagePriority; @@ -34,6 +34,7 @@ public class MessageMetadata implements Serializable { private int retryCount; private int jmsxDeliveryCount; private String topic; + private String deviceModelCode; private MessageMetadata() { // Default private constructor. @@ -46,7 +47,7 @@ private MessageMetadata(final Builder builder) { this.messageType = builder.messageType; this.domain = builder.domain; this.domainVersion = builder.domainVersion; - this.ipAddress = builder.ipAddress; + this.networkAddress = builder.networkAddress; this.baseTransceiverStationId = builder.baseTransceiverStationId; this.cellId = builder.cellId; this.messagePriority = builder.messagePriority; @@ -57,6 +58,7 @@ private MessageMetadata(final Builder builder) { this.retryCount = builder.retryCount; this.jmsxDeliveryCount = builder.jmsxDeliveryCount; this.topic = builder.topic; + this.deviceModelCode = builder.deviceModelCode; } public static MessageMetadata fromMessage(final Message message) throws JMSException { @@ -76,8 +78,8 @@ public static MessageMetadata fromMessage(final Message message) throws JMSExcep metadata.domainVersion = metadata.getStringProperty(message, Constants.DOMAIN_VERSION, StringUtils.EMPTY); - metadata.ipAddress = - metadata.getStringProperty(message, Constants.IP_ADDRESS, StringUtils.EMPTY); + metadata.networkAddress = + metadata.getStringProperty(message, Constants.NETWORK_ADDRESS, StringUtils.EMPTY); metadata.baseTransceiverStationId = metadata.getIntProperty(message, Constants.BASE_TRANSCEIVER_STATION_ID, null); @@ -93,6 +95,9 @@ public static MessageMetadata fromMessage(final Message message) throws JMSExcep metadata.topic = metadata.getStringProperty(message, Constants.TOPIC, StringUtils.EMPTY); + metadata.deviceModelCode = + metadata.getStringProperty(message, Constants.DEVICE_MODEL_CODE, StringUtils.EMPTY); + return metadata; } @@ -117,8 +122,8 @@ public void applyTo(final Message message) throws JMSException { message.setStringProperty(Constants.DOMAIN_VERSION, this.domainVersion); } - if (StringUtils.isNotBlank(this.ipAddress)) { - message.setStringProperty(Constants.IP_ADDRESS, this.ipAddress); + if (StringUtils.isNotBlank(this.networkAddress)) { + message.setStringProperty(Constants.NETWORK_ADDRESS, this.networkAddress); } if (this.baseTransceiverStationId != null) { @@ -143,6 +148,10 @@ public void applyTo(final Message message) throws JMSException { message.setStringProperty(Constants.TOPIC, this.topic); } + if (StringUtils.isNotBlank(this.deviceModelCode)) { + message.setStringProperty(Constants.DEVICE_MODEL_CODE, this.deviceModelCode); + } + /* * Not setting the jmsxDeliveryCount as int property named Constants.DELIVERY_COUNT, because * this is not some metadata to be transferred over to new JMS messages. This delivery count is @@ -192,6 +201,9 @@ public String toString() { } public static class Builder { + + private String deviceModelCode; + private String correlationUid; private String organisationIdentification; private String deviceIdentification; @@ -199,7 +211,7 @@ public static class Builder { private String domain = StringUtils.EMPTY; private String domainVersion = StringUtils.EMPTY; - private String ipAddress = StringUtils.EMPTY; + private String networkAddress = StringUtils.EMPTY; private Integer baseTransceiverStationId = null; private Integer cellId = null; private int messagePriority = 0; @@ -218,7 +230,7 @@ public Builder(final MessageMetadata otherMetadata) { this.messageType = otherMetadata.getMessageType(); this.domain = otherMetadata.getDomain(); this.domainVersion = otherMetadata.getDomainVersion(); - this.ipAddress = otherMetadata.getIpAddress(); + this.networkAddress = otherMetadata.getNetworkAddress(); this.baseTransceiverStationId = otherMetadata.getBaseTransceiverStationId(); this.cellId = otherMetadata.getCellId(); this.messagePriority = otherMetadata.getMessagePriority(); @@ -229,6 +241,7 @@ public Builder(final MessageMetadata otherMetadata) { this.retryCount = otherMetadata.getRetryCount(); this.jmsxDeliveryCount = otherMetadata.getJmsxDeliveryCount(); this.topic = otherMetadata.getTopic(); + this.deviceModelCode = otherMetadata.getDeviceModelCode(); } public Builder( @@ -274,8 +287,8 @@ public Builder withDomainVersion(final String domainVersion) { return this; } - public Builder withIpAddress(final String ipAddress) { - this.ipAddress = ipAddress; + public Builder withNetworkAddress(final String networkAddress) { + this.networkAddress = networkAddress; return this; } @@ -327,6 +340,11 @@ public Builder withTopic(final String topic) { return this; } + public Builder withDeviceModelCode(final String deviceModelCode) { + this.deviceModelCode = deviceModelCode; + return this; + } + public MessageMetadata build() { return new MessageMetadata(this); } diff --git a/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/infra/jms/ObjectMessageBuilder.java b/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/infra/jms/ObjectMessageBuilder.java index 44dd5806cd0..3c86960ba18 100644 --- a/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/infra/jms/ObjectMessageBuilder.java +++ b/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/infra/jms/ObjectMessageBuilder.java @@ -13,16 +13,16 @@ public class ObjectMessageBuilder { private String correlationUid = "test-corr-uid"; private String deviceIdentification = "test-dvc"; - private String domain = "domain"; - private String domainVersion = "domain-version"; + private final String domain = "domain"; + private final String domainVersion = "domain-version"; private String ipAddress = "localhost"; private String organisationIdentification = "test-org"; private String messageType; private Serializable object = null; - private int retryCount = 0; - private int messagePriority = 0; - private boolean bypassRetry = false; - private boolean scheduled = false; + private final int retryCount = 0; + private final int messagePriority = 0; + private final boolean bypassRetry = false; + private final boolean scheduled = false; public ObjectMessageBuilder withCorrelationUid(final String correlationUid) { this.correlationUid = correlationUid; @@ -67,7 +67,7 @@ public ObjectMessage build() throws JMSException { message.setBooleanProperty(Constants.BYPASS_RETRY, this.bypassRetry); message.setStringProperty(Constants.DOMAIN, this.domain); message.setStringProperty(Constants.DOMAIN_VERSION, this.domainVersion); - message.setStringProperty(Constants.IP_ADDRESS, this.ipAddress); + message.setStringProperty(Constants.NETWORK_ADDRESS, this.ipAddress); message.setBooleanProperty(Constants.IS_SCHEDULED, this.scheduled); message.setObject(this.object); diff --git a/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/infra/jms/ProtocolRequestMessage.java b/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/infra/jms/ProtocolRequestMessage.java index f6bca68b312..e6a65bbf381 100644 --- a/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/infra/jms/ProtocolRequestMessage.java +++ b/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/infra/jms/ProtocolRequestMessage.java @@ -21,6 +21,8 @@ public class ProtocolRequestMessage extends RequestMessage { private final boolean bypassRetry; private final int retryCount; + private final String deviceModelCode; + private ProtocolRequestMessage(final Builder builder) { super( builder.correlationUid, @@ -40,6 +42,7 @@ private ProtocolRequestMessage(final Builder builder) { this.maxScheduleTime = builder.maxScheduleTime; this.bypassRetry = builder.bypassRetry; this.retryCount = builder.retryCount; + this.deviceModelCode = builder.deviceModelCode; } public String getDomain() { @@ -78,6 +81,10 @@ public boolean bypassRetry() { return this.bypassRetry; } + public String getDeviceModelCode() { + return this.deviceModelCode; + } + @Override public MessageMetadata messageMetadata() { return super.messageMetadata() @@ -90,6 +97,7 @@ public MessageMetadata messageMetadata() { .withMaxScheduleTime(this.maxScheduleTime) .withBypassRetry(this.bypassRetry) .withRetryCount(this.retryCount) + .withDeviceModelCode(this.deviceModelCode) .build(); } @@ -116,6 +124,8 @@ public static class Builder { private int retryCount; private Serializable request; + private String deviceModelCode; + public Builder messageMetadata(final MessageMetadata messageMetadata) { this.deviceIdentification = messageMetadata.getDeviceIdentification(); this.organisationIdentification = messageMetadata.getOrganisationIdentification(); @@ -123,7 +133,7 @@ public Builder messageMetadata(final MessageMetadata messageMetadata) { this.messageType = messageMetadata.getMessageType(); this.domain = messageMetadata.getDomain(); this.domainVersion = messageMetadata.getDomainVersion(); - this.ipAddress = messageMetadata.getIpAddress(); + this.ipAddress = messageMetadata.getNetworkAddress(); this.baseTransceiverStationId = messageMetadata.getBaseTransceiverStationId(); this.cellId = messageMetadata.getCellId(); this.messagePriority = messageMetadata.getMessagePriority(); @@ -131,6 +141,8 @@ public Builder messageMetadata(final MessageMetadata messageMetadata) { this.maxScheduleTime = messageMetadata.getMaxScheduleTime(); this.bypassRetry = messageMetadata.isBypassRetry(); this.retryCount = messageMetadata.getRetryCount(); + this.deviceModelCode = messageMetadata.getDeviceModelCode(); + return this; } diff --git a/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/infra/jms/RequestMessage.java b/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/infra/jms/RequestMessage.java index f5bae402b50..050d89f86cb 100644 --- a/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/infra/jms/RequestMessage.java +++ b/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/infra/jms/RequestMessage.java @@ -24,7 +24,7 @@ public RequestMessage(final MessageMetadata messageMetadata, final Serializable messageMetadata.getCorrelationUid(), messageMetadata.getOrganisationIdentification(), messageMetadata.getDeviceIdentification(), - messageMetadata.getIpAddress(), + messageMetadata.getNetworkAddress(), messageMetadata.getBaseTransceiverStationId(), messageMetadata.getCellId(), request); @@ -113,7 +113,7 @@ public MessageMetadata messageMetadata() { .withDeviceIdentification(this.deviceIdentification) .withOrganisationIdentification(this.organisationIdentification) .withCorrelationUid(this.correlationUid) - .withIpAddress(this.ipAddress) + .withNetworkAddress(this.ipAddress) .withNetworkSegmentIds(this.baseTransceiverStationId, this.cellId) .build(); } diff --git a/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/infra/networking/ping/CommandExecutor.java b/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/infra/networking/ping/CommandExecutor.java index f4efde27c67..81c78c44364 100644 --- a/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/infra/networking/ping/CommandExecutor.java +++ b/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/infra/networking/ping/CommandExecutor.java @@ -25,6 +25,8 @@ public class CommandExecutor { private static final Logger LOGGER = LoggerFactory.getLogger(CommandExecutor.class); + private static final long AWAIT_TERMINATION_IN_SEC = 5; + public List execute(final List commands, final Duration timeout) throws IOException, TimeoutException, ExecutionException { @@ -32,27 +34,49 @@ public List execute(final List commands, final Duration timeout) final Process process = this.start(commands); final ExecutorService executorService = Executors.newSingleThreadExecutor(); + final Future> inputLines = + executorService.submit(() -> this.readLinesFromInput(process)); try { - final Future> inputLines = - executorService.submit(() -> this.readLinesFromInput(process)); return inputLines.get(timeout.toMillis(), TimeUnit.MILLISECONDS); + } catch (final TimeoutException e) { + inputLines.cancel(true); + throw e; } catch (final InterruptedException e) { - Thread.currentThread().interrupt(); LOGGER.warn( "Reading input lines from executed process was interrupted: \"{}\"", commandLine, e); } finally { - executorService.shutdownNow(); - if (process.isAlive()) { - LOGGER.debug("Destroy the process running \"{}\"", commandLine); - process.destroyForcibly(); - } else { - LOGGER.debug( - "Process running \"{}\" ended with exit value: {}", commands, process.exitValue()); - } + this.shutdownAndAwaitTermination(executorService); + this.destroyProcess(process, commands); } return Collections.emptyList(); } + private void destroyProcess(final Process process, final List commands) { + process.destroy(); + if (process.isAlive()) { + LOGGER.debug("Destroy the process running \"{}\"", commands); + process.destroyForcibly(); + } else { + LOGGER.debug( + "Process running \"{}\" ended with exit value: {}", commands, process.exitValue()); + } + } + + void shutdownAndAwaitTermination(final ExecutorService executorService) { + executorService.shutdown(); + try { + if (!executorService.awaitTermination(AWAIT_TERMINATION_IN_SEC, TimeUnit.SECONDS)) { + executorService.shutdownNow(); + if (!executorService.awaitTermination(AWAIT_TERMINATION_IN_SEC, TimeUnit.SECONDS)) { + LOGGER.error("Pool did not terminate"); + } + } + } catch (final InterruptedException ex) { + executorService.shutdownNow(); + Thread.currentThread().interrupt(); + } + } + private String commandLine(final List commands) { return String.join(" ", commands); } diff --git a/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/utils/FileZipper.java b/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/utils/FileZipper.java index 14598799321..a51d02b75d9 100644 --- a/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/utils/FileZipper.java +++ b/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/utils/FileZipper.java @@ -106,7 +106,7 @@ private void doCompressFile( final String zipEntryName, final int inMemoryBufferSize) throws IOException { - try (FileInputStream fileInputStream = new FileInputStream(inputFilePath); + try (final FileInputStream fileInputStream = new FileInputStream(inputFilePath); final ZipOutputStream zipOutputStream = this.createZipOutputStream(zipFilePath)) { this.createZipEntry(zipEntryName, zipOutputStream); this.writeZipFile(fileInputStream, zipOutputStream, inMemoryBufferSize); diff --git a/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/utils/JavaTimeHelpers.java b/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/utils/JavaTimeHelpers.java new file mode 100644 index 00000000000..c53a21db9d1 --- /dev/null +++ b/osgp/shared/shared/src/main/java/org/opensmartgridplatform/shared/utils/JavaTimeHelpers.java @@ -0,0 +1,63 @@ +package org.opensmartgridplatform.shared.utils; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.time.temporal.ChronoField; +import java.time.temporal.Temporal; +import java.util.Date; +import java.util.GregorianCalendar; + +public class JavaTimeHelpers { + + public static long getMillisFrom(final Temporal datetime) { + return datetime.get(ChronoField.MILLI_OF_SECOND); + } + + public static String formatDate(final Date date, final DateTimeFormatter formatter) { + return formatter.format(date.toInstant().atZone(ZoneId.systemDefault())); + } + + public static String formatDate(final Temporal date, final DateTimeFormatter formatter) { + return formatter.format(date); + } + + public static ZonedDateTime gregorianCalendarToZonedDateTime( + final GregorianCalendar gregorianCalendar, final ZoneId zoneId) { + return ZonedDateTime.ofInstant(gregorianCalendar.toInstant(), zoneId); + } + + public static int getOffsetForZonedDateTimeInMillis(final ZonedDateTime dateTime) { + return dateTime.getOffset().getTotalSeconds() * 1000; + } + + public static boolean isDayLightSavingsActive(final ZonedDateTime dateTime) { + return dateTime.getZone().getRules().isDaylightSavings(dateTime.toInstant()); + } + + /** + * Parses different kind of date strings to a ZonedDateTime. This method should not be used in + * production code. This code is created because the cucumber tests provides date strings in the + * following formats: - yyyy-mm-dd - yyyy-mm-dd:hh:mm:ss - yyyy-mm-dd:hh:mm:ss Z + * + * @param date the date string to parse + * @return ZonedDateTime parsed from the provided string + */ + @Deprecated + public static ZonedDateTime parseToZonedDateTime(final String date) { + ZonedDateTime zonedDateTime; + try { + zonedDateTime = ZonedDateTime.parse(date); + } catch (final DateTimeParseException firstAttempt) { + try { + zonedDateTime = LocalDateTime.parse(date).atZone(ZoneId.systemDefault()); + } catch (final DateTimeParseException secondAttempt) { + zonedDateTime = LocalDate.parse(date).atStartOfDay().atZone(ZoneId.systemDefault()); + } + } + return zonedDateTime; + } +} diff --git a/osgp/shared/shared/src/test/java/org/opensmartgridplatform/shared/utils/FileZipperTest.java b/osgp/shared/shared/src/test/java/org/opensmartgridplatform/shared/utils/FileZipperTest.java index 75bd934bb9c..5d805fbd5cf 100644 --- a/osgp/shared/shared/src/test/java/org/opensmartgridplatform/shared/utils/FileZipperTest.java +++ b/osgp/shared/shared/src/test/java/org/opensmartgridplatform/shared/utils/FileZipperTest.java @@ -6,6 +6,7 @@ import static org.assertj.core.api.Assertions.assertThat; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; @@ -57,22 +58,24 @@ public void createAndValidateZipFile() throws IOException { } private void validateZipFileContent(final File zipFile) throws IOException { - final StringBuilder stringBuilder = new StringBuilder(); + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try (ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipFile))) { + try (final ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipFile))) { ZipEntry zipEntry = zipInputStream.getNextEntry(); - final byte[] buffer = new byte[1024]; while (zipEntry != null) { - while (zipInputStream.read(buffer) > 0) { - stringBuilder.append(new String(buffer, StandardCharsets.UTF_8).trim()); + final byte[] buf = new byte[1024]; + int length; + while ((length = zipInputStream.read(buf, 0, buf.length)) >= 0) { + baos.write(buf, 0, length); } zipEntry = zipInputStream.getNextEntry(); } zipInputStream.closeEntry(); } - final String content = stringBuilder.toString(); - assertThat(content).isEqualTo(this.lines.get(0)); + final String content = baos.toString(); + assertThat(content) + .isEqualTo(String.join(System.lineSeparator(), this.lines) + System.lineSeparator()); } } diff --git a/osgp/shared/shared/src/test/java/org/opensmartgridplatform/shared/utils/JavaTimeHelpersTest.java b/osgp/shared/shared/src/test/java/org/opensmartgridplatform/shared/utils/JavaTimeHelpersTest.java new file mode 100644 index 00000000000..df742bcc5e5 --- /dev/null +++ b/osgp/shared/shared/src/test/java/org/opensmartgridplatform/shared/utils/JavaTimeHelpersTest.java @@ -0,0 +1,113 @@ +package org.opensmartgridplatform.shared.utils; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Date; +import java.util.GregorianCalendar; +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; +import org.junit.jupiter.api.Test; + +class JavaTimeHelpersTest { + + public static final int MILLIS_TO_SECONDS = 1000; + + @Test + void shouldCropNanoToMillis() { + final ZonedDateTime dateWithNano = + ZonedDateTime.of(1998, 1, 24, 1, 1, 1, 123999999, ZoneId.systemDefault()); + final long croppedMillis = JavaTimeHelpers.getMillisFrom(dateWithNano); + assertThat(croppedMillis).isEqualTo(123); + } + + @Test + void shouldFormatDatesTheSameAsJoda() { + final Instant instant = Instant.ofEpochMilli(1000L); + final Date date = Date.from(instant); + + final String dateTimeFormat = "yyyy-MM-dd HH:mm:ss"; + final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateTimeFormat); + final String formattedJoda = new DateTime(date).toString(dateTimeFormat); + final String formattedJava = JavaTimeHelpers.formatDate(date, formatter); + + assertThat(formattedJoda).isEqualTo(formattedJava); + } + + @Test + void shouldMapGregorianCalendarTheSameAsJoda() { + final ZonedDateTime zonedDateTime = + ZonedDateTime.of(1998, 1, 24, 1, 1, 1, 123999999, ZoneId.systemDefault()); + final GregorianCalendar gregorianCalendar = GregorianCalendar.from(zonedDateTime); + + final DateTime joda = new DateTime(gregorianCalendar).toDateTime(DateTimeZone.UTC); + final ZonedDateTime javaApi = + JavaTimeHelpers.gregorianCalendarToZonedDateTime(gregorianCalendar, ZoneId.of("UTC")); + + this.validateJodaDateToJavaDate(javaApi, joda); + } + + @Test + void shouldDetermineDayLightSavingsCorrectly() { + final ZonedDateTime daylightSavingDate = + ZonedDateTime.of(2023, 3, 26, 2, 0, 0, 0, ZoneId.of("Europe/Amsterdam")); + + final ZonedDateTime notDaylightSavingDate = + ZonedDateTime.of(2023, 3, 25, 2, 0, 0, 0, ZoneId.of("Europe/Amsterdam")); + + assertThat(JavaTimeHelpers.isDayLightSavingsActive(daylightSavingDate)).isTrue(); + assertThat(JavaTimeHelpers.isDayLightSavingsActive(notDaylightSavingDate)).isFalse(); + } + + @Test + void shouldReturnSameOffsetAsJoda() { + final Instant instant = Instant.ofEpochMilli(1000L); + final Date date = Date.from(instant); + + final DateTime joda = new DateTime(date); + final ZonedDateTime java = ZonedDateTime.ofInstant(instant, ZoneId.systemDefault()); + + final int jodaOffset = joda.getZone().getOffset(joda.getMillis()); + final int javaOffset = JavaTimeHelpers.getOffsetForZonedDateTimeInMillis(java); + + assertThat(jodaOffset).isEqualTo(javaOffset); + } + + @Test + void shouldParseDatesLikeJoda() { + final String localDateString = "1998-01-24"; + final String localDateTimeString = "1998-01-24T13:00:00"; + final String zonedDateTimeString = "2015-03-29T02:00:00.000+01:00"; + + final ZonedDateTime localDateParsedJava = JavaTimeHelpers.parseToZonedDateTime(localDateString); + final ZonedDateTime localDateTimeParsedJava = + JavaTimeHelpers.parseToZonedDateTime(localDateTimeString); + final ZonedDateTime zonedDateTimeParsedJava = + JavaTimeHelpers.parseToZonedDateTime(zonedDateTimeString); + + final DateTime localDateParsedJoda = DateTime.parse(localDateString); + final DateTime localDateTimeParsedJoda = DateTime.parse(localDateTimeString); + final DateTime zonedDateTimeParsedJoda = DateTime.parse(zonedDateTimeString); + + this.validateJodaDateToJavaDate(localDateParsedJava, localDateParsedJoda); + this.validateJodaDateToJavaDate(localDateTimeParsedJava, localDateTimeParsedJoda); + this.validateJodaDateToJavaDate(zonedDateTimeParsedJava, zonedDateTimeParsedJoda); + } + + private void validateJodaDateToJavaDate(final ZonedDateTime javaApi, final DateTime joda) { + assertThat(javaApi.getYear()).isEqualTo(joda.getYear()); + assertThat(javaApi.getMonthValue()).isEqualTo(joda.getMonthOfYear()); + assertThat(javaApi.getDayOfMonth()).isEqualTo(joda.getDayOfMonth()); + assertThat(javaApi.getHour()).isEqualTo(joda.getHourOfDay()); + assertThat(javaApi.getMinute()).isEqualTo(joda.getMinuteOfHour()); + assertThat(javaApi.getSecond()).isEqualTo(joda.getSecondOfMinute()); + assertThat(JavaTimeHelpers.getMillisFrom(javaApi)).isEqualTo(joda.getMillisOfSecond()); + // Checks if the timezone offset in seconds is the same for joda and java api + assertThat(javaApi.getZone().getRules().getOffset(Instant.now()).getTotalSeconds()) + .isEqualTo(joda.getZone().getOffset(new DateTime().getMillis()) / MILLIS_TO_SECONDS); + } +} diff --git a/pom.xml b/pom.xml index b97b71e5f21..1d68b8db7b2 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ SPDX-License-Identifier: Apache-2.0 org.opensmartgridplatform open-smart-grid-platform - 5.45.0-SNAPSHOT + 5.49.0-SNAPSHOT pom 2.4.1 - 1.9.2 + 1.11.3 2.4.7.RELEASE 2.12.11 @@ -155,6 +155,15 @@ SPDX-License-Identifier: Apache-2.0 + + + + org.postgresql + postgresql + runtime + + + @@ -339,6 +348,11 @@ SPDX-License-Identifier: Apache-2.0 osgp-core-db-api-iec61850 ${osgp.version} + + org.opensmartgridplatform + osgp-jasper-shared + ${osgp.version} + org.opensmartgridplatform cucumber-tests-core @@ -876,13 +890,6 @@ SPDX-License-Identifier: Apache-2.0 org.openmuc jdlms ${openmuc.jdlms.version} - - - - org.bouncycastle - bcprov-jdk15on - -