/
routes.py
187 lines (151 loc) · 5.66 KB
/
routes.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
from flask_security import auth_token_required
from flexmeasures.auth.decorators import account_roles_accepted
from flexmeasures.api.common.utils.api_utils import list_access
from flexmeasures.api.common.utils.decorators import as_response_type
from flexmeasures.api.v1 import (
flexmeasures_api as flexmeasures_api_v1,
implementations as v1_implementations,
)
# The service listing for this API version (import from previous version or update if needed)
v1_service_listing = {
"version": "1.0",
"services": [
{
"name": "getMeterData",
"access": ["Aggregator", "Supplier", "MDC", "DSO", "Prosumer", "ESCo"],
"description": "Request meter reading",
},
{
"name": "postMeterData",
"access": ["Aggregator", "Supplier", "MDC", "DSO", "Prosumer", "ESCo"],
"description": "Send meter reading",
},
],
}
@flexmeasures_api_v1.route("/getMeterData", methods=["GET", "POST"])
@as_response_type("GetMeterDataResponse")
@auth_token_required
@account_roles_accepted(*list_access(v1_service_listing, "getMeterData"))
def get_meter_data():
"""API endpoint to get meter data.
.. :quickref: Data; Download meter data from the platform
**Optional fields**
- "resolution" (see :ref:`frequency_and_resolution`)
- "horizon" (see :ref:`beliefs`)
- "prior" (see :ref:`beliefs`)
- "source" (see :ref:`sources`)
**Example request**
This "GetMeterDataRequest" message requests measured consumption between 0.00am and 1.30am for charging station 1.
.. code-block:: json
{
"type": "GetMeterDataRequest",
"connection": "CS 1",
"start": "2015-01-01T00:00:00Z",
"duration": "PT1H30M",
"unit": "MW"
}
**Example response**
This "GetMeterDataResponse" message indicates that consumption for charging station 1 was measured in 15-minute
intervals.
.. sourcecode:: json
{
"type": "GetMeterDataResponse",
"connection": "CS 1",
"values": [
306.66,
306.66,
0,
0,
306.66,
306.66
],
"start": "2015-01-01T00:00:00Z",
"duration": "PT1H30M",
"unit": "MW"
}
:reqheader Authorization: The authentication token
:reqheader Content-Type: application/json
:resheader Content-Type: application/json
:status 200: PROCESSED
:status 400: INVALID_DOMAIN, INVALID_MESSAGE_TYPE, INVALID_SOURCE, INVALID_TIMEZONE, INVALID_UNIT, UNRECOGNIZED_ASSET, or UNRECOGNIZED_CONNECTION_GROUP
:status 401: UNAUTHORIZED
:status 403: INVALID_SENDER
:status 405: INVALID_METHOD
"""
return v1_implementations.get_meter_data_response()
@flexmeasures_api_v1.route("/postMeterData", methods=["POST"])
@as_response_type("PostMeterDataResponse")
@auth_token_required
@account_roles_accepted(*list_access(v1_service_listing, "postMeterData"))
def post_meter_data():
"""API endpoint to post meter data.
.. :quickref: Data; Upload meter data to the platform
**Optional fields**
- "horizon" (see :ref:`prognoses`)
**Example request**
This "PostMeterDataRequest" message posts measured consumption for 15-minute intervals between 0.00am and 1.30am for
charging stations 1, 2 and 3 (negative values denote production).
.. code-block:: json
{
"type": "PostMeterDataRequest",
"groups": [
{
"connections": [
"CS 1",
"CS 3"
],
"values": [
306.66,
306.66,
0,
0,
306.66,
306.66
]
},
{
"connections": [
"CS 2"
],
"values": [
306.66,
0,
0,
0,
306.66,
306.66
]
}
],
"start": "2015-01-01T00:00:00Z",
"duration": "PT1H30M",
"unit": "MW"
}
It is allowed to send higher resolutions (in this example for instance, 30 minutes) which will be upsampled.
**Example response**
This "PostMeterDataResponse" message indicates that the measurement has been processed without any error.
.. sourcecode:: json
{
"type": "PostMeterDataResponse",
"status": "PROCESSED",
"message": "Request has been processed."
}
:reqheader Authorization: The authentication token
:reqheader Content-Type: application/json
:resheader Content-Type: application/json
:status 200: PROCESSED
:status 400: INVALID_DOMAIN, INVALID_MESSAGE_TYPE, INVALID_TIMEZONE, INVALID_UNIT, REQUIRED_INFO_MISSING, UNRECOGNIZED_ASSET or UNRECOGNIZED_CONNECTION_GROUP
:status 401: UNAUTHORIZED
:status 403: INVALID_SENDER
:status 405: INVALID_METHOD
"""
return v1_implementations.post_meter_data_response()
@flexmeasures_api_v1.route("/getService", methods=["GET"])
@as_response_type("GetServiceResponse")
def get_service():
"""API endpoint to get a service listing for this version.
.. :quickref: Public; Obtain a service listing for this version
:resheader Content-Type: application/json
:status 200: PROCESSED
"""
return v1_implementations.get_service_response(v1_service_listing)