def test_can_create(): """We can create a NemSettlementPeriod.""" feb = datetime(2020, 2, 25, 12, 15, 12) set_per = NemSettlementPeriod(moment=feb) aest = timezone('Etc/GMT-10') assert set_per.start == aest.localize(datetime(2020, 2, 25, 12, 0, 0)) assert set_per.end == aest.localize(datetime(2020, 2, 25, 12, 30, 0)) assert set_per.start_date == date(2020, 2, 25) assert set_per.period_id == 25 # Can handle change of days day_shift = datetime(2020, 2, 25, 23, 45, 12) set_per = NemSettlementPeriod(moment=day_shift) assert set_per.start == aest.localize(datetime(2020, 2, 25, 23, 30, 0)) assert set_per.end == aest.localize(datetime(2020, 2, 26, 0, 0, 0)) assert set_per.period_id == 48 assert set_per.start_hour == 23 assert set_per.end_hour == 0 # Will convert a TZ aware datetime adelaide_tz = timezone('Australia/Adelaide') adelaide = adelaide_tz.localize(datetime(2020, 3, 23, 5, 34, 51)) adelaide_sp = NemSettlementPeriod(moment=adelaide) assert adelaide_sp.start.isoformat() == '2020-03-23T05:00:00+10:00'
def test_aggregation_by_period_from_samples(): """An energy object, created from samples, can be aggregated by period.""" sample_1_1 = WattSample(watts=10000, moment='2019-11-01T13:00:00') sample_2_1 = WattSample(watts=10000, moment='2019-11-01T13:30:00') sample_2_2 = WattSample(watts=20000, moment='2019-11-01T13:45:00') sample_3_1 = WattSample(watts=10000, moment='2019-11-01T14:05:00') sample_3_2 = WattSample(watts=30000, moment='2019-11-01T14:15:00') samples = [sample_1_1, sample_2_1, sample_2_2, sample_3_1, sample_3_2] energy = ElectricalEnergy.from_power_samples(samples) # Energy between 13:00 and 14:15 is of a varied nature. # # 1. 30min constant 10kW # 2. 15min varying from 10 to 20 kW (average 15) # 3. 20min varying from 20 to 10 kW (average 15) # 4. 10min varying from 10 to 30 kW (average 20) # Total: # Approx 17.083333 kWh over 1hr 15min (75min) assert energy.kwh == 5 + 3.75 + 5 + (20 * (10 / 60)) assert energy.time == 75 * 60 energy_periods = energy.by_period(NemSettlementPeriod) assert len(energy_periods) == 3 # FIRST PERIOD: periods_1 = energy_periods[0].settlement_periods(NemSettlementPeriod) assert len(periods_1) == 1 assert periods_1 == [NemSettlementPeriod('2019-11-01T13:00:00')] # Constant power of 10kW across the 30min, measured only at the start assert energy_periods[0].kwh == 5.0 assert len(energy_periods[0].samples) == 2 # SECOND PERIOD: periods_2 = energy_periods[1].settlement_periods(NemSettlementPeriod) assert len(periods_2) == 1 assert periods_2 == [NemSettlementPeriod('2019-11-01T13:30:00')] # 1. Power rises from 10 to 20 (mean 15kW) in first 15min # 2. Implied constant 20kW for the remaining 15min assert energy_periods[1].kwh == (15 * (15 / 60)) + (20 * (15 / 60)) assert len(energy_periods[1].samples) == 3 # THIRD PERIOD: periods_3 = energy_periods[2].settlement_periods(NemSettlementPeriod) assert len(periods_3) == 1 assert periods_3 == [NemSettlementPeriod('2019-11-01T14:00:00')] # 1. Initial 5min is constant 10kW # 2. Power rises from 10 to 30 (mean 20 kW) over the next 10min # 3. Constant power of 30kW for the final 15min # Total: # Approx 11.6667 across the 30min expeted_period_3 = (10 * (5 / 60)) + (20 * (10 / 60)) + (30 * (15 / 60)) assert energy_periods[2].kwh == expeted_period_3 assert len(energy_periods[2].samples) == 4
def test_can_compare(): """Can compare two periods.""" early = NemSettlementPeriod(datetime(2020, 2, 25, 12, 15, 12)) late = NemSettlementPeriod(datetime(2020, 2, 26, 12, 15, 12)) assert early < late # Same period assert NemSettlementPeriod(datetime(2020, 2, 25, 12, 15, 12)) == early # Same period, but instantiated one minute apart assert NemSettlementPeriod(datetime(2020, 2, 25, 12, 16, 12)) == early # Later period in an earlier day assert NemSettlementPeriod(datetime(2020, 2, 24, 14, 15, 12)) < early
def test_class_localize(): """Can localize a datetie to match this class timezone.""" naive = datetime(2019, 1, 1, 12, 00) localized_naive = NemSettlementPeriod.localize(naive).isoformat() assert localized_naive == "2019-01-01T12:00:00+10:00" utc_time = datetime(2019, 1, 1, 12, 00, tzinfo=timezone('UTC')) localized_utc_time = NemSettlementPeriod.localize(utc_time).isoformat() assert localized_utc_time == "2019-01-01T22:00:00+10:00" naive_str = "2019-01-01T12:00:00" localized_naive_str = NemSettlementPeriod.localize(naive_str).isoformat() assert localized_naive_str == "2019-01-01T12:00:00+10:00" utc_time_str = "2019-01-01T12:00:00Z" localized_utc_str = NemSettlementPeriod.localize(utc_time_str).isoformat() assert localized_utc_str == "2019-01-01T22:00:00+10:00"
def test_can_create(): """We can create a power sample.""" adelaide_tz = timezone('Australia/Adelaide') sample_time = adelaide_tz.localize(datetime(2020, 3, 23, 5, 34, 51)) power_sample = WattSample(watts=1000, moment=sample_time) assert power_sample.killowatts == 1 assert power_sample.megawatts == 0.001 sample_period = power_sample.settlement_period(NemSettlementPeriod) period = NemSettlementPeriod(moment=sample_time) assert sample_period == period decimal_power_sample = WattSample(watts=Decimal(1000), moment=sample_time) assert decimal_power_sample == power_sample
def test_settlement_period(sample_momemt, period_moment): """Test that it reports the correct SP.""" sample = WattSample(watts=1, moment=sample_momemt) period = NemSettlementPeriod(period_moment) assert sample.settlement_period(NemSettlementPeriod) == period
# 1. Initial 5min is constant 10kW # 2. Power rises from 10 to 30 (mean 20 kW) over the next 10min # 3. Constant power of 30kW for the final 15min # Total: # Approx 11.6667 across the 30min expeted_period_3 = (10 * (5 / 60)) + (20 * (10 / 60)) + (30 * (15 / 60)) assert energy_periods[2].kwh == expeted_period_3 assert len(energy_periods[2].samples) == 4 PERIOD_DATA = [ ( '2019-11-01T13:30:00', '2019-11-01T13:35:00', [ NemSettlementPeriod('2019-11-01T13:30:00') ] ), ( '2019-11-01T13:30:00', '2019-11-01T14:25:00', [ NemSettlementPeriod('2019-11-01T13:30:00'), NemSettlementPeriod('2019-11-01T14:00:00') ] ), ( '2019-11-01T13:00:00', '2019-11-01T14:35:00', [ NemSettlementPeriod('2019-11-01T13:00:00'),
def test_nem_accuracy(moment, start, period_id): """Test the correct NEM period is built.""" period = NemSettlementPeriod(moment) assert period.start == start assert period.period_id == period_id
def test_can_create_from_string(): """Can be created from a string.""" set_per = NemSettlementPeriod(moment="2020-02-25T12:00:00") aest = timezone('Etc/GMT-10') assert set_per.start == aest.localize(datetime(2020, 2, 25, 12, 0, 0))