/// <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; }
public abstract MeterReading editMeterReading(int meterReadingId, MeterReading newReading);
public abstract int saveMeterReading(MeterReading meterReading);
/// <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; }
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; }
private MeterReading getNextReading(Meter meter, MeterReading reading) { ///deal with no meter readings if (meter.Register == null | meter.Register.Count == 0) { return null; } else { meter.Register = meter.Register.OrderBy(rdg => rdg.Date).ToList(); foreach (MeterReading rdg in meter.Register) { ///register is in ascending date order so the first reading with a date greater than the ///submitted reading is the required reading if (rdg.Date > reading.Date) return rdg; } ///if all readings are younger than the submitted reading return null 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 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); }
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; }
/// <summary> /// Saves the meter reading object to the database /// </summary> /// <param name="meterReading"></param> public override int saveMeterReading(MeterReading meterReading) { emdb.MeterReadings.Add(meterReading); emdb.SaveChanges(); return meterReading.Id; }
public override MeterReading editMeterReading(int meterReadingId, MeterReading newReading) { MeterReading oldReading = emdb.MeterReadings.Find(meterReadingId); oldReading.Consumption = newReading.Consumption; oldReading.Date = newReading.Date; oldReading.Reading = newReading.Reading; emdb.SaveChanges(); return oldReading; }