Beispiel #1
0
def get_sensor_by_generic_asset_type_and_location(
    generic_asset_type_name: str, latitude: float = 0, longitude: float = 0
) -> Union[Sensor, ResponseTuple]:
    """
    Search a sensor by generic asset type and location.
    Can create a sensor if needed (depends on API mode)
    and then inform the requesting user which one to use.
    """
    # Look for the Sensor object
    sensor = (
        Sensor.query.join(GenericAsset)
        .join(GenericAssetType)
        .filter(GenericAssetType.name == generic_asset_type_name)
        .filter(GenericAsset.generic_asset_type_id == GenericAssetType.id)
        .filter(GenericAsset.latitude == latitude)
        .filter(GenericAsset.longitude == longitude)
        .filter(Sensor.generic_asset_id == GenericAsset.id)
        .one_or_none()
    )
    if sensor is None:
        create_sensor_if_unknown = False
        if current_app.config.get("FLEXMEASURES_MODE", "") == "play":
            create_sensor_if_unknown = True

        # either create a new weather sensor and post to that
        if create_sensor_if_unknown:
            current_app.logger.info("CREATING NEW WEATHER SENSOR...")
            weather_sensor = WeatherSensor(
                name="Weather sensor for %s at latitude %s and longitude %s"
                % (generic_asset_type_name, latitude, longitude),
                weather_sensor_type_name=generic_asset_type_name,
                latitude=latitude,
                longitude=longitude,
            )
            db.session.add(weather_sensor)
            db.session.flush()  # flush so that we can reference the new object in the current db session
            sensor = weather_sensor.corresponding_sensor

        # or query and return the nearest sensor and let the requesting user post to that one
        else:
            nearest_weather_sensor = WeatherSensor.query.order_by(
                WeatherSensor.great_circle_distance(
                    latitude=latitude, longitude=longitude
                ).asc()
            ).first()
            if nearest_weather_sensor is not None:
                return unrecognized_sensor(
                    *nearest_weather_sensor.location,
                )
            else:
                return unrecognized_sensor()
    return sensor
Beispiel #2
0
def add_test_weather_sensor_and_forecasts(db: SQLAlchemy):
    """one day of test data (one complete sine curve) for two sensors"""
    data_source = DataSource.query.filter_by(name="Seita",
                                             type="demo script").one_or_none()
    for sensor_name in ("radiation", "wind_speed"):
        sensor_type = WeatherSensorType(name=sensor_name)
        sensor = WeatherSensor(name=sensor_name,
                               sensor_type=sensor_type,
                               latitude=100,
                               longitude=100)
        db.session.add(sensor)
        time_slots = pd.date_range(datetime(2015, 1, 1),
                                   datetime(2015, 1, 2, 23, 45),
                                   freq="15T")
        values = [
            random() * (1 + np.sin(x / 15)) for x in range(len(time_slots))
        ]
        if sensor_name == "temperature":
            values = [value * 17 for value in values]
        if sensor_name == "wind_speed":
            values = [value * 45 for value in values]
        if sensor_name == "radiation":
            values = [value * 600 for value in values]
        for dt, val in zip(time_slots, values):
            db.session.add(
                Weather(
                    sensor=sensor,
                    datetime=as_server_time(dt),
                    value=val,
                    horizon=timedelta(hours=6),
                    data_source_id=data_source.id,
                ))
Beispiel #3
0
def find_closest_weather_sensor(
        sensor_type: str,
        n: int = 1,
        **kwargs) -> Union[WeatherSensor, List[WeatherSensor], None]:
    """Returns the closest n weather sensors of a given type (as a list if n > 1).
    Parses latitude and longitude values stated in kwargs.

    Can be called with an object that has latitude and longitude properties, for example:

        sensor = find_closest_weather_sensor("wind_speed", object=asset)

    Can also be called with latitude and longitude parameters, for example:

        sensor = find_closest_weather_sensor("temperature", latitude=32, longitude=54)
        sensor = find_closest_weather_sensor("temperature", lat=32, lng=54)

    """

    latitude, longitude = parse_lat_lng(kwargs)
    sensors = WeatherSensor.query.filter(
        WeatherSensor.weather_sensor_type_name == sensor_type).order_by(
            WeatherSensor.great_circle_distance(lat=latitude,
                                                lng=longitude).asc())
    if n == 1:
        return sensors.first()
    else:
        return sensors.limit(n).all()
