예제 #1
0
class GenericAssetTypeSchema(ma.SQLAlchemySchema):
    """
    GenericAssetType schema, with validations.
    """

    id = ma.auto_field()
    name = fields.Str()
    description = ma.auto_field()

    class Meta:
        model = GenericAssetType
예제 #2
0
class SensorSchemaMixin(Schema):
    """
    Base sensor schema.

    Here we include all fields which are implemented by timely_beliefs.SensorDBMixin
    All classes inheriting from timely beliefs sensor don't need to repeat these.
    In a while, this schema can represent our unified Sensor class.

    When subclassing, also subclass from `ma.SQLAlchemySchema` and add your own DB model class, e.g.:

        class Meta:
            model = Asset
    """

    name = ma.auto_field(required=True)
    unit = ma.auto_field(required=True)
    timezone = ma.auto_field()
    event_resolution = fields.TimeDelta(required=True, precision="minutes")
    entity_address = fields.String(dump_only=True)

    @validates("unit")
    def validate_unit(self, unit: str):
        if not is_valid_unit(unit):
            raise ValidationError(f"Unit '{unit}' cannot be handled.")
예제 #3
0
class UserSchema(ma.SQLAlchemySchema):
    """
    This schema lists fields we support through this API (e.g. no password).
    """
    class Meta:
        model = UserModel

    @validates("timezone")
    def validate_timezone(self, timezone):
        if timezone not in all_timezones:
            raise ValidationError(f"Timezone {timezone} doesn't exist.")

    id = ma.auto_field(dump_only=True)
    email = ma.auto_field(required=True, validate=validate.Email)
    username = ma.auto_field(required=True)
    account_id = ma.auto_field(dump_only=True)
    active = ma.auto_field()
    timezone = ma.auto_field()
    flexmeasures_roles = ma.auto_field()
    last_login_at = AwareDateTimeField()
예제 #4
0
class GenericAssetSchema(ma.SQLAlchemySchema):
    """
    GenericAsset schema, with validations.
    """

    id = ma.auto_field(dump_only=True)
    name = fields.Str(required=True)
    account_id = ma.auto_field()
    latitude = ma.auto_field()
    longitude = ma.auto_field()
    generic_asset_type_id = fields.Integer(required=True)

    class Meta:
        model = GenericAsset

    @validates_schema(skip_on_field_errors=False)
    def validate_name_is_unique_in_account(self, data, **kwargs):
        if "name" in data and "account_id" in data:
            asset = GenericAsset.query.filter(
                GenericAsset.name == data["name"]
                and GenericAsset.account_id == data["account_id"]
            ).one_or_none()
            if asset:
                raise ValidationError(
                    f"An asset with the name {data['name']} already exists in this account.",
                    "name",
                )

    @validates("generic_asset_type_id")
    def validate_generic_asset_type(self, generic_asset_type_id: int):
        generic_asset_type = GenericAssetType.query.get(generic_asset_type_id)
        if not generic_asset_type:
            raise ValidationError(
                f"GenericAssetType with id {generic_asset_type_id} doesn't exist."
            )

    @validates("account_id")
    def validate_account(self, account_id: int):
        account = Account.query.get(account_id)
        if not account:
            raise ValidationError(f"Account with Id {account_id} doesn't exist.")

    @validates("latitude")
    def validate_latitude(self, latitude: Optional[float]):
        """Validate optional latitude."""
        if latitude is None:
            return
        if latitude < -90:
            raise ValidationError(
                f"Latitude {latitude} exceeds the minimum latitude of -90 degrees."
            )
        if latitude > 90:
            raise ValidationError(
                f"Latitude {latitude} exceeds the maximum latitude of 90 degrees."
            )

    @validates("longitude")
    def validate_longitude(self, longitude: Optional[float]):
        """Validate optional longitude."""
        if longitude is None:
            return
        if longitude < -180:
            raise ValidationError(
                f"Longitude {longitude} exceeds the minimum longitude of -180 degrees."
            )
        if longitude > 180:
            raise ValidationError(
                f"Longitude {longitude} exceeds the maximum longitude of 180 degrees."
            )
예제 #5
0
class AssetSchema(SensorSchemaMixin, ma.SQLAlchemySchema):
    """
    Asset schema, with validations.

    TODO: deprecate, as it is based on legacy data model. Move some attributes to SensorSchema.
    """

    class Meta:
        model = Asset

    @validates("name")
    def validate_name(self, name: str):
        asset = Asset.query.filter(Asset.name == name).one_or_none()
        if asset:
            raise ValidationError(f"An asset with the name {name} already exists.")

    @validates("owner_id")
    def validate_owner(self, owner_id: int):
        owner = User.query.get(owner_id)
        if not owner:
            raise ValidationError(f"Owner with id {owner_id} doesn't exist.")
        if not owner.account.has_role("Prosumer"):
            raise ValidationError(
                "Asset owner's account must have role 'Prosumer'."
                f" User {owner_id}'s account has roles: {'.'.join([r.name for r in owner.account.account_roles])}."
            )

    @validates("market_id")
    def validate_market(self, market_id: int):
        sensor = Sensor.query.get(market_id)
        if not sensor:
            raise ValidationError(f"Market with id {market_id} doesn't exist.")

    @validates("asset_type_name")
    def validate_asset_type(self, asset_type_name: str):
        asset_type = AssetType.query.get(asset_type_name)
        if not asset_type:
            raise ValidationError(f"Asset type {asset_type_name} doesn't exist.")

    @validates_schema(skip_on_field_errors=False)
    def validate_soc_constraints(self, data, **kwargs):
        if "max_soc_in_mwh" in data and "min_soc_in_mwh" in data:
            if data["max_soc_in_mwh"] < data["min_soc_in_mwh"]:
                errors = {
                    "max_soc_in_mwh": "This value must be equal or higher than the minimum soc."
                }
                raise ValidationError(errors)

    id = ma.auto_field()
    display_name = fields.Str(validate=validate.Length(min=4))
    capacity_in_mw = fields.Float(required=True, validate=validate.Range(min=0.0001))
    min_soc_in_mwh = fields.Float(validate=validate.Range(min=0))
    max_soc_in_mwh = fields.Float(validate=validate.Range(min=0))
    soc_in_mwh = ma.auto_field()
    soc_datetime = ma.auto_field()
    soc_udi_event_id = ma.auto_field()
    latitude = fields.Float(required=True, validate=validate.Range(min=-90, max=90))
    longitude = fields.Float(required=True, validate=validate.Range(min=-180, max=180))
    asset_type_name = ma.auto_field(required=True)
    owner_id = ma.auto_field(required=True)
    market_id = ma.auto_field(required=True)