pydae 0.56.4__py3-none-any.whl → 0.57__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pydae/__init__.py +1 -1
- pydae/bmapu/bmapu_builder.py +681 -681
- pydae/bmapu/bmapu_builder_line_exp.py +564 -0
- pydae/bmapu/lines/lib_dtr.py +425 -0
- pydae/bmapu/lines/lines.py +237 -1
- pydae/bmapu/lines/temp.py +1823 -0
- pydae/bmapu/lines/temp_ini_cffi.c +1280 -0
- pydae/bmapu/lines/temp_run_cffi.c +1280 -0
- pydae/bmapu/lines/temp_trap_cffi.c +971 -0
- pydae/bmapu/lines/temp_xy_0.json +7 -0
- pydae/bmapu/lines/xy_0.json +7 -0
- pydae/bmapu/pvs/pv_string.py +647 -0
- pydae/build_cffi.py +1 -1
- pydae/build_v2.py +29 -18
- pydae/models/pendulum/api_test.http +106 -0
- pydae/models/pendulum/dae_api.py +107 -0
- pydae/models/pendulum/dashboard.py +211 -0
- pydae/models/pendulum/temp.py +1882 -0
- pydae/models/pendulum/temp_ini_cffi.c +1247 -0
- pydae/models/pendulum/temp_run_cffi.c +1247 -0
- pydae/models/pendulum/temp_trap_cffi.c +950 -0
- pydae/svg_tools/bmapu_tooltips.ipynb +119 -0
- pydae/svg_tools/svg_tools.py +11 -4
- pydae/temp.py +1 -1
- pydae/temp_ini_cffi.c +4 -0
- pydae/temp_run_cffi.c +4 -0
- pydae/temp_trap_cffi.c +4 -0
- pydae/templates/class_dae_template_api.py +1857 -0
- pydae/utils/dates.py +233 -0
- {pydae-0.56.4.dist-info → pydae-0.57.dist-info}/METADATA +4 -2
- {pydae-0.56.4.dist-info → pydae-0.57.dist-info}/RECORD +34 -15
- {pydae-0.56.4.dist-info → pydae-0.57.dist-info}/WHEEL +1 -1
- {pydae-0.56.4.dist-info → pydae-0.57.dist-info/licenses}/COPYING +0 -0
- {pydae-0.56.4.dist-info → pydae-0.57.dist-info/licenses}/LICENSE +0 -0
pydae/build_v2.py
CHANGED
|
@@ -30,7 +30,7 @@ from cffi import FFI
|
|
|
30
30
|
|
|
31
31
|
class builder():
|
|
32
32
|
|
|
33
|
-
def __init__(self,sys,verbose=False):
|
|
33
|
+
def __init__(self,sys,verbose=False,API=False):
|
|
34
34
|
|
|
35
35
|
logging.basicConfig(format='%(asctime)s %(message)s', level=logging.INFO)
|
|
36
36
|
|
|
@@ -40,11 +40,12 @@ class builder():
|
|
|
40
40
|
self.name = self.sys['name']
|
|
41
41
|
self.save_sources = False
|
|
42
42
|
self.string_u2z = ''
|
|
43
|
-
self.u2z = '
|
|
43
|
+
self.u2z = r'#'
|
|
44
44
|
self.inirun = True
|
|
45
45
|
self.sparse = False
|
|
46
46
|
self.mkl = False
|
|
47
47
|
self.platform = 'Windows'
|
|
48
|
+
self.API = API
|
|
48
49
|
|
|
49
50
|
|
|
50
51
|
if not os.path.exists('build'):
|
|
@@ -118,7 +119,8 @@ class builder():
|
|
|
118
119
|
x = sym.Matrix(sys['x_list']).T
|
|
119
120
|
y_ini = sym.Matrix(sys['y_ini_list']).T
|
|
120
121
|
y_run = sym.Matrix(sys['y_run_list']).T
|
|
121
|
-
|
|
122
|
+
u_ini_list = [sym.Symbol(item,real=True) for item in list(sys['u_ini_dict'].keys())]
|
|
123
|
+
u_ini = sym.Matrix(u_ini_list).T
|
|
122
124
|
u_run_list = [sym.Symbol(item,real=True) for item in list(sys['u_run_dict'].keys())]
|
|
123
125
|
u_run = sym.Matrix(u_run_list).T
|
|
124
126
|
h = sym.Matrix(list(sys['h_dict'].values())).T
|
|
@@ -802,7 +804,10 @@ class builder():
|
|
|
802
804
|
if self.mkl:
|
|
803
805
|
class_template = pkgutil.get_data(__name__, "templates/class_dae_template_v2_mkl.py").decode().replace('\r\n','\n')
|
|
804
806
|
else:
|
|
805
|
-
|
|
807
|
+
if self.API:
|
|
808
|
+
class_template = pkgutil.get_data(__name__, "templates/class_dae_template_api.py").decode().replace('\r\n','\n')
|
|
809
|
+
else:
|
|
810
|
+
class_template = pkgutil.get_data(__name__, "templates/class_dae_template_v2.py").decode().replace('\r\n','\n')
|
|
806
811
|
if self.uz_jacs:
|
|
807
812
|
uz_jacs_template = pkgutil.get_data(__name__, "templates/uz_jacs_v2.py").decode().replace('\r\n','\n')
|
|
808
813
|
class_template += uz_jacs_template
|
|
@@ -1341,9 +1346,11 @@ def sym2xyup_mp(sys,full_list,inirun):
|
|
|
1341
1346
|
logging.debug('end full_list update with xyup and tipo')
|
|
1342
1347
|
|
|
1343
1348
|
|
|
1344
|
-
def build_numba(sys_dict,verbose=False):
|
|
1349
|
+
def build_numba(sys_dict,verbose=False, API=False):
|
|
1350
|
+
|
|
1351
|
+
from pydae.build_v2 import builder
|
|
1345
1352
|
|
|
1346
|
-
b = builder(sys_dict,verbose=
|
|
1353
|
+
b = builder(sys_dict,verbose=True,API=API)
|
|
1347
1354
|
b.sparse = False
|
|
1348
1355
|
b.mkl = False
|
|
1349
1356
|
b.uz_jacs = False
|
|
@@ -1354,6 +1361,8 @@ def build_numba(sys_dict,verbose=False):
|
|
|
1354
1361
|
b.template()
|
|
1355
1362
|
b.compile()
|
|
1356
1363
|
|
|
1364
|
+
|
|
1365
|
+
|
|
1357
1366
|
def build_mkl(sys_dict,verbose=False,platform='Windows'):
|
|
1358
1367
|
'''
|
|
1359
1368
|
|
|
@@ -1376,20 +1385,22 @@ def build_mkl(sys_dict,verbose=False,platform='Windows'):
|
|
|
1376
1385
|
def test_numba():
|
|
1377
1386
|
|
|
1378
1387
|
from pydae.models.pendulum.dae import dae
|
|
1379
|
-
from pydae.build_v2 import builder
|
|
1388
|
+
from pydae.build_v2 import builder,build_numba
|
|
1380
1389
|
|
|
1381
1390
|
sys_dict = dae('temp')
|
|
1382
1391
|
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
b
|
|
1386
|
-
b.
|
|
1387
|
-
b.
|
|
1388
|
-
b.
|
|
1389
|
-
b.
|
|
1390
|
-
b.
|
|
1391
|
-
b.
|
|
1392
|
-
b.
|
|
1392
|
+
build_numba(sys_dict,verbose=True)
|
|
1393
|
+
|
|
1394
|
+
# b = builder(sys_dict,verbose=True)
|
|
1395
|
+
# b.sparse = False
|
|
1396
|
+
# b.mkl = False
|
|
1397
|
+
# b.uz_jacs = False
|
|
1398
|
+
# b.dict2system()
|
|
1399
|
+
# b.functions()
|
|
1400
|
+
# b.jacobians()
|
|
1401
|
+
# b.cwrite()
|
|
1402
|
+
# b.template()
|
|
1403
|
+
# b.compile()
|
|
1393
1404
|
|
|
1394
1405
|
import temp
|
|
1395
1406
|
|
|
@@ -1471,4 +1482,4 @@ def test_mkl():
|
|
|
1471
1482
|
|
|
1472
1483
|
if __name__ == "__main__":
|
|
1473
1484
|
|
|
1474
|
-
|
|
1485
|
+
test_numba()
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
### GET measures. Devuelve todas las medidas del POI y de los inversores
|
|
2
|
+
GET http://127.100.0.1:8000/measurements
|
|
3
|
+
Content-Type: application/json
|
|
4
|
+
|
|
5
|
+
### GET measures. Devuelve todas las medidas del POI y de los inversores
|
|
6
|
+
GET http://10.20.0.2:5500/ppc_measurements
|
|
7
|
+
Content-Type: application/json
|
|
8
|
+
|
|
9
|
+
### GET measures. Devuelve todas las medidas del POI y de los inversores
|
|
10
|
+
GET http://10.20.0.4:5500/ppc_measurements
|
|
11
|
+
Content-Type: application/json
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### POST setpoints. POST request to change PPC references.
|
|
15
|
+
POST http://127.0.0.1:5500/ppc_setpoints
|
|
16
|
+
Content-Type: application/json
|
|
17
|
+
|
|
18
|
+
{
|
|
19
|
+
"p_ol_ref":0.0,
|
|
20
|
+
"q_ol_ref":0.0,
|
|
21
|
+
"p_s_ref_BESS":0.0
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
### POST false measurement liner transformations parameters .
|
|
27
|
+
POST http://127.100.0.1:8000/meas_pert
|
|
28
|
+
Content-Type: application/json
|
|
29
|
+
|
|
30
|
+
{
|
|
31
|
+
"U_SS1":{"m":0.5,"b":0}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
### POST setpoints. POST request to change active and reactive power references at POI.
|
|
37
|
+
POST http://10.20.0.2:8000/setpoints
|
|
38
|
+
Content-Type: application/json
|
|
39
|
+
|
|
40
|
+
{
|
|
41
|
+
"p_ol_ref":0.5,
|
|
42
|
+
"q_ol_ref":0.5,
|
|
43
|
+
"p_s_ref_BESS":0.0
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
### POST setpoints. POST request to change active and reactive power references at POI.
|
|
48
|
+
POST http://10.20.0.2:8000/setpoints
|
|
49
|
+
Content-Type: application/json
|
|
50
|
+
|
|
51
|
+
{
|
|
52
|
+
"p_s_ppc_LV0101":1.5e6,
|
|
53
|
+
"p_s_ppc_LV0102":01.5e6,
|
|
54
|
+
"p_s_ref_BESS":0.0
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
### POST setpoints. POST request to change PPC references.
|
|
61
|
+
POST http://127.0.0.1:5500/ppc_setpoints
|
|
62
|
+
Content-Type: application/json
|
|
63
|
+
|
|
64
|
+
{
|
|
65
|
+
"record":true
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
### POST setpoints. POST request to change PPC references.
|
|
71
|
+
POST http://127.0.0.1:5500/ppc_setpoints
|
|
72
|
+
Content-Type: application/json
|
|
73
|
+
|
|
74
|
+
{
|
|
75
|
+
"P_POI_ref":0.5,
|
|
76
|
+
"Q_POI_ref":-0.9
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
### POST setpoints. POST request to change PPC references.
|
|
80
|
+
POST http://127.0.0.1:5500/ppc_setpoints
|
|
81
|
+
Content-Type: application/json
|
|
82
|
+
|
|
83
|
+
{
|
|
84
|
+
"record":false
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
### POST setpoints. POST request to change PPC references.
|
|
89
|
+
POST http://127.0.0.1:5500/ppc_setpoints
|
|
90
|
+
Content-Type: application/json
|
|
91
|
+
|
|
92
|
+
{
|
|
93
|
+
"stop_ppc":true
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
### POST setpoints. POST request to change PPC references.
|
|
98
|
+
POST http://127.0.0.1:5500/ppc_params
|
|
99
|
+
Content-Type: application/json
|
|
100
|
+
|
|
101
|
+
{
|
|
102
|
+
"K_pp":0.5,
|
|
103
|
+
"K_pi":5.0,
|
|
104
|
+
"K_qp":0.5,
|
|
105
|
+
"K_qi":5.0
|
|
106
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import sympy as sym
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def dae(model_name):
|
|
6
|
+
L,G,M,K_d = sym.symbols('L,G,M,K_d', real=True)
|
|
7
|
+
p_x,p_y,v_x,v_y = sym.symbols('p_x,p_y,v_x,v_y', real=True)
|
|
8
|
+
lam,f_x,theta,u_dummy = sym.symbols('lam,f_x,theta,u_dummy', real=True)
|
|
9
|
+
|
|
10
|
+
dp_x = v_x
|
|
11
|
+
dp_y = v_y
|
|
12
|
+
dv_x = (-2*p_x*lam + f_x - K_d*v_x)/M
|
|
13
|
+
dv_y = (-M*G - 2*p_y*lam - K_d*v_y)/M
|
|
14
|
+
|
|
15
|
+
g_1 = p_x**2 + p_y**2 - L**2 -lam*1e-6
|
|
16
|
+
g_2 = -theta + sym.atan2(p_x,-p_y) + u_dummy
|
|
17
|
+
|
|
18
|
+
params_dict = {'L':5.21,'G':9.81,'M':10.0,'K_d':1e-3} # parameters with default values
|
|
19
|
+
|
|
20
|
+
u_ini_dict = {'theta':np.deg2rad(5.0),'u_dummy':0.0} # input for the initialization problem
|
|
21
|
+
u_run_dict = {'f_x':0,'u_dummy':0.0} # input for the running problem, its value is updated
|
|
22
|
+
|
|
23
|
+
sys_dict = {'name':model_name,
|
|
24
|
+
'params_dict':params_dict,
|
|
25
|
+
'f_list':[dp_x,dp_y,dv_x,dv_y],
|
|
26
|
+
'g_list':[g_1,g_2],
|
|
27
|
+
'x_list':[ p_x, p_y, v_x, v_y],
|
|
28
|
+
'y_ini_list':[lam,f_x],
|
|
29
|
+
'y_run_list':[lam,theta],
|
|
30
|
+
'u_ini_dict':u_ini_dict,
|
|
31
|
+
'u_run_dict':u_run_dict,
|
|
32
|
+
'h_dict':{'E_p':M*G*(p_y+L),'E_k':0.5*M*(v_x**2+v_y**2),
|
|
33
|
+
'theta':theta,'f_x':f_x,'lam':lam},
|
|
34
|
+
'xy_0':{'theta':sym.atan2(p_x,-p_y)}}
|
|
35
|
+
|
|
36
|
+
return sys_dict
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def test_build():
|
|
40
|
+
import pydae.build_v2 as db
|
|
41
|
+
sys_dict = dae('temp')
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
b = db.builder(sys_dict,verbose=True,API=True)
|
|
45
|
+
b.sparse = False
|
|
46
|
+
b.mkl = False
|
|
47
|
+
b.platform = 'Windows'
|
|
48
|
+
b.dict2system()
|
|
49
|
+
b.functions()
|
|
50
|
+
b.jacobians()
|
|
51
|
+
b.cwrite()
|
|
52
|
+
b.template()
|
|
53
|
+
b.compile()
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def test_ini():
|
|
57
|
+
|
|
58
|
+
import temp
|
|
59
|
+
|
|
60
|
+
model = temp.model()
|
|
61
|
+
|
|
62
|
+
M = 30.0 # mass of the bob (kg)
|
|
63
|
+
L = 5.21 # length of the pendulum (m)
|
|
64
|
+
model.ini({'M':M,'L':L, # parameters setting
|
|
65
|
+
'theta':np.deg2rad(0) # initial desired angle = 0º
|
|
66
|
+
},-1) # here -1 means that -1 is considered as initial gess for
|
|
67
|
+
# dynamic and algebraic states
|
|
68
|
+
|
|
69
|
+
model.report_x() # obtained dynamic states
|
|
70
|
+
model.report_y() # obtained algebraic states
|
|
71
|
+
model.report_z() # obtained outputs
|
|
72
|
+
model.report_u() # obtained algebraic states (theta is both state and output; f_x is both input and output)
|
|
73
|
+
model.report_params() # considered parameters
|
|
74
|
+
|
|
75
|
+
def test_api():
|
|
76
|
+
|
|
77
|
+
import temp
|
|
78
|
+
|
|
79
|
+
model = temp.model()
|
|
80
|
+
|
|
81
|
+
M = 30.0 # mass of the bob (kg)
|
|
82
|
+
L = 5.21 # length of the pendulum (m)
|
|
83
|
+
model.ini({'M':M,'L':L, # parameters setting
|
|
84
|
+
'theta':np.deg2rad(5) # initial desired angle = 0º
|
|
85
|
+
},-1) # here -1 means that -1 is considered as initial gess for
|
|
86
|
+
# dynamic and algebraic states
|
|
87
|
+
|
|
88
|
+
model.report_x() # obtained dynamic states
|
|
89
|
+
model.report_y() # obtained algebraic states
|
|
90
|
+
model.report_z() # obtained outputs
|
|
91
|
+
model.report_u() # obtained algebraic states (theta is both state and output; f_x is both input and output)
|
|
92
|
+
model.report_params() # considered parameters
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
# model.run(1.0,{})
|
|
96
|
+
model.run_api()
|
|
97
|
+
#model.step(0.000000001,{})
|
|
98
|
+
|
|
99
|
+
if __name__ == '__main__':
|
|
100
|
+
|
|
101
|
+
test_build()
|
|
102
|
+
test_ini()
|
|
103
|
+
test_api()
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import panel as pn
|
|
2
|
+
import datetime
|
|
3
|
+
import param
|
|
4
|
+
import asyncio
|
|
5
|
+
import re
|
|
6
|
+
from pydae.svg_tools import svg
|
|
7
|
+
import requests
|
|
8
|
+
import json
|
|
9
|
+
import time
|
|
10
|
+
import matplotlib.pyplot as plt
|
|
11
|
+
import numpy as np
|
|
12
|
+
pn.extension('katex','matplotlib')
|
|
13
|
+
|
|
14
|
+
t_0 = time.time()
|
|
15
|
+
plot_pane = pn.pane.Matplotlib(sizing_mode='stretch_width')
|
|
16
|
+
|
|
17
|
+
# A function to generate a new plot
|
|
18
|
+
|
|
19
|
+
# with open('cuerva_emec_db.svg', 'r') as fobj:
|
|
20
|
+
# svg_file_content = fobj.read()
|
|
21
|
+
|
|
22
|
+
# Generate the new SVG
|
|
23
|
+
#s = svg('cuerva_emec_db.svg')
|
|
24
|
+
# s.set_tspan('U_SS1', f"{meas_dict['V_SS1']:5.3f} pu")
|
|
25
|
+
# s.set_tspan('U_SS2', f"{meas_dict['V_SS2']:5.3f} pu")
|
|
26
|
+
# s.set_tspan('U_POI', f"{slider_val:5.3f} pu")
|
|
27
|
+
# s.set_title('GRID_title', f"V = {meas_dict['V_GRID']:5.3f} pu\nP = {meas_dict['p_line_POIHV_GRID'] / 1e6:5.3f} MW\nQ = {meas_dict['q_line_POIHV_GRID'] / 1e6:5.3f} Mvar")
|
|
28
|
+
# s.set_tspan('P_POI', f"{meas_dict['p_line_POI_POIHV'] / 1e6:5.1f} MW")
|
|
29
|
+
# s.set_tspan('Q_POI', f"{meas_dict['q_line_POI_POIHV'] / 1e6:5.1f} Mvar")
|
|
30
|
+
|
|
31
|
+
# html_code = """
|
|
32
|
+
# <div>
|
|
33
|
+
# <svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
|
|
34
|
+
# <circle id="interactive_circle" cx="100" cy="100" r="50" fill="skyblue">
|
|
35
|
+
# <title>This is a circle\nHola</title>
|
|
36
|
+
# </circle>
|
|
37
|
+
# <text id="time_label" x="50" y="50" font-family="Arial" font-size="24" text-anchor="middle" fill="#333">
|
|
38
|
+
# Time: 00:00:00
|
|
39
|
+
# </text>
|
|
40
|
+
# </svg>
|
|
41
|
+
# </div>
|
|
42
|
+
# """
|
|
43
|
+
|
|
44
|
+
N_t = 300
|
|
45
|
+
charts_data = {'Times':np.zeros(N_t),
|
|
46
|
+
'theta':np.zeros(N_t),
|
|
47
|
+
'f_x':np.zeros(N_t),
|
|
48
|
+
'k':0, 'N_t':N_t, 't_0':t_0
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
# html_code = f"""
|
|
52
|
+
# <div>
|
|
53
|
+
# {s.tostring()}
|
|
54
|
+
# </div>
|
|
55
|
+
# """
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
#svg_pane = pn.pane.HTML(html_code, width=200, height=200)
|
|
59
|
+
# panel.servable()
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
# Create other widgets
|
|
63
|
+
button1 = pn.widgets.Button(name='Set to Red', button_type='success')
|
|
64
|
+
button2 = pn.widgets.Button(name='Set to Green', button_type='primary')
|
|
65
|
+
slider1 = pn.widgets.IntSlider(name='Circle Radius', start=20, end=100, value=80)
|
|
66
|
+
color_picker = pn.widgets.ColorPicker(name='Circle Color', value='#FF0000')
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
sld_f_x_label = pn.pane.LaTeX(r'$\mathsf {f_{x}}$ (Nm):', width=80)
|
|
70
|
+
sld_f_x = pn.widgets.FloatSlider(start=-200.0, end=200.0, value=0.0, step=0.01)
|
|
71
|
+
|
|
72
|
+
# Crear pestañas con Panel
|
|
73
|
+
tabs_monitor = pn.Tabs(
|
|
74
|
+
# ('Plant', svg_pane),
|
|
75
|
+
('Charts', plot_pane)
|
|
76
|
+
)
|
|
77
|
+
tabs_ctrl = pn.Tabs(
|
|
78
|
+
('Enviroment', pn.Column(
|
|
79
|
+
sld_f_x_label,sld_f_x))
|
|
80
|
+
# ('POI', pn.widgets.Button(name='Set to 2', button_type='success')),
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
# # A reusable function to update the SVG (for buttons and sliders)
|
|
84
|
+
# def update_svg(event=None):
|
|
85
|
+
# current_svg = svg_pane.object
|
|
86
|
+
|
|
87
|
+
# new_radius = slider1.value
|
|
88
|
+
# new_color = color_picker.value
|
|
89
|
+
|
|
90
|
+
# if event and event.obj is button1:
|
|
91
|
+
# new_color = '#FF0000'
|
|
92
|
+
# elif event and event.obj is button2:
|
|
93
|
+
# new_color = '#00FF00'
|
|
94
|
+
|
|
95
|
+
# # Use regular expressions for more reliable attribute updates
|
|
96
|
+
# updated_svg = re.sub(
|
|
97
|
+
# r'(<circle id="interactive_circle".*?)\sfill=".*?"',
|
|
98
|
+
# r'\1 fill="{}"'.format(new_color),
|
|
99
|
+
# current_svg
|
|
100
|
+
# )
|
|
101
|
+
# updated_svg = re.sub(
|
|
102
|
+
# r'(<circle id="interactive_circle".*?)\sr=".*?"',
|
|
103
|
+
# r'\1 r="{}"'.format(new_radius),
|
|
104
|
+
# updated_svg
|
|
105
|
+
# )
|
|
106
|
+
|
|
107
|
+
# # s.set_tspan('U_SS1', f"{meas_dict['V_SS1']:5.3f} pu")
|
|
108
|
+
# # s.set_tspan('U_SS2', f"{meas_dict['V_SS2']:5.3f} pu")
|
|
109
|
+
# # s.set_tspan('U_POI', f"{slider_val:5.3f} pu")
|
|
110
|
+
# # s.set_title('GRID_title', f"V = {meas_dict['V_GRID']:5.3f} pu\nP = {meas_dict['p_line_POIHV_GRID'] / 1e6:5.3f} MW\nQ = {meas_dict['q_line_POIHV_GRID'] / 1e6:5.3f} Mvar")
|
|
111
|
+
# # s.set_tspan('P_POI', f"{meas_dict['p_line_POI_POIHV'] / 1e6:5.1f} MW")
|
|
112
|
+
# # s.set_tspan('Q_POI', f"{meas_dict['q_line_POI_POIHV'] / 1e6:5.1f} Mvar")
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
# svg_pane.object = updated_svg
|
|
116
|
+
|
|
117
|
+
# The asynchronous function to be called periodically
|
|
118
|
+
async def update_time_label():
|
|
119
|
+
"""
|
|
120
|
+
Asynchronously updates the time label in the SVG.
|
|
121
|
+
"""
|
|
122
|
+
current_time = datetime.datetime.now().strftime("%H:%M:%S")
|
|
123
|
+
# current_svg = svg_pane.object
|
|
124
|
+
|
|
125
|
+
# # Use a regular expression to update the content of the text element
|
|
126
|
+
# new_svg = re.sub(
|
|
127
|
+
# r'(<tspan id="P_POI".*?>)(.*?)(</tspan>)',
|
|
128
|
+
# r'\1Time: {}\3'.format(current_time),
|
|
129
|
+
# current_svg,
|
|
130
|
+
# flags=re.DOTALL
|
|
131
|
+
# )
|
|
132
|
+
|
|
133
|
+
url = "http://localhost:8000/measurements"
|
|
134
|
+
|
|
135
|
+
ppc_ip = '10.30.0.4'
|
|
136
|
+
|
|
137
|
+
# http://10.30.0.4:5500/ppc_measurements
|
|
138
|
+
|
|
139
|
+
##############################################################################
|
|
140
|
+
url = "http://localhost:8000/measurements"
|
|
141
|
+
#url = f"http://{ppc_ip}:5500/ppc_measurements"
|
|
142
|
+
response = requests.get(url, headers={"Content-Type": "application/json"}, timeout=0.5) # Added a timeout
|
|
143
|
+
response.raise_for_status()
|
|
144
|
+
meas_dict = response.json()
|
|
145
|
+
time.sleep(0.05)
|
|
146
|
+
|
|
147
|
+
###############################################################################
|
|
148
|
+
url = "http://localhost:8000/setpoints"
|
|
149
|
+
#url = f"http://{ppc_ip}:5500/ppc_setpoints"
|
|
150
|
+
headers = {"Content-Type": "application/json"}
|
|
151
|
+
data = {
|
|
152
|
+
"f_x":float(sld_f_x.value)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
response = requests.post(url, headers=headers, data=json.dumps(data))
|
|
156
|
+
|
|
157
|
+
# # This is the line that's failing
|
|
158
|
+
# response.raise_for_status()
|
|
159
|
+
|
|
160
|
+
#response = requests.post(url, headers=headers, data=json.dumps(data))
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
# time.sleep(1.0)
|
|
165
|
+
|
|
166
|
+
# # Generate the new SVG
|
|
167
|
+
# s = svg('cuerva_emec_db.svg')
|
|
168
|
+
# s.set_tspan('U_SS1', f"{meas_dict['U_SS1']/20e3:5.3f} pu")
|
|
169
|
+
# s.set_tspan('U_SS2', f"{meas_dict['U_SS2']/20e3:5.3f} pu")
|
|
170
|
+
# s.set_tspan('U_POI', f"{meas_dict['U_POI']/20e3:5.3f} pu")
|
|
171
|
+
# #s.set_title('GRID_title', f"V = {meas_dict['V_GRID']:5.3f} pu\nP = {meas_dict['p_line_POIHV_GRID'] / 1e6:5.3f} MW\nQ = {meas_dict['q_line_POIHV_GRID'] / 1e6:5.3f} Mvar")
|
|
172
|
+
# s.set_tspan('P_POI', f"{meas_dict['p_line_POI_POIHV'] / 1e6:5.2f} MW")
|
|
173
|
+
# s.set_tspan('Q_POI', f"{meas_dict['q_line_POI_POIHV'] / 1e6:5.2f} Mvar")
|
|
174
|
+
|
|
175
|
+
charts_data['Times'][-1] = time.time() - t_0
|
|
176
|
+
charts_data['theta'][-1] = meas_dict['theta']
|
|
177
|
+
charts_data['f_x'][-1] = meas_dict['f_x']
|
|
178
|
+
|
|
179
|
+
charts_data['Times'][0:-1] = charts_data['Times'][1:]
|
|
180
|
+
charts_data['theta'][0:-1] = charts_data['theta'][1:]
|
|
181
|
+
charts_data['f_x'][0:-1] = charts_data['f_x'][1:]
|
|
182
|
+
|
|
183
|
+
charts_data['k'] += 1
|
|
184
|
+
|
|
185
|
+
plt.close('all') # Clear previous plot
|
|
186
|
+
fig, ax = plt.subplots(figsize=(6, 4))
|
|
187
|
+
ax.plot(charts_data['Times'], charts_data['theta'], color='blue') # Plot new random data
|
|
188
|
+
ax.plot(charts_data['Times'], charts_data['f_x'], color='red') # Plot new random data
|
|
189
|
+
|
|
190
|
+
plot_pane.object = fig # Assign the new figure to the pane
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
# # Link widgets to the update function
|
|
194
|
+
# button1.on_click(update_svg)
|
|
195
|
+
# button2.on_click(update_svg)
|
|
196
|
+
# slider1.param.watch(update_svg, 'value')
|
|
197
|
+
# color_picker.param.watch(update_svg, 'value')
|
|
198
|
+
|
|
199
|
+
# Combine all components into a Panel layout
|
|
200
|
+
dashboard = pn.Column(
|
|
201
|
+
tabs_monitor,
|
|
202
|
+
tabs_ctrl
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
# Use pn.io.periodic_async to run the update_time_label function every 1000ms (1 second)
|
|
206
|
+
# The `dashboard.servable()` is required to use periodic functions in a standalone app.
|
|
207
|
+
# In a Jupyter notebook, `dashboard` will automatically display the periodic updates.
|
|
208
|
+
pn.state.add_periodic_callback(update_time_label, period=100)
|
|
209
|
+
|
|
210
|
+
# Display the dashboard
|
|
211
|
+
dashboard.show()
|