Beispiel #4
0
def setup_ui_test_data(
    db,
    setup_accounts,
    setup_roles_users,
    setup_markets,
    setup_sources,
    setup_asset_types,
):
    """
    Create another prosumer, without data, and an admin
    Also, a weather sensor (and sensor type).

    TODO: review if any of these are really needed (might be covered now by main conftest)
    """
    print("Setting up data for UI tests on %s" % db.engine)

    create_user(
        username="******",
        email="*****@*****.**",
        password="******",
        account_name=setup_accounts["Prosumer"].name,
        user_roles=dict(name="admin", description="A site admin."),
    )

    test_user_ui = create_user(
        username="******",
        email="*****@*****.**",
        password="******",
        account_name=setup_accounts["Prosumer"].name,
    )
    asset = Asset(
        name="solar pane 1",
        display_name="Solar Pane 1",
        asset_type_name="solar",
        unit="MW",
        capacity_in_mw=10,
        latitude=10,
        longitude=100,
        min_soc_in_mwh=0,
        max_soc_in_mwh=0,
        soc_in_mwh=0,
    )
    db.session.add(asset)
    asset.owner = test_user_ui

    # Create 1 weather sensor
    test_sensor_type = WeatherSensorType(name="irradiance")
    db.session.add(test_sensor_type)
    sensor = WeatherSensor(
        name="irradiance_sensor",
        weather_sensor_type_name="irradiance",
        latitude=33.4843866,
        longitude=126,
        unit="kW/m²",
    )
    db.session.add(sensor)

    print("Done setting up data for UI tests")
Beispiel #5
0
def get_weather_sensor_by(weather_sensor_type_name: str,
                          latitude: float = 0,
                          longitude: float = 0) -> WeatherSensor:
    """
    Search a weather sensor by type and location.
    Can create a weather sensor if needed (depends on API mode)
    and then inform the requesting user which one to use.
    """
    # Look for the WeatherSensor object
    weather_sensor = (WeatherSensor.query.filter(
        WeatherSensor.weather_sensor_type_name == weather_sensor_type_name).
                      filter(WeatherSensor.latitude == latitude).filter(
                          WeatherSensor.longitude == longitude).one_or_none())
    if weather_sensor is None:
        create_sensor_if_unknown = False
        if current_app.config.get("FLEXMEASURES_MODE", "") == "play":
            create_sensor_if_unknown = True

        # either create a new weather sensor and post to that
        if create_sensor_if_unknown:
            current_app.logger.info("CREATING NEW WEATHER SENSOR...")
            weather_sensor = WeatherSensor(
                name="Weather sensor for %s at latitude %s and longitude %s" %
                (weather_sensor_type_name, latitude, longitude),
                weather_sensor_type_name=weather_sensor_type_name,
                latitude=latitude,
                longitude=longitude,
            )
            db.session.add(weather_sensor)
            db.session.flush(
            )  # flush so that we can reference the new object in the current db session

        # or query and return the nearest sensor and let the requesting user post to that one
        else:
            nearest_weather_sensor = WeatherSensor.query.order_by(
                WeatherSensor.great_circle_distance(
                    latitude=latitude, longitude=longitude).asc()).first()
            if nearest_weather_sensor is not None:
                return unrecognized_sensor(
                    nearest_weather_sensor.latitude,
                    nearest_weather_sensor.longitude,
                )
            else:
                return unrecognized_sensor()
    return weather_sensor
Beispiel #6
0
def add_legacy_weather_sensors(db):
    test_sensor_type = WeatherSensorType(name="wind speed")
    db.session.add(test_sensor_type)
    wind_sensor = WeatherSensor(
        name="wind_speed_sensor",
        weather_sensor_type_name="wind speed",
        event_resolution=timedelta(minutes=5),
        latitude=33.4843866,
        longitude=126,
    )
    db.session.add(wind_sensor)
    test_sensor_type2 = WeatherSensorType(name="temperature")
    db.session.add(test_sensor_type2)
    temperature_sensor = WeatherSensor(
        name="temperature_sensor",
        weather_sensor_type_name="temperature",
        event_resolution=timedelta(minutes=5),
        latitude=33.4843866,
        longitude=126,
    )
    db.session.add(temperature_sensor)
