def generate(self, pipeline: redis.client.Pipeline):
        meter_reading_dao = MeterReadingDaoRedis(self.redis, self.key_schema)

        for site in self.sites:
            max_capacity = self._get_max_minute_wh_generated(site.capacity)
            current_capacity = self._get_next_value(max_capacity)
            current_temperature = self._get_next_value(self.MAX_TEMPERATURE_C)
            current_usage = self._get_initial_minute_wh_used(max_capacity)
            current_time = datetime.datetime.utcnow() - datetime.timedelta(
                minutes=self.minute_days)

            for i in range(self.minute_days):
                reading = MeterReading(site_id=site.id,
                                       timestamp=current_time,
                                       wh_used=current_usage,
                                       wh_generated=current_capacity,
                                       temp_c=current_temperature)

                self.readings[site.id - 1][i] = reading

                current_time = current_time + datetime.timedelta(minutes=1)
                current_temperature = self._get_next_value(current_temperature)
                current_capacity = self._get_next_value(current_capacity)
                current_usage = self._get_next_value(current_usage)

        for i in range(self.minute_days):
            for j in range(len(self.sites)):
                reading = self.readings[j][i]
                meter_reading_dao.add(reading, pipeline=pipeline)
                yield reading
Ejemplo n.º 2
0
def readings():
    now = datetime.datetime.utcnow()
    yield [
        MeterReading(site_id=i,
                     timestamp=now,
                     wh_used=1.2,
                     wh_generated=i,
                     temp_c=22.0) for i in range(10)
    ]
Ejemplo n.º 3
0
def readings():
    now = datetime.datetime.utcnow()
    yield [
        MeterReading(site_id=i,
                     timestamp=now - datetime.timedelta(minutes=i),
                     wh_used=1.2,
                     wh_generated=i,
                     temp_c=22.0) for i in range(9, -1, -1)
    ]
Ejemplo n.º 4
0
def test_update(site_stats_dao: SiteStatsDaoRedis):
    reading1 = MeterReading(site_id=1,
                            timestamp=datetime.datetime.now(),
                            temp_c=15.0,
                            wh_generated=1.0,
                            wh_used=0.0)
    reading2 = MeterReading(site_id=1,
                            timestamp=datetime.datetime.now(),
                            temp_c=15.0,
                            wh_generated=2.0,
                            wh_used=0.0)

    site_stats_dao.update(reading1)
    site_stats_dao.update(reading2)

    stats = site_stats_dao.find_by_id(1, reading1.timestamp)

    assert stats.max_wh_generated == 2.0
    assert stats.min_wh_generated == 1.0
    assert stats.max_capacity == 2.0
Ejemplo n.º 5
0
def readings(metric_dao) -> Generator[Deque[MeterReading], None, None]:
    readings: deque = deque()
    time = NOW
    for i in range(72 * 60):
        readings.appendleft(
            MeterReading(site_id=1,
                         temp_c=i * 1.0,
                         wh_used=i * 1.0,
                         wh_generated=i * 1.0,
                         timestamp=time))
        time = time - datetime.timedelta(minutes=1)
    yield readings
Ejemplo n.º 6
0
def readings(metric_dao) -> Generator[List[MeterReading], None, None]:
    """Generate 72 hours worth of data."""
    readings = []
    time = NOW
    for i in range(72 * 60):
        readings.append(
            MeterReading(site_id=1,
                         temp_c=i * 1.0,
                         wh_used=i * 1.0,
                         wh_generated=i * 1.0,
                         timestamp=time))
        time = time - datetime.timedelta(minutes=1)
    yield readings
Ejemplo n.º 7
0
def test_datetime_is_unix_timestamp(metric_dao, client):
    reading = MeterReading(site_id=1,
                           temp_c=1.0,
                           wh_used=1.0,
                           wh_generated=1.0,
                           timestamp=NOW)
    metric_dao.insert(reading)

    resp = client.get(f'/metrics/{TESTING_SITE_ID}?count=1').json
    plots = resp['plots']
    measurement = plots[0]['measurements'][0]
    mdt = datetime.datetime.fromtimestamp(measurement['timestamp'])
    rdt = reading.timestamp
    assert mdt.hour == rdt.hour and mdt.minute == rdt.minute \
        and mdt.day == mdt.day and mdt.year == rdt.year
