sensors.py 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. from __future__ import annotations
  2. from sqlalchemy import select, Select
  3. from flexmeasures.data.models.generic_assets import GenericAsset, GenericAssetType
  4. from flexmeasures.data.queries.utils import potentially_limit_assets_query_to_account
  5. def query_sensor_by_name_and_generic_asset_type_name(
  6. sensor_name: str | None = None,
  7. generic_asset_type_names: list[str] | None = None,
  8. account_id: int | None = None,
  9. ) -> Select:
  10. """Match a sensor by its own name and that of its generic asset type.
  11. :param sensor_name: should match (if None, no match is needed)
  12. :param generic_asset_type_names: should match at least one of these (if None, no match is needed)
  13. :param account_id: Pass in an account ID if you want to query an account other than your own. This only works for admins. Public assets are always queried.
  14. """
  15. from flexmeasures.data.models.time_series import Sensor
  16. query = select(Sensor)
  17. if sensor_name is not None:
  18. query = query.filter(Sensor.name == sensor_name)
  19. if generic_asset_type_names is not None:
  20. query = (
  21. query.join(GenericAsset)
  22. .join(GenericAssetType)
  23. .filter(GenericAssetType.name.in_(generic_asset_type_names))
  24. .filter(GenericAsset.generic_asset_type_id == GenericAssetType.id)
  25. .filter(Sensor.generic_asset_id == GenericAsset.id)
  26. )
  27. query = potentially_limit_assets_query_to_account(query, account_id)
  28. return query
  29. def query_sensors_by_proximity(
  30. latitude: float,
  31. longitude: float,
  32. generic_asset_type_name: str | None,
  33. sensor_name: str | None,
  34. account_id: int | None = None,
  35. ) -> Select:
  36. """Order them by proximity of their asset's location to the target."""
  37. from flexmeasures.data.models.time_series import Sensor
  38. closest_sensor_query = (
  39. select(Sensor)
  40. .join(GenericAsset, Sensor.generic_asset_id == GenericAsset.id)
  41. .filter(Sensor.generic_asset_id == GenericAsset.id)
  42. )
  43. if generic_asset_type_name:
  44. closest_sensor_query = closest_sensor_query.join(GenericAssetType)
  45. closest_sensor_query = closest_sensor_query.filter(
  46. Sensor.generic_asset_id == GenericAsset.id,
  47. GenericAsset.generic_asset_type_id == GenericAssetType.id,
  48. GenericAssetType.name == generic_asset_type_name,
  49. )
  50. if sensor_name is not None:
  51. closest_sensor_query = closest_sensor_query.filter(Sensor.name == sensor_name)
  52. closest_sensor_query = closest_sensor_query.order_by(
  53. GenericAsset.great_circle_distance(lat=latitude, lng=longitude).asc()
  54. )
  55. closest_sensor_query = potentially_limit_assets_query_to_account(
  56. closest_sensor_query, account_id
  57. )
  58. return closest_sensor_query