def process_internal_api_response(asset_data: dict, asset_id: Optional[int] = None, make_obj=False) -> Union[GenericAsset, dict]: """ Turn data from the internal API into something we can use to further populate the UI. Either as an asset object or a dict for form filling. """ def expunge_asset(): # use if no insert is wanted from a previous query which flushes its results if asset in db.session: db.session.expunge(asset) asset_data.pop("status", None) # might have come from requests.response if asset_id: asset_data["id"] = asset_id if make_obj: asset = GenericAsset(**asset_data) # TODO: use schema? asset.generic_asset_type = GenericAssetType.query.get( asset.generic_asset_type_id) if "id" in asset_data: expunge_asset() asset.sensors = Sensor.query.filter( Sensor.generic_asset_id == asset_data["id"]).all() expunge_asset() return asset return asset_data
def post(self, asset_data: dict): """Create new asset. .. :quickref: Asset; Create a new asset This endpoint creates a new asset. **Example request** .. sourcecode:: json { "name": "Test battery", "generic_asset_type_id": 2, "account_id": 2, "latitude": 40, "longitude": 170.3, } The newly posted asset is returned in the response. :reqheader Authorization: The authentication token :reqheader Content-Type: application/json :resheader Content-Type: application/json :status 201: CREATED :status 400: INVALID_REQUEST :status 401: UNAUTHORIZED :status 403: INVALID_SENDER :status 422: UNPROCESSABLE_ENTITY """ asset = GenericAsset(**asset_data) db.session.add(asset) db.session.commit() return asset_schema.dump(asset), 201
def create_weather_sensors(db: SQLAlchemy, generic_asset_types) -> Dict[str, Sensor]: """Add a weather station asset with two weather sensors.""" weather_station = GenericAsset( name="Test weather station", generic_asset_type=generic_asset_types["weather_station"], latitude=33.4843866, longitude=126, ) db.session.add(weather_station) wind_sensor = Sensor( name="wind speed", generic_asset=weather_station, event_resolution=timedelta(minutes=5), unit="m/s", ) db.session.add(wind_sensor) temp_sensor = Sensor( name="temperature", generic_asset=weather_station, event_resolution=timedelta(minutes=5), unit="°C", ) db.session.add(temp_sensor) return {"wind": wind_sensor, "temperature": temp_sensor}
def query_sensors_by_proximity( latitude: float, longitude: float, generic_asset_type_name: Optional[str], sensor_name: Optional[str], account_id: Optional[int] = None, ) -> Query: """Order them by proximity of their asset's location to the target.""" from flexmeasures.data.models.time_series import Sensor closest_sensor_query = Sensor.query.join(GenericAsset).filter( Sensor.generic_asset_id == GenericAsset.id) if generic_asset_type_name: closest_sensor_query = closest_sensor_query.join(GenericAssetType) closest_sensor_query = closest_sensor_query.filter( Sensor.generic_asset_id == GenericAsset.id, GenericAsset.generic_asset_type_id == GenericAssetType.id, GenericAssetType.name == generic_asset_type_name, ) if sensor_name is not None: closest_sensor_query = closest_sensor_query.filter( Sensor.name == sensor_name) closest_sensor_query = closest_sensor_query.order_by( GenericAsset.great_circle_distance(lat=latitude, lng=longitude).asc()) closest_sensor_query = potentially_limit_query_to_account_assets( closest_sensor_query, account_id) return closest_sensor_query
def add_test_weather_sensor_and_forecasts(db: SQLAlchemy, setup_generic_asset_types): """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() weather_station = GenericAsset( name="Test weather station farther away", generic_asset_type=setup_generic_asset_types["weather_station"], latitude=100, longitude=100, ) for sensor_name, unit in (("irradiance", "kW/m²"), ("wind speed", "m/s")): sensor = Sensor(name=sensor_name, generic_asset=weather_station, unit=unit) 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 == "irradiance": values = [value * 600 for value in values] for dt, val in zip(time_slots, values): db.session.add( TimedBelief( sensor=sensor, event_start=as_server_time(dt), event_value=val, belief_horizon=timedelta(hours=6), source=data_source, ) )
def add_transmission_zone_asset(country_code: str, db: SQLAlchemy) -> GenericAsset: """ Ensure a GenericAsset exists to model a transmission zone for a country. """ transmission_zone_type = GenericAssetType.query.filter( GenericAssetType.name == "transmission zone").one_or_none() if not transmission_zone_type: click.echo("Adding transmission zone type ...") transmission_zone_type = GenericAssetType( name="transmission zone", description= "A grid regulated & balanced as a whole, usually a national grid.", ) db.session.add(transmission_zone_type) ga_name = f"{country_code} transmission zone" transmission_zone = GenericAsset.query.filter( GenericAsset.name == ga_name).one_or_none() if not transmission_zone: click.echo(f"Adding {ga_name} ...") transmission_zone = GenericAsset( name=ga_name, generic_asset_type=transmission_zone_type, account_id=None, # public ) return transmission_zone
def create_generic_assets(db, setup_generic_asset_types, setup_accounts): troposphere = GenericAsset( name="troposphere", generic_asset_type=setup_generic_asset_types["public_good"] ) db.session.add(troposphere) test_battery = GenericAsset( name="Test grid connected battery storage", generic_asset_type=setup_generic_asset_types["battery"], owner=setup_accounts["Prosumer"], ) db.session.add(test_battery) test_wind_turbine = GenericAsset( name="Test wind turbine", generic_asset_type=setup_generic_asset_types["wind"], owner=setup_accounts["Supplier"], ) db.session.add(test_wind_turbine) return dict( troposphere=troposphere, test_battery=test_battery, test_wind_turbine=test_wind_turbine, )
def add_nearby_weather_sensors(db, add_weather_sensors) -> Dict[str, Sensor]: temp_sensor_location = add_weather_sensors["temperature"].generic_asset.location weather_station_type = GenericAssetType.query.filter( GenericAssetType.name == "weather station" ).one_or_none() farther_weather_station = GenericAsset( name="Test weather station farther away", generic_asset_type=weather_station_type, latitude=temp_sensor_location[0], longitude=temp_sensor_location[1] + 0.1, ) db.session.add(farther_weather_station) farther_temp_sensor = Sensor( name="temperature", generic_asset=farther_weather_station, event_resolution=timedelta(minutes=5), unit="°C", ) db.session.add(farther_temp_sensor) even_farther_weather_station = GenericAsset( name="Test weather station even farther away", generic_asset_type=weather_station_type, latitude=temp_sensor_location[0], longitude=temp_sensor_location[1] + 0.2, ) db.session.add(even_farther_weather_station) even_farther_temp_sensor = Sensor( name="temperature", generic_asset=even_farther_weather_station, event_resolution=timedelta(minutes=5), unit="°C", ) db.session.add(even_farther_temp_sensor) add_weather_sensors["farther_temperature"] = farther_temp_sensor add_weather_sensors["even_farther_temperature"] = even_farther_temp_sensor return add_weather_sensors
def add_gas_sensor(db, test_supplier_user): incineration_type = GenericAssetType(name="waste incinerator", ) db.session.add(incineration_type) db.session.flush() incineration_asset = GenericAsset( name="incineration line", generic_asset_type=incineration_type, account_id=test_supplier_user.account_id, ) db.session.add(incineration_asset) db.session.flush() gas_sensor = Sensor( name="some gas sensor", unit="m³/h", event_resolution=timedelta(minutes=10), generic_asset=incineration_asset, ) db.session.add(gas_sensor) gas_sensor.owner = test_supplier_user.account