2
2
# Copyright (C) 2024 RapidSilicon
3
3
# Authorized use only
4
4
#
5
- from flask import Blueprint
5
+ from flask import Blueprint , request
6
6
from flask_restful import Api , Resource
7
- from marshmallow import Schema , fields
7
+ from marshmallow import Schema , fields , ValidationError
8
8
from submodule .rs_device_manager import RsDeviceManager
9
9
from submodule .rs_device_resources import DeviceNotFoundException
10
10
from submodule .rs_message import RsMessageType
11
- from .errors import DeviceNotExistsError , InternalServerError
11
+ from .errors import DeviceNotExistsError , InternalServerError , SchemaValidationError
12
12
from .errors import errors
13
13
14
14
#---------------------------------------------------------------------------#
15
15
# endpoints | methods | classes #
16
16
#---------------------------------------------------------------------------#
17
17
# devices | get | DevicesApi #
18
- # devices/<device_id> | get | DeviceApi #
18
+ # devices/<device_id> | get, patch | DeviceApi #
19
19
# devices/<device_id>/consumption | get | DeviceConsumptionApi #
20
20
#---------------------------------------------------------------------------#
21
21
22
22
class MessageSchema (Schema ):
23
23
type = fields .Enum (RsMessageType , by_value = True )
24
24
text = fields .Str ()
25
25
26
+ class AmbientSchema (Schema ):
27
+ typical = fields .Number ()
28
+ worsecase = fields .Number ()
29
+
30
+ class ThermalSpecSchema (Schema ):
31
+ theta_ja = fields .Number ()
32
+ ambient = fields .Nested (AmbientSchema )
33
+
34
+ class TypicalDynamicScalingSchema (Schema ):
35
+ fpga_complex = fields .Number ()
36
+ processing_complex = fields .Number ()
37
+
38
+ class PowerSpecSchema (Schema ):
39
+ budget = fields .Number ()
40
+ typical_dynamic_scaling = fields .Nested (TypicalDynamicScalingSchema )
41
+
42
+ class SpecificationSchema (Schema ):
43
+ thermal = fields .Nested (ThermalSpecSchema )
44
+ power = fields .Nested (PowerSpecSchema )
45
+
26
46
class DeviceSchema (Schema ):
27
47
id = fields .Str ()
28
48
series = fields .Str ()
29
49
logic_density = fields .Str ()
30
50
package = fields .Str ()
31
51
speedgrade = fields .Str ()
32
52
temperature_grade = fields .Str ()
53
+ specification = fields .Nested (SpecificationSchema )
33
54
34
- class DevicePowerThermalSchema (Schema ):
35
- total_power = fields .Number ()
36
- thermal = fields .Number ()
55
+ class DeviceTotalPowerTemperatureSchema (Schema ):
56
+ type = fields .Str ()
57
+ power = fields .Number ()
58
+ temperature = fields .Number ()
59
+
60
+ class DeviceComponentSchema (Schema ):
61
+ type = fields .Str ()
62
+ power = fields .Number ()
63
+ percentage = fields .Number ()
64
+
65
+ class DeviceDynamicSchema (Schema ):
66
+ components = fields .Nested (DeviceComponentSchema , many = True )
67
+ power = fields .Number ()
68
+ percentage = fields .Number ()
69
+
70
+ class DeviceStaticSchema (Schema ):
71
+ power = fields .Number ()
72
+ percentage = fields .Number ()
73
+
74
+ class DeviceComplexSchema (Schema ):
75
+ dynamic = fields .Nested (DeviceDynamicSchema )
76
+ static = fields .Nested (DeviceStaticSchema )
77
+ total_power = fields .Number (default = 0.0 )
78
+ total_percentage = fields .Number (default = 0.0 )
37
79
38
80
class DeviceConsumptionSchema (Schema ):
39
- worsecase = fields .Nested (DevicePowerThermalSchema )
40
- typical = fields .Nested (DevicePowerThermalSchema )
81
+ total_power_temperature = fields .Nested (DeviceTotalPowerTemperatureSchema , many = True )
82
+ processing_complex = fields .Nested (DeviceComplexSchema )
83
+ fpga_complex = fields .Nested (DeviceComplexSchema )
41
84
42
85
class DevicesApi (Resource ):
43
86
def get (self ):
@@ -89,20 +132,102 @@ def get(self):
89
132
type: string
90
133
temperature_grade:
91
134
type: string
92
- DevicePowerThermal:
135
+ DeviceTotalPowerTemperature:
136
+ type: object
137
+ properties:
138
+ type:
139
+ type: string
140
+ power:
141
+ type: number
142
+ temperature:
143
+ type: number
144
+ DeviceComponent:
145
+ type: object
146
+ properties:
147
+ type:
148
+ type: string
149
+ power:
150
+ type: number
151
+ percentage:
152
+ type: number
153
+ DeviceDynamic:
154
+ type: object
155
+ properties:
156
+ components:
157
+ type: array
158
+ items:
159
+ $ref: '#/definitions/DeviceComponent'
160
+ power:
161
+ type: number
162
+ percentage:
163
+ type: number
164
+ DeviceStatic:
93
165
type: object
94
166
properties:
167
+ power:
168
+ type: number
169
+ percentage:
170
+ type: number
171
+ DeviceComplex:
172
+ type: object
173
+ properties:
174
+ dynamic:
175
+ $ref: '#/definitions/DeviceDynamic'
176
+ static:
177
+ $ref: '#/definitions/DeviceStatic'
95
178
total_power:
96
179
type: number
97
- thermal :
180
+ total_percentage :
98
181
type: number
99
182
DeviceConsumption:
100
183
type: object
101
184
properties:
102
- worsecase:
103
- $ref: '#/definitions/DevicePowerThermal'
185
+ total_power_temperature:
186
+ type: array
187
+ items:
188
+ $ref: '#/definitions/DeviceTotalPowerTemperature'
189
+ processing_complex:
190
+ $ref: '#/definitions/DeviceComplex'
191
+ fpga_complex:
192
+ $ref: '#/definitions/DeviceComplex'
193
+ Ambient:
194
+ type: object
195
+ properties:
104
196
typical:
105
- $ref: '#/definitions/DevicePowerThermal'
197
+ type: number
198
+ worsecase:
199
+ type: number
200
+ TypicalDynamicScaling:
201
+ type: object
202
+ properties:
203
+ fpga_complex:
204
+ type: number
205
+ processing_complex:
206
+ type: number
207
+ Thermal:
208
+ type: object
209
+ properties:
210
+ theta_ja:
211
+ type: number
212
+ ambient:
213
+ $ref: '#/definitions/Ambient'
214
+ Power:
215
+ type: object
216
+ properties:
217
+ budget:
218
+ type: number
219
+ typical_dynamic_scaling:
220
+ $ref: '#/definitions/TypicalDynamicScaling'
221
+ Specification:
222
+ type: object
223
+ properties:
224
+ specification:
225
+ type: object
226
+ properties:
227
+ thermal:
228
+ $ref: '#/definitions/Thermal'
229
+ power:
230
+ $ref: '#/definitions/Power'
106
231
responses:
107
232
200:
108
233
description: Successfully returned a list of devices
@@ -135,7 +260,9 @@ def get(self, device_id : str):
135
260
200:
136
261
description: Successfully returned the details of a device
137
262
schema:
138
- $ref: '#/definitions/Device'
263
+ allOf:
264
+ - $ref: '#/definitions/Device'
265
+ - $ref: '#/definitions/Specification'
139
266
400:
140
267
description: Invalid request
141
268
schema:
@@ -151,6 +278,48 @@ def get(self, device_id : str):
151
278
except Exception as e :
152
279
raise InternalServerError
153
280
281
+ def patch (self , device_id : str ):
282
+ """
283
+ This is an endpoint that updates the power and thermal spec of a device
284
+ ---
285
+ tags:
286
+ - Device
287
+ description: Update the power and thermal spec of a device.
288
+ parameters:
289
+ - name: device_id
290
+ in: path
291
+ type: string
292
+ required: true
293
+ - name: spec
294
+ in: body
295
+ description: Update the power and thermal spec of a device
296
+ schema:
297
+ $ref: '#/definitions/Specification'
298
+ responses:
299
+ 200:
300
+ description: Successfully updated the power and thermal spec
301
+ schema:
302
+ allOf:
303
+ - $ref: '#/definitions/Device'
304
+ - $ref: '#/definitions/Specification'
305
+ 400:
306
+ description: Invalid request
307
+ schema:
308
+ $ref: '#/definitions/HTTPErrorMessage'
309
+ """
310
+ try :
311
+ device_mgr = RsDeviceManager .get_instance ()
312
+ device = device_mgr .get_device (device_id )
313
+ schema = DeviceSchema ()
314
+ device .update_spec (schema .load (request .json ))
315
+ return schema .dump (device ), 200
316
+ except ValidationError as e :
317
+ raise SchemaValidationError
318
+ except DeviceNotFoundException as e :
319
+ raise DeviceNotExistsError
320
+ except Exception as e :
321
+ raise InternalServerError
322
+
154
323
class DeviceConsumptionApi (Resource ):
155
324
def get (self , device_id : str ):
156
325
"""
0 commit comments