Beispiel #7
0
def setup_ui_test_data(db):
    """
    Create another prosumer, without data, and an admin
    Also, a weather sensor (and sensor type).
    """
    print("Setting up data for UI tests on %s" % db.engine)

    create_user(
        username="******",
        email="*****@*****.**",
        password=hash_password("testtest"),
        user_roles=dict(name="admin", description="A site admin."),
    )

    test_prosumer2 = create_user(
        username="******",
        email="*****@*****.**",
        password=hash_password("testtest"),
        user_roles=dict(name="Prosumer",
                        description="A Prosumer with one asset but no data."),
    )
    asset = Asset(
        name="solar pane 1",
        display_name="Solar Pane 1",
        asset_type_name="solar",
        unit="MW",
        capacity_in_mw=10,
        latitude=10,
        longitude=100,
        min_soc_in_mwh=0,
        max_soc_in_mwh=0,
        soc_in_mwh=0,
    )
    db.session.add(asset)
    asset.owner = test_prosumer2

    # Create 1 weather sensor
    test_sensor_type = WeatherSensorType(name="radiation")
    db.session.add(test_sensor_type)
    sensor = WeatherSensor(
        name="radiation_sensor",
        weather_sensor_type_name="radiation",
        latitude=33.4843866,
        longitude=126,
        unit="kW/m²",
    )
    db.session.add(sensor)

    print("Done setting up data for UI tests")
Beispiel #8
0
def setup_api_test_data(db):
    """
    Set up data for API v1.1 tests.
    """
    print("Setting up data for API v1.1 tests on %s" % db.engine)

    from flexmeasures.data.models.user import User, Role
    from flexmeasures.data.models.assets import Asset, AssetType
    from flexmeasures.data.models.weather import WeatherSensor, WeatherSensorType

    user_datastore = SQLAlchemySessionUserDatastore(db.session, User, Role)

    # Create a user without proper registration as a data source
    user = user_datastore.create_user(
        username="******",
        email="*****@*****.**",
        password=hash_password("testtest"),
    )
    role = user_datastore.find_role("Prosumer")
    user_datastore.add_role_to_user(user, role)

    # Create a test user without a USEF role
    create_user(
        username="******",
        email="*****@*****.**",
        password=hash_password("testtest"),
    )

    # Create 3 test assets for the test_prosumer user
    test_prosumer = user_datastore.find_user(email="*****@*****.**")
    test_asset_type = AssetType(name="test-type")
    db.session.add(test_asset_type)
    asset_names = ["CS 1", "CS 2", "CS 3"]
    assets: List[Asset] = []
    for asset_name in asset_names:
        asset = Asset(
            name=asset_name,
            asset_type_name="test-type",
            event_resolution=timedelta(minutes=15),
            capacity_in_mw=1,
            latitude=100,
            longitude=100,
            unit="MW",
        )
        asset.owner = test_prosumer
        assets.append(asset)
        db.session.add(asset)

    # Add power forecasts to the assets
    cs_1 = Asset.query.filter(Asset.name == "CS 1").one_or_none()
    cs_2 = Asset.query.filter(Asset.name == "CS 2").one_or_none()
    cs_3 = Asset.query.filter(Asset.name == "CS 3").one_or_none()
    data_source = DataSource.query.filter(
        DataSource.user == test_prosumer).one_or_none()
    power_forecasts = []
    for i in range(6):
        p_1 = Power(
            datetime=isodate.parse_datetime("2015-01-01T00:00:00Z") +
            timedelta(minutes=15 * i),
            horizon=timedelta(hours=6),
            value=(300 + i) * -1,
            asset_id=cs_1.id,
            data_source_id=data_source.id,
        )
        p_2 = Power(
            datetime=isodate.parse_datetime("2015-01-01T00:00:00Z") +
            timedelta(minutes=15 * i),
            horizon=timedelta(hours=6),
            value=(300 - i) * -1,
            asset_id=cs_2.id,
            data_source_id=data_source.id,
        )
        p_3 = Power(
            datetime=isodate.parse_datetime("2015-01-01T00:00:00Z") +
            timedelta(minutes=15 * i),
            horizon=timedelta(hours=6),
            value=(0 + i) * -1,
            asset_id=cs_3.id,
            data_source_id=data_source.id,
        )
        power_forecasts.append(p_1)
        power_forecasts.append(p_2)
        power_forecasts.append(p_3)
    db.session.bulk_save_objects(power_forecasts)

    # Create 2 weather sensors
    test_sensor_type = WeatherSensorType(name="wind_speed")
    db.session.add(test_sensor_type)
    sensor = WeatherSensor(
        name="wind_speed_sensor",
        weather_sensor_type_name="wind_speed",
        event_resolution=timedelta(minutes=5),
        latitude=33.4843866,
        longitude=126,
        unit="m/s",
    )
    db.session.add(sensor)

    test_sensor_type = WeatherSensorType(name="temperature")
    db.session.add(test_sensor_type)
    sensor = WeatherSensor(
        name="temperature_sensor",
        weather_sensor_type_name="temperature",
        event_resolution=timedelta(minutes=5),
        latitude=33.4843866,
        longitude=126,
        unit="°C",
    )
    db.session.add(sensor)

    print("Done setting up data for API v1.1 tests")