public async Task AddTwoDifferentReadingsExpectBothToBeAdded() { SimpleInMemoryRepo inMemRepo = new SimpleInMemoryRepo(); MeterReading meterReading1 = new MeterReading() { AccountId = 1234, MeterReadingDateTime = new DateTime(2005, 5, 21), MeterReadValue = "00063" }; MeterReading meterReading2 = new MeterReading() { AccountId = 1234, MeterReadingDateTime = new DateTime(2005, 5, 21), MeterReadValue = "00064" }; MeterReading readingTask1 = await inMemRepo.AddReading(meterReading1); MeterReading readingTask2 = await inMemRepo.AddReading(meterReading2); Assert.IsNotNull(readingTask1); Assert.IsNotNull(readingTask2); }
public int createMeterReading(string date, int reading, int meterId, int propertyId) { Meter meter = mediator.DataManager.getMeter(meterId); MeterReading newReading = new MeterReading { Date = Convert.ToDateTime(date), Reading = reading }; ///check if this is the first reading for this meter if (meter.Register.Count == 0) { MeterReading firstReading = new MeterReading(); firstReading.Date = newReading.Date; firstReading.Reading = newReading.Reading; firstReading.Consumption = 0; int firstReadingId = mediator.DataManager.saveMeterReading(firstReading); mediator.DataManager.addReadingToMeter(firstReadingId, meter.Id); return(firstReadingId); } newReading.Consumption = calculatekWh(newReading, meter); int readingId = mediator.DataManager.saveMeterReading(newReading); mediator.DataManager.addReadingToMeter(readingId, meterId); ///update property's annual kWh total mediator.updatePropertyAnnualTotalkWh(propertyId); mediator.updateAnnualCO2(propertyId); return(readingId); }
public override async Task <StatusMessage> AddReading(ReadingPacket request, ServerCallContext context) { if (request.Successful == ReadingStatus.Success) { foreach (var reading in request.Readings) { var readingValue = new MeterReading() { CustomerId = reading.CustomerId, Value = reading.ReadingValue, ReadingDate = reading.ReadingTime.ToDateTime() }; _logger.LogInformation($"Adding {reading.ReadingValue}"); _repository.AddEntity(readingValue); } if (await _repository.SaveAllAsync()) { _logger.LogInformation("Successfully Saved new Readings..."); return(new StatusMessage() { Notes = "Successfully added to the database.", Status = ReadingStatus.Success }); } } _logger.LogError("Failed to Saved new Readings..."); return(new StatusMessage() { Notes = "Failed to store readings in Database", Status = ReadingStatus.Success }); }
public async Task <IActionResult> PutMeterReading([FromRoute] int id, [FromBody] MeterReading meterReading) { if (!ModelState.IsValid) { return(BadRequest(ModelState)); } if (id != meterReading.Id) { return(BadRequest()); } _context.Entry(meterReading).State = EntityState.Modified; try { await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!MeterReadingExists(id)) { return(NotFound()); } else { throw; } } return(NoContent()); }
/// <summary> /// Determines the measurement period of the specified interval reading list. /// </summary> /// <param name="meterReading">The meter reading with interval readings to check.</param> /// <param name="checkAll">If set to <c>true</c>, check all interval readings.</param> /// <returns>The most frequently found interval or <c>TimeSpan.Zero</c> if no valid interval was found.</returns> public static TimeSpan GetMeasurementPeriod(this MeterReading meterReading, bool checkAll = false) { if (meterReading.ReadingType.MeasurementPeriod != 0) { return(TimeSpan.FromSeconds(meterReading.ReadingType.MeasurementPeriod)); } // first check only values without critical or fatal errors foreach (var block in meterReading.IntervalBlocks) { var period = block.IntervalReadings.GetMeasurementPeriod(true, ignoreErrors: true); if (period != TimeSpan.Zero) { return(period); } } // if no measurement period was found, check again and include values with errors foreach (var block in meterReading.IntervalBlocks) { var period = block.IntervalReadings.GetMeasurementPeriod(true, ignoreErrors: false); if (period != TimeSpan.Zero) { return(period); } } return(TimeSpan.Zero); }
public async override Task <StatusMessage> AddReading(ReadingPacket request, ServerCallContext context) { var result = new StatusMessage() { Success = ReadingStatus.Failure }; try { if (request.Successful == ReadingStatus.Success) { foreach (var reading in request.Readings) { var read = new MeterReading { CustomerId = reading.CustomerId, Value = reading.ReadingValue, ReadingDate = reading.ReadingTime.ToDateTime() }; readingRepository.AddEntity(read); } if (await readingRepository.SaveAllAsync()) { result.Success = ReadingStatus.Success; } } } catch (Exception ex) { result.Message = "Exception throwing during process"; logger.LogError($"Error occurred while processing : {ex}"); } return(result); }
public void deleteReading(int readingId, int meterId, int propertyId) { Meter meter = mediator.DataManager.getMeter(meterId); MeterReading deletedRead = mediator.DataManager.getReading(readingId); MeterReading nextRead = getNextReading(meter, deletedRead); ///check the deleted reading isn't the only or oldest reading in the list if (nextRead != null) { ///the consumption in the deleted reading needs to be added to the consumption ///of the next reading to maintain data integrity MeterReading updatedReading = new MeterReading { Date = nextRead.Date, Reading = nextRead.Reading, Consumption = nextRead.Consumption + deletedRead.Consumption }; mediator.DataManager.editMeterReading(nextRead.Id, updatedReading); } ///if the reading IS the only/oldest we can just delete it mediator.DataManager.deleteReading(readingId); mediator.updateAnnualCO2(propertyId); mediator.updatePropertyAnnualTotalkWh(propertyId); }
/// <summary> /// Calculates the energy in kWh for a given meter reading. Previous reading is retrieved from the Register of the meter and /// used in the calculation. NB kWh calculated to nearest whole number, rounding away from zero. /// </summary> /// <param name="reading">the MeterReading object of the current reading</param> /// <param name="meter">the Id of the meter the reading belongs to</param> /// <returns>kWh consumed as integer</returns> public int calculatekWh(MeterReading reading, Meter meter) { int kWh = 0; ///find the most recent reading before this one ///caculate the units consumed ///calculate the energy consumed --> need to know which meter this reading belongs to MeterReading previousReading = getPreviousReadingOnMeter(reading, meter); int unitsConsumed = calculateUnits(previousReading, reading, meter); ///to determine kWh need to know type of meter var elecMeter = meter as ElectricityMeter; if (elecMeter != null) { ///must be an electricity meter ///only coeff is scaling factor /// kWh = (int)Math.Round((double)unitsConsumed * elecMeter.ScalingFactor, MidpointRounding.AwayFromZero); } else { ///must be a gas meter var gasMeter = meter as GasMeter; kWh = (int)Math.Round( (double)unitsConsumed * gasMeter.MeterCoefficient ///converts from units on meter to m3 (defined in constructor) * gasMeter.CalorificValue ///converts from m3 into joules (defined in constructor) * gasMeter.CorrectionFactor ///corrects joules for standard room temp and pressure / EMConverter.fromJoulesTokWh, ///converts from joules to kWh, static property of EMConverter class MidpointRounding.AwayFromZero); } return(kWh); }
// Validation of an MeterReading instance private static void ValidateMeterReading(MeterReading meterReading, List <Exception> exceptions) { if (string.IsNullOrWhiteSpace(meterReading.MeterReadingId)) { exceptions.Add(new InvalidOperationException("Das Element \"MeterReadingId\" enthält keinen gültigen Wert.")); } if (meterReading.ReadingType == null) { exceptions.Add(new InvalidOperationException("Das Element \"MeterReading\" muss das Element \"ReadingType\" enthalten.")); } else { ValidateReadingType(meterReading.ReadingType, exceptions); } if (meterReading.Meters.Count < 1) { exceptions.Add(new InvalidOperationException("Das Element \"MeterReading\" muss das Elemnt \"Meter\" enthalten.")); } if (meterReading.IntervalBlocks.Count < 1) { } else { foreach (IntervalBlock intervalBlock in meterReading.IntervalBlocks) { ValidateIntervalBlock(intervalBlock, exceptions); } } }
private static void Taf1RegisterMeterReading(this MeterReading meterReading, MeterReading oml, BillingPeriod billingPeriod, MeterReadingConfig meterReadingConfig) { var intervalBlock = InitIntervalBlockWithInterval(billingPeriod.Begin, (DateTime)billingPeriod.End); var period = meterReadingConfig.Taf1PeriodInMonth; var requiredValues = GetRequiredIntervalReadingsFromOML(oml, billingPeriod.Begin, (DateTime)billingPeriod.End); var timestamp = billingPeriod.Begin.AddMonths(period); var initValue = requiredValues.FirstOrDefault(val => val.TimePeriod.Start == billingPeriod.Begin).Value; var value = GetNextValue(initValue, requiredValues, timestamp, (DateTime)billingPeriod.End); while (timestamp <= billingPeriod.End) { var ir = new IntervalReading() { TimePeriod = new Interval() { Duration = 0, Start = timestamp }, Value = value }; SetStatusWord(ir, meterReadingConfig); ir.IntervalBlock = intervalBlock; intervalBlock.IntervalReadings.Add(ir); timestamp = timestamp.AddMonths(period); value = GetNextValue(initValue, requiredValues, timestamp, (DateTime)billingPeriod.End); } intervalBlock.MeterReading = meterReading; meterReading.IntervalBlocks.Add(intervalBlock); }
/// <summary> /// The main calculation method for the accounting period in Taf-1. /// </summary> /// <param name="supplier">Contains the calculation data.</param> /// <param name="meterReading">The MeterReading instance with the raw data.</param> /// <param name="startReading">The intervalReading at the beginning of the section.</param> /// <param name="endReading">The intervalReading at the end of the section.</param> /// <param name="tariffId">The valid tariffId.</param> /// <returns>The calculated AccountingSection</returns> public AccountingMonth GetSection(UsagePointLieferant supplier, MeterReading meterReading, IntervalReading startReading, IntervalReading endReading, ushort tariffId) { var registers = supplier.GetRegister(); this.UpdateReadingTypeFromOriginalValueList(registers); var section = new AccountingMonth(registers) { Reading = new Reading() { Amount = startReading.Value, ObisCode = new ObisId(meterReading.ReadingType.ObisCode) } }; var start = startReading.TargetTime.Value; var end = endReading.TargetTime.Value; long amount = (long)(endReading.Value - startReading.Value); var range = new MeasuringRange(start, end, tariffId, amount); section.Add(range); section.Start = start; return(section); }
public void MeterLineIsValidExpectASuccessfulReading() { MeterReading expectedMeterReading = new MeterReading() { AccountId = 123, MeterReadingDateTime = new DateTime(2005, 5, 21), MeterReadValue = "00045" }; Mock <IMeterCsvValidator> mockValidator = new Mock <IMeterCsvValidator>(); Mock <IMeterCsvLineParser> mockLineParser = new Mock <IMeterCsvLineParser>(); mockValidator.Setup(v => v.ValidateHeaders(It.IsAny <string[]>(), It.IsAny <string[]>())).Returns(true); mockLineParser.Setup(p => p.TryParseMeterLine(It.IsAny <string>(), out expectedMeterReading)).Returns(true); MeterCsvReader meterCsvReader = new MeterCsvReader(mockValidator.Object, mockLineParser.Object); (var successFulReadings, var failedLines) = meterCsvReader.ParseCsv("abc\r\n\r\n123"); Assert.AreEqual(1, successFulReadings.Count); Assert.AreEqual(expectedMeterReading.AccountId, successFulReadings[0].AccountId); Assert.AreEqual(expectedMeterReading.MeterReadingDateTime, successFulReadings[0].MeterReadingDateTime); Assert.AreEqual(expectedMeterReading.MeterReadValue, successFulReadings[0].MeterReadValue); Assert.AreEqual(0, failedLines.Count); }
public async Task <IActionResult> PutMeterReading(DateTime id, MeterReading meterReading) { if (id != meterReading.MeterReadingDate) { return(BadRequest()); } _context.Entry(meterReading).State = EntityState.Modified; try { await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!MeterReadingExists(id)) { return(NotFound()); } else { throw; } } return(NoContent()); }
private int calculateUnits(MeterReading previousReading, MeterReading rdg, Meter meter) { int unitsConsumed = 0; string readingAsString = rdg.Reading.ToString(); ///truncate reading length if greater than no digits on meter if (readingAsString.Length > meter.NumbDigits) { readingAsString = readingAsString.Substring(0, meter.NumbDigits); rdg.Reading = int.Parse(readingAsString); } ///get max possible reading on this meter StringBuilder maxRead = new StringBuilder(); maxRead.Append('9', meter.NumbDigits); int maxPossibleReading = int.Parse(maxRead.ToString()); ///check if the meter has 'ticked over', ie gone past max reading if (previousReading.Reading > rdg.Reading) { ///meter has gone past the max read and started again ///therefore need units from previous --> max ///and from 0 --> current reading ///+1 for max --> 0 (eg 999999 + 1 will take the meter back to 0) unitsConsumed = maxPossibleReading - previousReading.Reading + rdg.Reading + 1; } else { ///units consumed is just the difference between prev and present unitsConsumed = rdg.Reading - previousReading.Reading; } return(unitsConsumed); }
public async Task Create(MeterReadingDTO dto) { //var flats = await buildingService.GetFlatDTO(dto.FlatId); //var period = await periodService.GetPeriodDTO(dto.PeriodId); Guid id = Guid.NewGuid(); using (MUEContext db = new MUEContext()) { var mr = await GetEntity(dto.FlatId, dto.PeriodId, dto.TypeofServiceId); if (mr != null) { await Delete(mr.MeterReadingId); } MeterReading meterReading = new MeterReading { FlatId = dto.FlatId, MeterReadingId = id, PeriodId = dto.PeriodId, TypeofServiceId = dto.TypeofServiceId, Value = dto.Value, }; db.MeterReadings.Add(meterReading); await db.SaveChangesAsync(); } }
/// <summary> /// Gets the previous reading on this meter, using the date of the reading object passed in /// </summary> /// <param name="currentReading"></param> /// <param name="meter"></param> /// <returns></returns> private MeterReading getPreviousReadingOnMeter(MeterReading currentReading, Meter meter) { MeterReading previousReading = new MeterReading(); meter.Register = meter.Register.OrderByDescending(rdg => rdg.Date).ToList(); foreach (MeterReading rdg in meter.Register) { ///where there is only one other reading, the other reading is the start date of the meter ///it is acceptable to have a reading on the start date so currentReading date >= rdg date if (meter.Register.Count == 1) { if (rdg.Date <= currentReading.Date) { return(rdg); } } else { ///there are other non-zero readings, so currentReading date > rdg date if (rdg.Date < currentReading.Date) { return(rdg); } } } /// return(null); }
public void editMeterReading(int readingId, int meterId, string readingJSON, int propertyId) { ///desrialise reading and update in the database MeterReading updatedReading = EMConverter.fromJSONtoA <MeterReading>(readingJSON); mediator.DataManager.editMeterReading(readingId, updatedReading); ///get the meter (now with updated reading) and recalc the consumption for each reading Meter meter = mediator.DataManager.getMeter(meterId); meter.Register = meter.Register.OrderBy(rdg => rdg.Date).ToList(); foreach (MeterReading rdg in meter.Register) { if (rdg.Date >= updatedReading.Date) { MeterReading revisedReading = new MeterReading { Date = rdg.Date, Reading = rdg.Reading }; revisedReading.Consumption = calculatekWh(revisedReading, meter); mediator.DataManager.editMeterReading(rdg.Id, revisedReading); } } mediator.updateAnnualCO2(propertyId); mediator.updatePropertyAnnualTotalkWh(propertyId); }
public async override Task AddReadingStream( IAsyncStreamReader <ReadingMessage> requestStream, IServerStreamWriter <ErrorMessage> responseStream, ServerCallContext context) { while (await requestStream.MoveNext()) { var msg = requestStream.Current; if (msg.ReadingValue < 500) { await responseStream.WriteAsync(new ErrorMessage() { Message = $"Value less than 500. Value: { msg.ReadingValue }" }); } var readingValue = new MeterReading() { CustomerId = msg.CustomerId, Value = msg.ReadingValue, ReadingDate = msg.ReadingTime.ToDateTime() }; _logger.LogInformation($"Adding {msg.ReadingValue} from Stream"); _repository.AddEntity(readingValue); await _repository.SaveAllAsync(); } }
public async Task UpdateMeterReading(MeterReading meterReadingToBeUpdated, MeterReading meterReading) { meterReadingToBeUpdated.MeterReadingDateTime = meterReading.MeterReadingDateTime; meterReadingToBeUpdated.MeterReadValue = meterReading.MeterReadValue; await _unitOfWork.CommitAsync(); }
private async Task <bool> AddMeterReading(string lineText) { try { var meterReadingDetails = lineText.Split(','); if (meterReadingDetails.Length != 3) { throw new Exception($"Invalid line was found: {lineText}"); } var accountNumber = meterReadingDetails[0]; if (!int.TryParse(accountNumber, out int accountNumberInteger)) { throw new Exception($"Account number is invalid: {accountNumber}"); } var account = await _context.Accounts.SingleOrDefaultAsync(x => x.AccountNumber == accountNumberInteger); if (account == null) { throw new Exception($"Account was not found: {accountNumberInteger}"); } if (!DateTime.TryParse(meterReadingDetails[1], out DateTime readingDateTime)) { throw new Exception($"Meter reading date is invalid: {meterReadingDetails[1]}"); } if (!int.TryParse(meterReadingDetails[2], out int readingValue)) { throw new Exception($"Meter reading value is invalid: {meterReadingDetails[2]}"); } if (_context.MeterReadings.Any(x => x.Value == readingValue && x.Account.AccountNumber == accountNumberInteger && x.DateTime == readingDateTime)) { throw new Exception($"Duplicate details were found: {lineText}"); } var meterReading = new MeterReading { Account = account, DateTime = readingDateTime, Value = readingValue }; _context.MeterReadings.Add(meterReading); await _context.SaveChangesAsync(); return(true); } catch (Exception e) { // TODO: Add to logs. Console.WriteLine(e); return(false); } }
public override async Task <StatusMessage> AddReading(ReadingPacket request, ServerCallContext context) { var result = new StatusMessage() { Success = ReadingStatus.Failure }; if (request.Successful == ReadingStatus.Success) { try { foreach (var r in request.Readings) { if (r.ReadingValue < 1000) { _logger.LogDebug("Reading value below acceptable level"); //throw new RpcException(Status.DefaultCancelled, "Value too low"); var trailer = new Metadata() { { "BadValue", r.ReadingValue.ToString() }, { "Field", "ReadingValue" }, { "Message", "Readings are invalid" } }; throw new RpcException(new Status(StatusCode.OutOfRange, "Value too low")); } //Save into db var reading = new MeterReading() { Value = r.ReadingValue, ReadingDate = r.ReadingTime.ToDateTime(), CustomerId = r.CustomerId }; _repository.AddEntity(reading); if (await _repository.SaveAllAsync()) { _logger.LogInformation($"{request.Readings.Count} New Readings ..."); result.Success = ReadingStatus.Success; } } } catch (RpcException) { throw; } catch (Exception e) { //result.Message = e.Message; _logger.LogError($"Exception thrown during saving of readings:{e}"); throw new RpcException(Status.DefaultCancelled, "Exception thrown during process"); } } //return base.AddReading(request, context); return(result); }
public ActionResult DeleteConfirmed(int id) { MeterReading meterReading = db.MeterReadings.Find(id); db.MeterReadings.Remove(meterReading); db.SaveChanges(); return(RedirectToAction("Index")); }
private async Task CreateMeterReading(MeterReading meterReading) { var newMeterReading = await _meterReadingService.CreateMeterReading(meterReading); var toMeterReadingResource = _mapper.Map <MeterReading, MeterReadingResource>(newMeterReading); _meterReadingReport.AddToMeterReadingValidationReport(toMeterReadingResource); }
public void addReadingToMeter(int readingId, int meterId) { MeterReading reading = emdb.MeterReadings.Find(readingId); Meter meter = emdb.Meters.Find(meterId); meter.Register.Add(reading); emdb.SaveChanges(); }
public async Task <MeterReading> AddMeterReading(MeterReading meterReading, CancellationToken token) { await _context.MeterReadings.AddAsync(meterReading, token); await _context.SaveChangesAsync(token); return(meterReading); }
public override async Task <StatusMessage> AddReading(ReadingPacket request, ServerCallContext context) { _logger.LogInformation($"AddReading function executed...."); var result = new StatusMessage { Successful = ReadingStatus.Failure }; if (request.Successful == ReadingStatus.Success) { try { foreach (var item in request.Readings) { if (item.ReadingValue < 1000) { var trailer = new Metadata { { "bad_value", item.ReadingValue.ToString().ToLower() }, { "message", "values are too low" } }; _logger.LogDebug("reading value below acceptable level"); throw new RpcException(new Status(StatusCode.OutOfRange, "Value too low"), trailer); } //save to the database var reading = new MeterReading() { Value = item.ReadingValue, ReadingDate = item.ReadingTime.ToDateTime(), CustomerId = item.CustomerId, }; repository.AddEntity(reading); _logger.LogInformation($"Adding Entity....{reading}"); } if (await repository.SaveAllAsync()) { _logger.LogInformation($"Stored {request.Readings.Count} New Readings...."); result.Successful = ReadingStatus.Success; } } catch (RpcException) { throw; } catch (System.Exception exception) { _logger.LogError($"Exception thrown during saving of readings: {exception}"); throw new RpcException(Status.DefaultCancelled, $"exception thrown during process {exception}"); } } return(result); }
public MeasuringRange(DateTime start, DateTime end, MeterReading mr, int amount) { this.Start = start; this.End = end; var obis = new ObisId(mr.ReadingType.ObisCode); this.TariffId = obis.E; this.Amount = amount; }
public async Task <MeterReading> CreateMeterReading(MeterReading newMeterReading) { await _unitOfWork.MeterReading .AddAsync(newMeterReading); await _unitOfWork.CommitAsync(); return(newMeterReading); }
private void DeleteReadingFromRepository(MeterReading meterReading) { m_Repository.DeleteObject(meterReading.DueDate); if (m_SelectedReading.EntryDate != null) { m_Repository.DeleteObject(m_SelectedReading.EntryDate); } m_Repository.MeterReadings.Remove(meterReading); }
public async override Task <StatusMessage> AddReading(ReadingPacket request, ServerCallContext context) { var result = new StatusMessage() { Success = ReadingStatus.Failure }; if (request.Successful == ReadingStatus.Success) { try { foreach (var r in request.Readings) { if (r.ReadingValue < 1000) { _logger.LogDebug("Reading value below acceptable level"); var trailer = new Metadata() { { "BadValue", r.ReadingValue.ToString() }, { "Field", "ReadingValue" }, { "Message", "Readings are invalid" } }; throw new RpcException(new Status(StatusCode.OutOfRange, "Value too low"), trailer); } var reading = new MeterReading() { Value = r.ReadingValue, ReadingDate = r.ReadingTime.ToDateTime(), CustomerId = r.CustomerId }; _repository.AddEntity(reading); } if (await _repository.SaveAllAsync()) { result.Success = ReadingStatus.Success; } } catch (RpcException) { throw; } catch (Exception ex) { _logger.LogError($"Exception: {ex.Message}"); throw new RpcException(Status.DefaultCancelled, $"Exception occured: {ex.Message}"); } } return(result); }
public void InsertMeterReading(MeterReading readings) { db.MeterReadings.AddObject(readings); }