conftest.py 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. import pytest
  2. from datetime import datetime, timedelta
  3. from pytz import utc
  4. import pandas as pd
  5. from flexmeasures.data.models.planning.utils import initialize_index
  6. from flexmeasures.data.models.generic_assets import GenericAsset, GenericAssetType
  7. from flexmeasures.data.models.data_sources import DataSource
  8. from flexmeasures.data.models.time_series import Sensor, TimedBelief
  9. @pytest.fixture(scope="module")
  10. def generic_report(db, app):
  11. report_asset_type = GenericAssetType(name="ReportAssetType")
  12. db.session.add(report_asset_type)
  13. generic_report = GenericAsset(
  14. name="GenericReport", generic_asset_type=report_asset_type
  15. )
  16. db.session.add(generic_report)
  17. return generic_report
  18. @pytest.fixture(scope="module")
  19. def profit_report(db, app, generic_report, add_market_prices, setup_sources):
  20. device_type = GenericAssetType(name="Device")
  21. db.session.add(device_type)
  22. electricity_device = GenericAsset(
  23. name="Electricity Consuming Device", generic_asset_type=device_type
  24. )
  25. db.session.add(electricity_device)
  26. power_sensor = Sensor(
  27. "power",
  28. generic_asset=electricity_device,
  29. event_resolution=timedelta(minutes=15),
  30. unit="MW",
  31. timezone="Europe/Amsterdam",
  32. )
  33. energy_sensor = Sensor(
  34. "energy",
  35. generic_asset=electricity_device,
  36. event_resolution=timedelta(minutes=15),
  37. unit="MWh",
  38. timezone="Europe/Amsterdam",
  39. )
  40. profit_sensor_hourly = Sensor(
  41. "profit hourly",
  42. generic_asset=generic_report,
  43. event_resolution=timedelta(hours=1),
  44. unit="EUR",
  45. timezone="Europe/Amsterdam",
  46. )
  47. profit_sensor_daily = Sensor(
  48. "profit daily",
  49. generic_asset=generic_report,
  50. event_resolution=timedelta(hours=24),
  51. unit="EUR",
  52. timezone="Europe/Amsterdam",
  53. )
  54. db.session.add_all(
  55. [profit_sensor_hourly, profit_sensor_daily, energy_sensor, power_sensor]
  56. )
  57. time_slots = initialize_index(
  58. start=pd.Timestamp("2015-01-03").tz_localize("Europe/Amsterdam"),
  59. end=pd.Timestamp("2015-01-04").tz_localize("Europe/Amsterdam"),
  60. resolution="15min",
  61. )
  62. def save_values(sensor, values):
  63. beliefs = [
  64. TimedBelief(
  65. event_start=dt,
  66. belief_horizon=timedelta(hours=0),
  67. event_value=val,
  68. source=setup_sources["Seita"],
  69. sensor=sensor,
  70. )
  71. for dt, val in zip(time_slots, values)
  72. ]
  73. db.session.add_all(beliefs)
  74. # periodic pattern of producing 100kW for 4h and consuming 100kW for 4h:
  75. # i.e. [0.1 0.1 0.1 0.1 ... -0.1 -0.1 -0.1 -0.1]
  76. save_values(power_sensor, ([0.1] * 16 + [-0.1] * 16) * 3)
  77. # creating the same pattern as above but with energy
  78. # a flat consumption / production rate of 100kW is equivalent to consume / produce 25kWh
  79. # every 15min block for 1h
  80. save_values(energy_sensor, ([0.025] * 16 + [-0.025] * 16) * 3)
  81. db.session.commit()
  82. yield profit_sensor_hourly, profit_sensor_daily, power_sensor, energy_sensor
  83. @pytest.fixture(scope="module")
  84. def setup_dummy_data(db, app, generic_report):
  85. """
  86. Create 2 Sensors, 1 Asset and 1 AssetType
  87. """
  88. dummy_asset_type = GenericAssetType(name="DummyGenericAssetType")
  89. db.session.add(dummy_asset_type)
  90. dummy_asset = GenericAsset(
  91. name="DummyGenericAsset", generic_asset_type=dummy_asset_type
  92. )
  93. db.session.add(dummy_asset)
  94. sensor1 = Sensor(
  95. "sensor 1",
  96. generic_asset=dummy_asset,
  97. event_resolution=timedelta(hours=1),
  98. unit="kW",
  99. )
  100. db.session.add(sensor1)
  101. sensor2 = Sensor(
  102. "sensor 2", generic_asset=dummy_asset, event_resolution=timedelta(hours=1)
  103. )
  104. db.session.add(sensor2)
  105. sensor3 = Sensor(
  106. "sensor 3",
  107. generic_asset=dummy_asset,
  108. event_resolution=timedelta(hours=1),
  109. timezone="Europe/Amsterdam",
  110. )
  111. db.session.add(sensor3)
  112. sensor4 = Sensor(
  113. "sensor 4",
  114. generic_asset=dummy_asset,
  115. event_resolution=timedelta(minutes=15),
  116. timezone="Europe/Amsterdam",
  117. unit="kW",
  118. )
  119. db.session.add(sensor4)
  120. report_sensor = Sensor(
  121. "report sensor",
  122. generic_asset=generic_report,
  123. event_resolution=timedelta(hours=1),
  124. )
  125. db.session.add(report_sensor)
  126. daily_report_sensor = Sensor(
  127. "daily report sensor",
  128. generic_asset=generic_report,
  129. event_resolution=timedelta(days=1),
  130. timezone="Europe/Amsterdam",
  131. )
  132. db.session.add(daily_report_sensor)
  133. """
  134. Create 3 DataSources
  135. """
  136. source1 = DataSource("source1", type="A")
  137. source2 = DataSource("source2", type="B")
  138. source2v02 = DataSource("source2", type="B", version="0.2")
  139. """
  140. Create TimedBeliefs
  141. """
  142. beliefs = []
  143. for sensor in [sensor1, sensor2]:
  144. for si, source in enumerate([source1, source2]):
  145. for t in range(10):
  146. beliefs.append(
  147. TimedBelief(
  148. event_start=datetime(2023, 4, 10, tzinfo=utc)
  149. + timedelta(hours=t + si),
  150. belief_horizon=timedelta(hours=24),
  151. event_value=t,
  152. sensor=sensor,
  153. source=source,
  154. )
  155. )
  156. # add simple data for testing the AggregatorReporter:
  157. # 24 hourly events with value 1 for sensor1 and value -1 for sensor2
  158. for sensor, source, value in zip([sensor1, sensor2], [source1, source2], [1, -1]):
  159. for t in range(24):
  160. beliefs.append(
  161. TimedBelief(
  162. event_start=datetime(2023, 5, 10, tzinfo=utc) + timedelta(hours=t),
  163. belief_horizon=timedelta(hours=24),
  164. event_value=value,
  165. sensor=sensor,
  166. source=source,
  167. )
  168. )
  169. # add simple data for testing DST transition
  170. for t in range(24 * 4): # create data for 4 days
  171. # UTC+1 -> UTC+2
  172. beliefs.append(
  173. TimedBelief(
  174. event_start=datetime(2023, 3, 24, tzinfo=utc) + timedelta(hours=t),
  175. belief_horizon=timedelta(hours=24),
  176. event_value=t,
  177. sensor=sensor3,
  178. source=source1,
  179. )
  180. )
  181. # UTC+2 -> UTC+1
  182. beliefs.append(
  183. TimedBelief(
  184. event_start=datetime(2023, 10, 27, tzinfo=utc) + timedelta(hours=t),
  185. belief_horizon=timedelta(hours=24),
  186. event_value=t,
  187. sensor=sensor3,
  188. source=source1,
  189. )
  190. )
  191. # Add data source transition, from DataSource 1 to DataSource 2
  192. # At 12:00, there is one event from both of the sources
  193. for t in range(12): # create data for 4 days
  194. # 00:00 -> 12:00
  195. beliefs.append(
  196. TimedBelief(
  197. event_start=datetime(2023, 4, 24, tzinfo=utc) + timedelta(hours=t),
  198. belief_horizon=timedelta(hours=24),
  199. event_value=1,
  200. sensor=sensor3,
  201. source=source1,
  202. )
  203. )
  204. # 12:00 -> 24:00
  205. beliefs.append(
  206. TimedBelief(
  207. event_start=datetime(2023, 4, 24, tzinfo=utc) + timedelta(hours=t + 12),
  208. belief_horizon=timedelta(hours=24),
  209. event_value=-1,
  210. sensor=sensor3,
  211. source=source2,
  212. )
  213. )
  214. # add a belief belonging to Source 1 in the second half of the day
  215. beliefs.append(
  216. TimedBelief(
  217. event_start=datetime(2023, 4, 24, tzinfo=utc) + timedelta(hours=12),
  218. belief_horizon=timedelta(hours=24),
  219. event_value=1,
  220. sensor=sensor3,
  221. source=source1,
  222. )
  223. )
  224. # add a belief belonging to version 0.2 of Source 2 around the end of the day, recorded 25 instead of 24 hours in advance
  225. beliefs.append(
  226. TimedBelief(
  227. event_start=datetime(2023, 4, 24, tzinfo=utc) + timedelta(hours=23),
  228. belief_horizon=timedelta(hours=25),
  229. event_value=3,
  230. sensor=sensor3,
  231. source=source2v02,
  232. )
  233. )
  234. # add data for sensor 4
  235. for t in range(24 * 3):
  236. beliefs.append(
  237. TimedBelief(
  238. event_start=datetime(2023, 1, 1, tzinfo=utc) + timedelta(hours=t),
  239. belief_horizon=timedelta(hours=24),
  240. event_value=1,
  241. sensor=sensor4,
  242. source=source1,
  243. )
  244. )
  245. db.session.add_all(beliefs)
  246. db.session.commit()
  247. yield sensor1, sensor2, sensor3, sensor4, report_sensor, daily_report_sensor