GetPeriodicMeterReadsGasCommandExecutor extends
        AbstractPeriodicMeterReadsCommandExecutor<PeriodicMeterReadsRequestDto, PeriodicMeterReadGasResponseDto> { @Override public PeriodicMeterReadGasResponseDto execute(final DlmsConnectionManager conn, final DlmsDevice device, final PeriodicMeterReadsRequestDto periodicMeterReadsQuery) throws ProtocolAdapterException { if (periodicMeterReadsQuery == null) { throw new IllegalArgumentException( "PeriodicMeterReadsQuery should contain PeriodType, BeginDate and EndDate."); } final PeriodTypeDto queryPeriodType = periodicMeterReadsQuery.getPeriodType(); final DateTime from = new DateTime(periodicMeterReadsQuery.getBeginDate()); final DateTime to = new DateTime(periodicMeterReadsQuery.getEndDate()); final AttributeAddressForProfile profileBufferAddress = this.getProfileBufferAddress(queryPeriodType, periodicMeterReadsQuery.getChannel(), from, to, device); final List<AttributeAddress> scalerUnitAddresses = this.getScalerUnitAddresses( periodicMeterReadsQuery.getChannel(), profileBufferAddress); final Optional<ProfileCaptureTime> intervalTime = this.getProfileCaptureTime(device, this.dlmsObjectConfigService, Medium.GAS); LOGGER.info("Retrieving current billing period and profiles for gas for period type: {}, from: " + "{}, to: {}", queryPeriodType, from, to); final List<GetResult> getResultList = new ArrayList<>(); final List<AttributeAddress> 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)); } LOGGER.info("Received getResult: {} ", getResultList); final DataObject resultData = this.dlmsHelper.readDataObject(getResultList.get(0), PERIODIC_G_METER_READS); final List<DataObject> bufferedObjectsList = resultData.getValue(); final List<PeriodicMeterReadsGasResponseItemDto> periodicMeterReads = new ArrayList<>(); for (final DataObject bufferedObject : bufferedObjectsList) { final List<DataObject> bufferedObjectValue = bufferedObject.getValue(); try { periodicMeterReads.add(this.convertToResponseItem( new ConversionContext(periodicMeterReadsQuery, bufferedObjectValue, getResultList, profileBufferAddress, scalerUnitAddresses, intervalTime), periodicMeterReads)); } catch (final BufferedDateTimeValidationException e) { LOGGER.warn(e.getMessage(), e); } } LOGGER.info("Resulting periodicMeterReads: {} ", periodicMeterReads); return new PeriodicMeterReadGasResponseDto(queryPeriodType, periodicMeterReads); } @Autowired  GetPeriodicMeterReadsGasCommandExecutor(final DlmsHelper dlmsHelper,
            final AmrProfileStatusCodeHelper amrProfileStatusCodeHelper,
            final DlmsObjectConfigService dlmsObjectConfigService); @Override PeriodicMeterReadsRequestDto fromBundleRequestInput(final ActionRequestDto bundleInput); @Override PeriodicMeterReadGasResponseDto execute(final DlmsConnectionManager conn, final DlmsDevice device,
            final PeriodicMeterReadsRequestDto periodicMeterReadsQuery); @Override Logger getLogger();  }
@Test public void testExecuteNullRequest() throws ProtocolAdapterException { try { this.executor.execute(this.connectionManager, this.device, null); fail("Calling execute with null query should fail"); } catch (final IllegalArgumentException e) { } }
@Test public void testExecuteObjectNotFound() { final PeriodicMeterReadsRequestDto request = new PeriodicMeterReadsRequestDto(PeriodTypeDto.DAILY, this.fromDateTime.toDate(), this.toDateTime.toDate(), ChannelDto.ONE); when(this.dlmsObjectConfigService.findAttributeAddressForProfile(any(), any(), any(), any(), any(), any())) .thenReturn(Optional.empty()); try { this.executor.execute(this.connectionManager, this.device, request); 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); } }
@Test public void testHappy() throws Exception { final PeriodTypeDto periodType = PeriodTypeDto.DAILY; final ChannelDto channel = ChannelDto.ONE; final PeriodicMeterReadsRequestDto request = new PeriodicMeterReadsRequestDto(periodType, this.fromDateTime.toDate(), this.toDateTime.toDate(), channel); 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<DlmsCaptureObject> 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 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(this.fromDateTime), eq(this.toDateTime), 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)); final DataObject data0 = mock(DataObject.class); final DataObject data1 = mock(DataObject.class); final DataObject data2 = mock(DataObject.class); 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); final DataObject bufferedObject2 = mock(DataObject.class); when(bufferedObject2.getValue()).thenReturn(asList(data3, data4, data5)); final DataObject resultData = mock(DataObject.class); when(resultData.getValue()).thenReturn(asList(bufferedObject1, bufferedObject2)); final String expectedDescription = "retrieve periodic meter reads for " + periodType + ", channel " + channel; 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)); when(this.dlmsHelper.readDataObject(eq(getResult), any(String.class))).thenReturn(resultData); final String expectedDateTimeDescriptionLogTime = String.format("Clock from %s buffer", periodType); final String expectedDateTimeDescriptionCaptureTime = "Clock from mbus interval extended register"; final CosemDateTimeDto cosemDateTime = new CosemDateTimeDto(this.fromDateTime); when(this.dlmsHelper.readDateTime(data0, expectedDateTimeDescriptionLogTime)).thenReturn(cosemDateTime); when(this.dlmsHelper.readDateTime(data3, expectedDateTimeDescriptionLogTime)).thenReturn(cosemDateTime); when(this.dlmsHelper.readDateTime(data2, expectedDateTimeDescriptionCaptureTime)).thenReturn(cosemDateTime); when(this.dlmsHelper.readDateTime(data5, expectedDateTimeDescriptionCaptureTime)).thenReturn(cosemDateTime); 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); final PeriodicMeterReadGasResponseDto result = this.executor.execute(this.connectionManager, this.device, request); verify(this.dlmsMessageListener).setDescription(String.format( "GetPeriodicMeterReadsGas for channel ONE, DAILY from %s until %s, retrieve attribute: {%s,%s,%s}", new DateTime(this.from), new DateTime(this.to), dlmsProfile.getClassId(), dlmsProfile.getObisCodeAsString(), dlmsProfile.getDefaultAttributeId())); verify(this.dlmsHelper, times(2)).validateBufferedDateTime(any(DateTime.class), argThat(new DateTimeMatcher(this.from)), argThat(new DateTimeMatcher(this.to))); verify(this.dlmsObjectConfigService).findDlmsObject(any(Protocol.class), any(DlmsObjectType.class), any(Medium.class)); final List<PeriodicMeterReadsGasResponseItemDto> periodicMeterReads = result.getPeriodicMeterReadsGas(); assertThat(periodicMeterReads.size()).isEqualTo(2); assertThat(periodicMeterReads.stream().anyMatch(r -> r.getConsumption() == meterValue1)).isEqualTo(true); assertThat(periodicMeterReads.stream().anyMatch(r -> r.getConsumption() == meterValue2)).isEqualTo(true); assertThat(periodicMeterReads.stream().allMatch(r -> this.areDatesEqual(r.getLogTime(), cosemDateTime))) .isEqualTo(true); assertThat(periodicMeterReads.stream().allMatch(r -> this.areDatesEqual(r.getCaptureTime(), cosemDateTime))) .isEqualTo(true); }