def test_calls_other_daos(meter_reading_dao):
    reading = MeterReading(site_id=1,
                           timestamp=datetime.datetime.now(),
                           temp_c=15.0,
                           wh_generated=0.025,
                           wh_used=0.015)

    meter_reading_dao['dao'].add(reading)
    mocks = meter_reading_dao['mocks']

    # Challenge #3
    # assert mocks['site_stats'].called is True
    assert mocks['metric'].called is True
    assert mocks['feed'].called is True
    assert mocks['capacity'].called is True
Ejemplo n.º 9
0
def test_site_readings_get_custom_count(client):
    now = datetime.datetime.utcnow()
    readings = [
        MeterReading(site_id=2,
                     timestamp=now - datetime.timedelta(minutes=i),
                     wh_used=1.2,
                     wh_generated=i,
                     temp_c=22.0) for i in range(9, -1, -1)
    ]
    data = MeterReadingsSchema().dump({"readings": readings})
    readings_post = client.post('/meter_readings', json=data)
    assert readings_post.status_code == 202

    readings_get = client.get('/meter_readings?count=2')
    assert readings_get.status_code == 200
    assert readings_get.json == MeterReadingsSchema().dump(
        {"readings": [readings[9], readings[8]]})
Ejemplo n.º 10
0
def readings(metric_dao) -> Generator[List[MeterReading], None, None]:
    """
    Generate 72 hours worth of data.

    Unlike with our sorted set implementation, RedisTimeSeries requires that we
    add entries in order. So we generate meter readings oldest to newest.

    We could also build a list and then reverse it, but where's the fun in
    that?
    """
    time = NOW - datetime.timedelta(hours=72)
    readings = []
    for i in range((72 * 60) - 1, -1, -1):
        readings.append(
            MeterReading(site_id=1,
                         temp_c=i * 1.0,
                         wh_used=i * 1.0,
                         wh_generated=i * 1.0,
                         timestamp=time))
        time = time + datetime.timedelta(minutes=1)
    yield readings
Ejemplo n.º 11
0
def test_find_by_geo_with_excess_capacity(site_geo_dao, capacity_dao):
    site1 = Site(id=1,
                 capacity=10.0,
                 panels=100,
                 address="100 SE Pine St.",
                 city="Portland",
                 state="OR",
                 postal_code="97202",
                 coordinate=PORTLAND)

    site_geo_dao.insert(site1)

    # Check that this site is returned when we're not looking for excess capacity.
    query = GeoQuery(coordinate=PORTLAND, radius=1, radius_unit=GeoUnit.MI)
    assert site_geo_dao.find_by_geo(query) == {site1}

    # Simulate changing a meter reading with no excess capacity.
    reading = MeterReading(site_id=site1.id,
                           wh_used=1.0,
                           wh_generated=0.0,
                           temp_c=10,
                           timestamp=datetime.datetime.now())
    capacity_dao.update(reading)

    # In this case, no sites are returned for an excess capacity query.
    query = GeoQuery(coordinate=PORTLAND,
                     radius=1,
                     radius_unit=GeoUnit.MI,
                     only_excess_capacity=True)
    sites = site_geo_dao.find_by_geo(query)
    assert len(sites) == 0

    # Simulate changing a meter reading indicating excess capacity.
    reading = MeterReading(site_id=site1.id,
                           wh_used=1.0,
                           wh_generated=2.0,
                           temp_c=10,
                           timestamp=datetime.datetime.now())
    capacity_dao.update(reading)

    # Add more Sites -- none with excess capacity -- to make the test more
    # realistic.
    for i in range(2, 20, 1):  # Site 1 is our expected site - skip it!
        site = Site(id=i,
                    capacity=10,
                    panels=100,
                    address=f"100{i} SE Pine St.",
                    city="Portland",
                    state="OR",
                    postal_code="97202",
                    coordinate=PORTLAND)

        site_geo_dao.insert(site)

        reading = MeterReading(site_id=i,
                               wh_used=i,
                               wh_generated=0,
                               temp_c=10,
                               timestamp=datetime.datetime.now())
        capacity_dao.update(reading)

    # In this case, one site is returned on the excess capacity query
    sites = site_geo_dao.find_by_geo(query)
    assert site1 in sites
Ejemplo n.º 12
0
def generate_meter_reading(site_id: int, datetime: datetime.datetime):
    return MeterReading(site_id=site_id,
                        timestamp=datetime,
                        temp_c=15.0,
                        wh_generated=0.025,
                        wh_used=0.015)