Commit aa8e5884dc92b4924c4b69f584697b093197c0c9
1 parent
68279fc8
Exists in
dev
Grosse amélioration du XML et de la classe ConfigPyros.
Showing
2 changed files
with
770 additions
and
171 deletions
Show diff stats
config/config_unit_simulunit1.xml
... | ... | @@ -7,9 +7,12 @@ This File describes all the parameters that characterize a unit. |
7 | 7 | One parameter <param></param> is defined using the following attributes: |
8 | 8 | section, key, value, type, unit, access, comment, label, reference, timestamp |
9 | 9 | |
10 | +* Mandatory | |
10 | 11 | section : Category of the keyword |
11 | 12 | key : Key of the keyword |
12 | 13 | value : Useful value of the keyword |
14 | + | |
15 | +* Optional | |
13 | 16 | type : Python type to interpret the value |
14 | 17 | unit : Physical value to allow conversions |
15 | 18 | access : 0brwrwrw (rw for PI-Mount, rw for Maintenance, rw for Astronomers) |
... | ... | @@ -23,62 +26,95 @@ timestamp : Date when the value has been last updated |
23 | 26 | |
24 | 27 | <unit alias="SimulUnit1"> |
25 | 28 | |
26 | - <date_created>2018-04-13 00:38:14.461736</date_created> | |
27 | - <!-- Select the unit as one unit and one or more channels --> | |
28 | - <param section="instanciation" key="mount1" value="VirtualMount"/> | |
29 | - <param section="instanciation" key="channel1" value="VirtualCamera"/> | |
29 | + <!-- Some informations about this configuration --> | |
30 | + <date_creation>2018-04-13 00:38:14</date_creation> | |
31 | + <date_last_modification>2019-02-18 16:38:00</date_last_modification> | |
32 | + <author_last_modification>Alain Klotz</author_last_modification> | |
33 | + | |
34 | + <!-- Select the unit as one mount and one or more channels --> | |
35 | + <param section="assembly" key="alias" value="PyROSDatabase" comment="database"/> | |
36 | + <param section="assembly" key="alias" value="VirtualMount" comment="mount"/> | |
37 | + <param section="assembly" key="alias" value="VirtualCamera1" comment="channel"/> | |
30 | 38 | |
39 | + <!-- A database definition --> | |
40 | + <database alias="PyROSDatabase"> | |
41 | + <!-- Select the type of database (DBMS) --> | |
42 | + <param section="management" key="system" value="MySQL"/> | |
43 | + <!-- Access autorizations --> | |
44 | + <param section="access" key="host" value="127.0.0.1"/> | |
45 | + <param section="access" key="port" value="3306"/> | |
46 | + <param section="access" key="user" value="pyros"/> | |
47 | + <param section="access" key="pswd" value="6cacc99693b5bca5a2b9e37dbba529116d" type="str" unit="crypted1"/> | |
48 | + <!-- Database characteristics --> | |
49 | + <param section="database" key="name" value="pyros"/> | |
50 | + </database> | |
51 | + | |
31 | 52 | <!-- A mount definition --> |
32 | 53 | <mount alias="VirtualMount"> |
54 | + <!-- General description --> | |
55 | + <param section="mount" key="name" value="Losmandy"/> | |
56 | + <param section="mount" key="home" value="IRAP" type="str" unit="" comment="Institut de Recherche en Astrophysique et Planetologie"/> | |
57 | + <param section="mount" key="iau_num" value="n.d" type="str" unit="" comment="Not defined"/> | |
33 | 58 | <!-- Set period parameters --> |
34 | 59 | <param section="period" key="periods" value="(1, 2018, 9, 1, 2019, 3, 1), (2, 2019, 3, 1, 2019, 9, 1)" type="int" unit=""/> |
35 | 60 | <param section="period" key="sun_elev_night" value="-10" type="float" unit="deg"/> |
36 | 61 | <param section="partner" key="partners" value="(1, 'PAA', 45, 'Partner_A'), (1, 'PAB', 22, 'Partner_B'), (1, 'PAC', 33, 'Partner_C')" type="int" unit=""/> |
37 | - <!-- Set site parameters --> | |
38 | - <param section="localization" key="home" value="GPS 1.477083 E 43.81667 150" type="str" unit=""/> | |
39 | - <param section="localization" key="name" value="IRAP" type="str" unit="" comment="Institut de Recherche en Astrophysique et Planetologie"/> | |
40 | - <param section="localization" key="iau_num" value="n.d" type="str" unit="" comment="Not defined"/> | |
62 | + <!-- Set device controller agent --> | |
63 | + <param section="MountPointing" key="agent" value="TelescopeSimulator" comment="Value must be the alias of the controller agent"/> | |
41 | 64 | <!-- Set mount paramters for simulations and scheduler --> |
42 | - <param section="mount" key="axe_type" value="hadec" type="str" unit=""/> | |
43 | - <param section="mount" key="ha_liminf" value="-90" type="float" unit="Angle"/> | |
44 | - <param section="mount" key="ha_limsup" value="90" type="float" unit="Angle"/> | |
45 | - <param section="mount" key="dec_liminf" value="-30" type="float" unit="Angle"/> | |
46 | - <param section="mount" key="dec_limsup" value="89.7" type="float" unit="Angle"/> | |
47 | - <param section="mount" key="ha_vel_profile" value="scurve" type="str" unit=""/> | |
48 | - <param section="mount" key="dec_vel_profile" value="scurve" type="str" unit=""/> | |
65 | + <param section="MountPointing" key="home" value="GPS 1.477083 E 43.81667 150" type="str" unit=""/> | |
66 | + <param section="MountPointing" key="axe_type" value="hadec" type="str" unit=""/> | |
67 | + <param section="MountPointing" key="ha_liminf" value="-90" type="float" unit="Angle"/> | |
68 | + <param section="MountPointing" key="ha_limsup" value="90" type="float" unit="Angle"/> | |
69 | + <param section="MountPointing" key="dec_liminf" value="-30" type="float" unit="Angle"/> | |
70 | + <param section="MountPointing" key="dec_limsup" value="89.7" type="float" unit="Angle"/> | |
71 | + <param section="MountPointing" key="ha_vel_profile" value="scurve" type="str" unit=""/> | |
72 | + <param section="MountPointing" key="dec_vel_profile" value="scurve" type="str" unit=""/> | |
49 | 73 | </mount> |
50 | 74 | |
51 | 75 | <!-- A channel definition --> |
52 | - <channel alias="VirtualCamera"> | |
53 | - <!-- Set a name to the camera --> | |
54 | - <param section="channel" key="name" value="VirtualCam" type="str" unit=""/> | |
55 | - <!-- Parameters of the channel for the web form for a plan --> | |
56 | - <param section="channel" key="plan" value="'filter': 'filters symbols', 'binning': 'detector binnings', 'exptime': 'detector exptime_mini exptime_maxi', 'nb_images': 'int 1 Inf', 'shutter': 'shutters', 'delay': 'float 0 Inf'" type="dict" unit=""/> | |
76 | + <channel alias="VirtualCamera1"> | |
77 | + <!-- General description --> | |
78 | + <param section="channel" key="name" value="Takahshi + Atik"/> | |
79 | + <!-- Set device controller agent --> | |
80 | + <param section="DetectorSensor" key="agent" value="CameraSimulator" comment="Value must be the alias of the controller agent"/> | |
81 | + <param section="DetectorShutter" key="agent" value="CameraSimulator" comment="Value must be the alias of the controller agent"/> | |
82 | + <param section="DetectorTimer" key="agent" value="CameraSimulator" comment="Value must be the alias of the controller agent"/> | |
83 | + <param section="FilterSelector" key="agent" value="CameraSimulator" comment="Value must be the alias of the controller agent"/> | |
84 | + <param section="DetectorFocus" key="agent" value="TelescopeSimulator" comment="Value must be the alias of the controller agent"/> | |
85 | + <!-- Camera properties for plans and for simulations --> | |
86 | + <param section="DetectorSensor" key="name" value="Atik 460" type="str" unit=""/> | |
87 | + <param section="DetectorSensor" key="serial_number" value="S/N67Y" type="str" unit=""/> | |
88 | + <param section="DetectorSensor" key="sensor_type" value="CCD" type="str" unit=""/> | |
89 | + <param section="DetectorSensor" key="efficiency" value="0.9" type="float" unit=""/> | |
90 | + <param section="DetectorSensor" key="binnings" value="(1, 1), (2, 2), (3, 3), (4,4)" type="list" unit=""/> | |
91 | + <param section="DetectorSensor" key="exptime_mini" value="0.1" type="float" unit="sec"/> | |
92 | + <param section="DetectorSensor" key="exptime_maxi" value="1000" type="float" unit="sec"/> | |
93 | + <param section="DetectorSensor" key="readouttime" value="10" type="float" unit="sec"/> | |
94 | + <param section="DetectorSensor" key="nbcells1" value="4096" type="int" unit=""/> | |
95 | + <param section="DetectorSensor" key="cellsize1" value="15" type="float" unit="mu"/> | |
96 | + <param section="DetectorSensor" key="nbcells2" value="4096" type="int" unit=""/> | |
97 | + <param section="DetectorSensor" key="cellsize2" value="15" type="float" unit="mu"/> | |
98 | + <param section="DetectorSensor" key="readoutnoise" value="7.5" type="float" unit="electrons"/> | |
99 | + <param section="DetectorSensor" key="gain" value="2.5" type="float" unit="electrons/adu"/> | |
100 | + <param section="DetectorSensor" key="temperature" value="-50" type="float" unit="degC"/> | |
101 | + <param section="DetectorSensor" key="thermic_signal" value="0.05" type="float" unit="electrons/s"/> | |
102 | + <!-- Shutter properties for plans and for simulations --> | |
103 | + <param section="DetectorShutter" key="mode" value="synchro, openned, closed" type="str" unit=""/> | |
104 | + <param section="DetectorShutter" key="delayopening" value="60" type="int" unit="us"/> | |
105 | + <param section="DetectorShutter" key="delayclosing" value="30" type="int" unit="us"/> | |
106 | + <!-- Filter properties for plans and for simulations --> | |
107 | + <param section="FilterSelector" key="symbols" value="B g r i gri" type="str" unit=""/> | |
108 | + <param section="FilterSelector" key="efficiencies" value="0.75 0.85 0.85 0.85 0.85 0.85" type="float" unit=""/> | |
109 | + <param section="FilterSelector" key="lambda_mins" value="0.37 0.40 0.55 0.70 0.40" type="float" unit="mu"/> | |
110 | + <param section="FilterSelector" key="lambda_maxs" value="0.50 0.55 0.70 0.80 0.80" type="float" unit="mu"/> | |
111 | + <param section="FilterSelector" key="positions" value="0 60 120 180 240" type="float" unit="deg"/> | |
57 | 112 | <!-- Optical design of the channel for simulations --> |
113 | + <param section="optic" key="name" value="Takahashi epsilon" type="str" unit=""/> | |
114 | + <param section="optic" key="serial_number" value="875432" type="str" unit=""/> | |
58 | 115 | <param section="optic" key="aperdiam" value="0.16" type="float" unit="m"/> |
59 | 116 | <param section="optic" key="focleneq" value="0.53" type="float" unit="m"/> |
60 | 117 | <param section="optic" key="efficiency" value="0.68" type="float" unit=""/> |
61 | - <!-- List of optical filters for plans and for simulations --> | |
62 | - <param section="filters" key="symbols" value="B g r i gri" type="str" unit=""/> | |
63 | - <param section="filters" key="efficiencies" value="0.75 0.85 0.85 0.85 0.85 0.85" type="float" unit=""/> | |
64 | - <param section="filters" key="lambda_mins" value="0.37 0.40 0.55 0.70 0.40" type="float" unit="mu"/> | |
65 | - <param section="filters" key="lambda_maxs" value="0.50 0.55 0.70 0.80 0.80" type="float" unit="mu"/> | |
66 | - <!-- Camera properties for plans and for simulations --> | |
67 | - <param section="detector" key="sensor_type" value="CCD" type="str" unit=""/> | |
68 | - <param section="detector" key="efficiency" value="0.9" type="float" unit=""/> | |
69 | - <param section="detector" key="binnings" value="(1, 1), (2, 2), (3, 3), (4,4)" type="int" unit=""/> | |
70 | - <param section="detector" key="exptime_mini" value="0.1" type="float" unit="sec"/> | |
71 | - <param section="detector" key="exptime_maxi" value="1000" type="float" unit="sec"/> | |
72 | - <param section="detector" key="readouttime" value="10" type="float" unit="sec"/> | |
73 | - <param section="detector" key="shutters" value="synchro, openned, closed" type="str" unit=""/> | |
74 | - <param section="detector" key="nbcells1" value="4096" type="int" unit=""/> | |
75 | - <param section="detector" key="cellsize1" value="15" type="float" unit="mu"/> | |
76 | - <param section="detector" key="nbcells2" value="4096" type="int" unit=""/> | |
77 | - <param section="detector" key="cellsize2" value="15" type="float" unit="mu"/> | |
78 | - <param section="detector" key="readoutnoise" value="7.5" type="float" unit="electrons"/> | |
79 | - <param section="detector" key="gain" value="2.5" type="float" unit="electrons/adu"/> | |
80 | - <param section="detector" key="temperature" value="-50" type="float" unit="degC"/> | |
81 | - <param section="detector" key="thermic_signal" value="0.05" type="float" unit="electrons/s"/> | |
82 | 118 | <!-- Atmospheric conditions for simulations --> |
83 | 119 | <param section="atmosphere" key="temperature" value="300" type="float" unit="Kelvin"/> |
84 | 120 | <param section="atmosphere" key="pressure" value="101325" type="float" unit="Pascal"/> |
... | ... | @@ -87,14 +123,117 @@ timestamp : Date when the value has been last updated |
87 | 123 | <param section="atmosphere" key="transparency" value="0.8" type="float" unit="0b110101"/> |
88 | 124 | <!-- Define the horizon line for scheduler --> |
89 | 125 | <param section="horizon" key="amer_list" value="(0, 10), (50, 15), (60,10)" type="tuple" unit="Angle"/> |
126 | + <!-- Plan description of this channel for the web form and observations --> | |
127 | + <plan> | |
128 | + <param section="form" key="filter" label="Filter" default_value="" element="input" element_attribute=''/> | |
129 | + <param section="form" key="binning" label="Binning" default_value="" element="select" element_attribute="" options="param detector binnings"/> | |
130 | + <param section="form" key="exptime" label="Exposure time (s)" default_value="1" element="range" element_attribute='min="0.1" max="100"'/> | |
131 | + <param section="form" key="nb_images" label="Number image" default_value="1" element="range" element_attribute='min="1" max="10000"'/> | |
132 | + <param section="form" key="shutter" label="Shutter mode" default_value="1" element="select" element_attribute="" options="param detector shutter_mode"/> | |
133 | + <param section="form" key="delay" label="Delay start (s)" default_value="0" element="range" element_attribute='min="0" max="100"'/> | |
134 | + </plan> | |
90 | 135 | </channel> |
91 | 136 | |
92 | 137 | <!-- A computer definition --> |
93 | 138 | <computer alias="Computer1"> |
139 | + <!-- Access --> | |
140 | + <param section="local" key="hostname" value="titanium" comment="returned by import socket;print(socket.gethostname())"/> | |
141 | + <param section="local" key="ip" value="192.168.0.1"/> | |
142 | + <param section="global" key="hostname" value="titanium.irap.omp.eu"/> | |
143 | + <param section="global" key="www_port" value="80"/> | |
144 | + <!-- Agents to launch on this computer --> | |
145 | + <param section="agent_to_launch" key="alias" value="AgentX"/> | |
146 | + <param section="agent_to_launch" key="alias" value="Monitoring"/> | |
147 | + <param section="agent_to_launch" key="alias" value="TelescopeSimulator"/> | |
148 | + <param section="agent_to_launch" key="alias" value="CameraSimulator"/> | |
149 | + </computer> | |
150 | + | |
151 | + <!-- A computer definition --> | |
152 | + <computer alias="Computer2"> | |
94 | 153 | <!-- Access autorizations --> |
95 | - <param section="access" key="mysql_host" value="127.0.0.1"/> | |
96 | - <param section="access" key="mysql_user" value="pyros"/> | |
97 | - <param section="access" key="mysql_pswd" value="DjangoPyros"/> | |
154 | + <param section="local" key="hostname" value="etienne" comment="returned by import socket;print(socket.gethostname())"/> | |
155 | + <param section="local" key="ip" value="192.168.0.1"/> | |
156 | + <param section="global" key="hostname" value="etienne.irap.omp.eu"/> | |
157 | + <param section="global" key="www_port" value="80"/> | |
158 | + <!-- Agents to launch on this computer --> | |
159 | + <param section="agent_to_launch" key="alias" value="AgentX"/> | |
160 | + <param section="agent_to_launch" key="alias" value="Monitoring"/> | |
161 | + <param section="agent_to_launch" key="alias" value="TelescopeSimulator"/> | |
162 | + <param section="agent_to_launch" key="alias" value="CameraSimulator"/> | |
98 | 163 | </computer> |
99 | 164 | |
100 | -</unit> | |
101 | 165 | \ No newline at end of file |
166 | + <!-- A computer definition --> | |
167 | + <computer alias="Computer3"> | |
168 | + <!-- Access autorizations --> | |
169 | + <param section="local" key="hostname" value="patrick" comment="returned by import socket;print(socket.gethostname())"/> | |
170 | + <param section="local" key="ip" value="192.168.0.1"/> | |
171 | + <param section="global" key="hostname" value="etienne.irap.omp.eu"/> | |
172 | + <param section="global" key="www_port" value="80"/> | |
173 | + <!-- Agents to launch on this computer --> | |
174 | + <param section="agent_to_launch" key="alias" value="AgentX"/> | |
175 | + <param section="agent_to_launch" key="alias" value="Monitoring"/> | |
176 | + <param section="agent_to_launch" key="alias" value="TelescopeSimulator"/> | |
177 | + <param section="agent_to_launch" key="alias" value="CameraSimulator"/> | |
178 | + </computer> | |
179 | + | |
180 | + <!-- An agent definition --> | |
181 | + <agent alias="Superagent1"> | |
182 | + <!-- --> | |
183 | + <param section="general" key="startmode" value="RUN"/> | |
184 | + <!-- Where is the code to launch ? Concatenation of path0_filename + path1_filename + tail_filename --> | |
185 | + <param section="code" key="path0_filename" value="$PYROS"/> | |
186 | + <param section="code" key="path1_filename" value="../pyros_simulunit1/src/superagent1"/> | |
187 | + <param section="code" key="tail_filename" value="SuperAgent1.py"/> | |
188 | + </agent> | |
189 | + | |
190 | + <!-- An agent definition --> | |
191 | + <agent alias="AgentX"> | |
192 | + <!-- --> | |
193 | + <param section="general" key="startmode" value="IDLE"/> | |
194 | + <!-- Where is the code to launch ? Concatenation of path0_filename + path1_filename + tail_filename --> | |
195 | + <param section="code" key="path0_filename" value="$PYROS"/> | |
196 | + <param section="code" key="path1_filename" value="src/agentx"/> | |
197 | + <param section="code" key="tail_filename" value="AgentX.py"/> | |
198 | + </agent> | |
199 | + | |
200 | + <!-- An agent definition --> | |
201 | + <agent alias="AgentY"> | |
202 | + <!-- --> | |
203 | + <param section="general" key="startmode" value="RUN"/> | |
204 | + <!-- Where is the code to launch ? Concatenation of path0_filename + path1_filename + tail_filename --> | |
205 | + <param section="code" key="path0_filename" value="$PYROS"/> | |
206 | + <param section="code" key="path1_filename" value="../pyros_simulunit1/src/agenty"/> | |
207 | + <param section="code" key="tail_filename" value="AgentY.py"/> | |
208 | + </agent> | |
209 | + | |
210 | + <!-- An agent definition --> | |
211 | + <agent alias="TelescopeSimulator"> | |
212 | + <!-- --> | |
213 | + <param section="general" key="startmode" value="RUN"/> | |
214 | + <!-- Where is the code to launch ? Concatenation of path0_filename + path1_filename + tail_filename --> | |
215 | + <param section="code" key="path0_filename" value="$PYROS"/> | |
216 | + <param section="code" key="path1_filename" value="src/telescopesimulator"/> | |
217 | + <param section="code" key="tail_filename" value="TelescopeSimulator.py"/> | |
218 | + </agent> | |
219 | + | |
220 | + <!-- An agent definition --> | |
221 | + <agent alias="CameraSimulator"> | |
222 | + <!-- --> | |
223 | + <param section="general" key="startmode" value="RUN"/> | |
224 | + <!-- Where is the code to launch ? Concatenation of path0_filename + path1_filename + tail_filename --> | |
225 | + <param section="code" key="path0_filename" value="$PYROS"/> | |
226 | + <param section="code" key="path1_filename" value="src/camerasimulator"/> | |
227 | + <param section="code" key="tail_filename" value="CameraSimulator.py"/> | |
228 | + </agent> | |
229 | + | |
230 | + <!-- An agent definition --> | |
231 | + <agent alias="Monitoring"> | |
232 | + <!-- --> | |
233 | + <param section="general" key="startmode" value="RUN"/> | |
234 | + <!-- Where is the code to launch ? Concatenation of path0_filename + path1_filename + tail_filename --> | |
235 | + <param section="code" key="path0_filename" value="$PYROS"/> | |
236 | + <param section="code" key="path1_filename" value="src/monitoring"/> | |
237 | + <param section="code" key="tail_filename" value="start_agent_monitoring.py"/> | |
238 | + </agent> | |
239 | + | |
240 | +</unit> | ... | ... |
config/configpyros.py
... | ... | @@ -2,31 +2,404 @@ |
2 | 2 | # ---------------------------------------------------------------------------------------------------- |
3 | 3 | # Parameter attributes = section, key, value, type, unit, access, comment, label, reference, timestamp |
4 | 4 | # ---------------------------------------------------------------------------------------------------- |
5 | +""" | |
6 | +Example of | |
7 | +config = ConfigPyros() | |
8 | +config.set_configfile('/tmp/myconfig.xml') | |
9 | +stmod = config.get_paramvalue('angentX','general','startmode') | |
10 | +""" | |
11 | +# ---------------------------------------------------------------------------------------------------- | |
12 | + | |
5 | 13 | from lxml import etree |
6 | 14 | import os |
15 | +import socket | |
16 | +import random | |
7 | 17 | |
8 | 18 | class ConfigPyros: |
9 | 19 | |
10 | 20 | # === Constants |
11 | 21 | NO_ERROR = 0 |
12 | - ERR_FILE_NOT_EXISTS = 100 | |
13 | - ERR_LOAD_ERROR = 200 | |
14 | - ERR_TAG_ROOT_IS_NOT_UNIT = 201 | |
15 | - ERR_TAG_ROOT_HAS_NO_ATTRIBUTE_ALIAS = 202 | |
22 | + | |
23 | + ERR_FILE_NOT_EXISTS = 101 | |
24 | + ERR_XML_FILE_ERROR = 102 | |
25 | + | |
26 | + ERR_A_SUBTAG_UNIT_HAVE_NO_ATTRIBUTE_ALIAS = 301 | |
27 | + ERR_ASSEMBLED_ALIAS_NOT_DEFINED = 302 | |
28 | + ERR_NO_MOUNT_ASSEMBLED = 303 | |
29 | + ERR_ONLY_ONE_MOUNT_CAN_BE_ASSEMBLED = 304 | |
30 | + ERR_NO_CHANNEL_ASSEMBLED = 305 | |
31 | + ERR_NO_DATABASE_ASSEMBLED = 306 | |
16 | 32 | |
17 | 33 | # === Private variables |
18 | 34 | _last_errno = NO_ERROR |
35 | + _last_errparam1 = "" | |
36 | + # --- XML file | |
19 | 37 | _config_filename = "" |
20 | 38 | _config_filename_mtime = 0 |
21 | 39 | _config_filename_need_to_be_read = True |
22 | - _unit_component_params = [] | |
23 | - _unit_component_params_valid = False | |
40 | + # --- XML structure | |
41 | + _tags_to_scan = None | |
42 | + # --- XML contents | |
43 | + _config_contents_valid = False | |
44 | + _tree = None | |
45 | + _root = None | |
46 | + _unit_subtags = None | |
47 | + _tag_aliases = None | |
48 | + _assemblies = None | |
49 | + # --- Computer infos | |
50 | + _hostname = None | |
51 | + _this_computer_alias = None | |
52 | + | |
53 | +# ===================================================================== | |
54 | +# ===================================================================== | |
55 | +# Private methods | |
56 | +# ===================================================================== | |
57 | +# ===================================================================== | |
58 | + | |
59 | + def _configfile_verify(self): | |
60 | + """ Update parameters of the configuration file (existing, modification date) | |
61 | + """ | |
62 | + self._config_filename_need_to_be_read = False | |
63 | + self._last_errno = self.NO_ERROR | |
64 | + if os.path.isfile(self._config_filename): | |
65 | + # --- verify the date of last modification of the file | |
66 | + config_filename_mtime = os.path.getmtime(self._config_filename) | |
67 | + if config_filename_mtime > self._config_filename_mtime: | |
68 | + self._config_filename_need_to_be_read = True | |
69 | + #### self._config_filename_mtime = config_filename_mtime | |
70 | + else: | |
71 | + self._last_errno = self.ERR_FILE_NOT_EXISTS | |
72 | + | |
73 | + def _parse_xml2lists(self, verbose:bool = False): | |
74 | + """ Transform the DOM XML structure into usable lists for PyROS | |
75 | + """ | |
76 | + | |
77 | + if (verbose==True): | |
78 | + print("============== Subtags of <unit> Information with attribute alias") | |
79 | + | |
80 | + unit_subtags = [] | |
81 | + tags_to_scan = [''] | |
82 | + xpath = '/unit' + '/*' | |
83 | + for elem in self._root.xpath(xpath): | |
84 | + if str(type(elem)) != "<class 'lxml.etree._Element'>": | |
85 | + continue | |
86 | + if elem.tag in unit_subtags: | |
87 | + continue | |
88 | + if elem.attrib.get('alias',None) == None: | |
89 | + continue | |
90 | + unit_subtags.append(elem.tag) | |
91 | + tags_to_scan.append(elem.tag) | |
92 | + if (verbose==True): | |
93 | + print("<{}> subtags = {}".format(xpath, unit_subtags)) | |
94 | + | |
95 | + # --- verify the presence of at less one of the following subtag of <unit> | |
96 | + mandatory_tags = ['', 'database', 'mount', 'channel', 'computer', 'agent'] | |
97 | + for mandatory_tag in mandatory_tags: | |
98 | + if mandatory_tag not in tags_to_scan: | |
99 | + self._last_errno = self.ERR_A_SUBTAG_UNIT_HAVE_NO_ATTRIBUTE_ALIAS | |
100 | + if mandatory_tag == '': | |
101 | + self._last_errparam1 = 'unit' | |
102 | + else: | |
103 | + self._last_errparam1 = mandatory_tag | |
104 | + return False | |
105 | + | |
106 | + # --- Get all aliases of subtags of <unit> | |
107 | + # --- Set the tag_aliases dictionnary of lists | |
108 | + tag_aliases = {} | |
109 | + for tag in tags_to_scan: | |
110 | + | |
111 | + if tag == "": | |
112 | + xpath = '/unit' | |
113 | + tag = 'unit' | |
114 | + else: | |
115 | + xpath = '/unit/' + tag | |
116 | + if (verbose==True): | |
117 | + print("============== Aliases of <" + tag + ">") | |
118 | + | |
119 | + attrib_key_to_get = 'alias' | |
120 | + aliases = config.get_attribute_level0(xpath,attrib_key_to_get) | |
121 | + if (verbose==True): | |
122 | + print("<{} {}> = {}".format(xpath, attrib_key_to_get, aliases)) | |
123 | + if aliases == [None]: | |
124 | + self._last_errno = self.ERR_TAG_MOUNT_HAVE_NO_ATTRIBUTE_ALIAS | |
125 | + return False | |
126 | + tag_aliases[tag] = aliases | |
127 | + | |
128 | + if (verbose==True): | |
129 | + print("============== Unit all alias intantiations in one list") | |
130 | + | |
131 | + # --- get all the assemblies | |
132 | + xpath = '/unit' | |
133 | + attrib_to_select = {'alias': (tag_aliases['unit'])[0]} | |
134 | + tag_to_get = "param" | |
135 | + tag_attrib_to_select = {'section': 'assembly', 'key': 'alias'} | |
136 | + tag_attrib_key_to_get = 'value' | |
137 | + assembled_aliases = config.get_attribute_level1(xpath,attrib_to_select,tag_to_get,tag_attrib_to_select,tag_attrib_key_to_get) | |
138 | + if (verbose==True): | |
139 | + print("{} <{} {}> = {}".format(attrib_to_select, tag_to_get, tag_attrib_to_select, assembled_aliases)) | |
140 | + | |
141 | + if (verbose==True): | |
142 | + print("============== Unit alias intantiations in dictionnary of tags") | |
143 | + | |
144 | + # --- Set the assembly dictionnary of lists | |
145 | + assemblies = {} | |
146 | + for assembled_alias in assembled_aliases: | |
147 | + als = [] | |
148 | + for tag in tags_to_scan: | |
149 | + if tag == '': | |
150 | + continue | |
151 | + #print("tag = {}".format(tag)) | |
152 | + #print("assembled_alias = {}".format(assembled_alias)) | |
153 | + #print("tag_aliases[tag] = {}".format(tag_aliases[tag])) | |
154 | + if assembled_alias in tag_aliases[tag]: | |
155 | + als.append(assembled_alias) | |
156 | + the_tag = tag | |
157 | + #print("n = {}".format(n)) | |
158 | + if len(als) == 0: | |
159 | + self._last_errno = self.ERR_ASSEMBLED_ALIAS_NOT_DEFINED | |
160 | + self._last_errparam1 = tag | |
161 | + return False | |
162 | + else: | |
163 | + assemblies[the_tag] = als | |
164 | + if (verbose==True): | |
165 | + print("assemblies = {}".format(assemblies)) | |
166 | + | |
167 | + # --- check the number of mounts assembled | |
168 | + if 'mount' in assemblies.keys(): | |
169 | + if (len(assemblies['mount']) > 1): | |
170 | + if (verbose==True): | |
171 | + print("Error: Only one mount can be assembled") | |
172 | + self._last_errno = self.ERR_ONLY_ONE_MOUNT_CAN_BE_ASSEMBLED | |
173 | + return False | |
174 | + else: | |
175 | + if (verbose==True): | |
176 | + print("Error: No mount assembled") | |
177 | + self._last_errno = self.ERR_NO_MOUNT_ASSEMBLED | |
178 | + return False | |
179 | + | |
180 | + # --- check the number of channels assembled | |
181 | + if 'channel' not in assemblies.keys(): | |
182 | + if (verbose==True): | |
183 | + print("Error: No channel assembled") | |
184 | + self._last_errno = self.ERR_NO_CHANNEL_ASSEMBLED | |
185 | + return False | |
186 | + | |
187 | + # --- Chack the computer infos | |
188 | + if (verbose==True): | |
189 | + print("============== Unit all alias intantiations in one list") | |
190 | + | |
191 | + # --- get all the assemblies | |
192 | + this_computer_alias = None | |
193 | + hostname = socket.gethostname() | |
194 | + aliases = tag_aliases['computer'] | |
195 | + xpath = '/unit/computer' | |
196 | + tag_to_get = "param" | |
197 | + tag_attrib_to_select = {'section': 'local', 'key': 'hostname'} | |
198 | + tag_attrib_key_to_get = 'value' | |
199 | + for alias in aliases: | |
200 | + attrib_to_select = {'alias': alias} | |
201 | + hname = config.get_attribute_level1(xpath,attrib_to_select,tag_to_get,tag_attrib_to_select,tag_attrib_key_to_get) | |
202 | + if hname[0] == hostname: | |
203 | + this_computer_alias = alias | |
204 | + | |
205 | + # --- Everything was OK until this point. Validate the XML | |
206 | + self._unit_subtags = unit_subtags | |
207 | + self._tags_to_scan = tags_to_scan | |
208 | + self._tag_aliases = tag_aliases | |
209 | + self._assemblies = assemblies | |
210 | + self._this_computer_alias = this_computer_alias | |
211 | + | |
212 | + return True | |
213 | + | |
214 | + def _alias2xpath(self, alias, subtag=""): | |
215 | + #print("alias={}".format(alias)) | |
216 | + tag = self.get_unit_subtag(alias) | |
217 | + #print("tag={}".format(tag)) | |
218 | + if tag == 'unit': | |
219 | + xpath = '/unit' | |
220 | + elif tag == None: | |
221 | + return None | |
222 | + else: | |
223 | + xpath = '/unit/' + tag | |
224 | + if subtag != "": | |
225 | + xpath += '/' + subtag | |
226 | + return xpath | |
227 | + | |
228 | + def _encode(self, texte:str, method:str = 'crypted1', phrase:str = "(Af%"): | |
229 | + if method == 'crypted1': | |
230 | + lphrase = len(phrase) | |
231 | + plus = random.randint(1,9) | |
232 | + for i in range(plus): | |
233 | + texte += chr(random.randint(32,255)) | |
234 | + texte += chr(ord(str(plus))) | |
235 | + texte_hexa_codeds = "" | |
236 | + for i in range(len(texte)): | |
237 | + phrase_deci = ord(phrase[i%lphrase])+i | |
238 | + texte_deci = ord(texte[i]) | |
239 | + #texte_hexa = hex(texte_deci) | |
240 | + texte_deci_coded = (texte_deci + phrase_deci)%256 | |
241 | + texte_hexa_coded = "{0:#0{1}x}".format(texte_deci_coded,4) | |
242 | + texte_hexa_codeds += texte_hexa_coded[2:4] | |
243 | + #print("{} raw={} {} {} coded={} {}".format(i,texte[i],texte_deci,phrase_deci,texte_deci_coded,texte_hexa_coded)) | |
244 | + return texte_hexa_codeds | |
245 | + else: | |
246 | + return texte | |
247 | + | |
248 | + def _decode(self, crypted:str, method:str = 'crypted1', phrase:str = "(Af%"): | |
249 | + if method == 'crypted1': | |
250 | + if crypted == '': | |
251 | + return '' | |
252 | + lphrase = len(phrase) | |
253 | + texte_hexa_codeds = crypted | |
254 | + texte = "" | |
255 | + for i in range(int(len(texte_hexa_codeds)/2)): | |
256 | + phrase_deci = ord(phrase[i%lphrase])+i | |
257 | + texte_hexa_coded = '0x'+texte_hexa_codeds[2*i:2*i+2] | |
258 | + texte_deci_coded = int(texte_hexa_coded,16) | |
259 | + texte_deci = (texte_deci_coded - phrase_deci + 256)%256 | |
260 | + texte += chr(texte_deci) | |
261 | + #print("{} coded={} raw={} {}".format(i,texte_hexa_coded,texte_deci,chr(texte_deci))) | |
262 | + plus = int(texte[-1]) | |
263 | + texte = texte[0:-1-plus] | |
264 | + return texte | |
265 | + else: | |
266 | + return crypted | |
267 | + | |
268 | +# ===================================================================== | |
269 | +# ===================================================================== | |
270 | +# Methods for experimented users | |
271 | +# ===================================================================== | |
272 | +# ===================================================================== | |
273 | + | |
274 | + def get_attribute_level0(self, xpath:str, attrib_key_to_get:str): | |
275 | + """ Read a list of values ['d', 'e'] from the following XML structure: | |
276 | + <a> | |
277 | + <b "c"="d"> | |
278 | + ... | |
279 | + </b> | |
280 | + <b "c"="e"> | |
281 | + ... | |
282 | + </b> | |
283 | + </a> | |
284 | + Select the path: xpath = '/a/b' | |
285 | + Select key attribute: attrib_key_to_get = 'c' | |
286 | + Call the method: | |
287 | + result = ConfigPyros.get_attribute_level0(xpath,attrib_to_select,tag_to_get,tag_attrib_to_select tag_attrib_key_to_get) | |
288 | + """ | |
289 | + if self._config_contents_valid == False: | |
290 | + return "" | |
291 | + root = self._root | |
292 | + # | |
293 | + # 1) get the path of /unit/agent with a given attribute | |
294 | + # -- | |
295 | + attrib_value_to_gets = [] | |
296 | + for elem in root.xpath(xpath): | |
297 | + if str(type(elem)) != "<class 'lxml.etree._Element'>": | |
298 | + continue | |
299 | + attrib_value_to_gets.append( elem.attrib.get(attrib_key_to_get,None) ) | |
300 | + return attrib_value_to_gets | |
24 | 301 | |
302 | + def get_attribute_level1(self, xpath:str, attrib_to_select:dict, tag_to_get:str, tag_attrib_to_select:dict, tag_attrib_key_to_get:str): | |
303 | + """ Read a value 'k' from the following XML structure: | |
304 | + <a> | |
305 | + <b "c"="d"> | |
306 | + <e "f"="g" "h"="i" "j"="k"/> | |
307 | + </b> | |
308 | + </a> | |
309 | + Select the path: xpath = '/a/b' | |
310 | + Select the attribute dictionary: attrib_to_select = {'c': 'd'} | |
311 | + Select tag: tag_to_get = "e" | |
312 | + Select tag attribute dictionary: tag_attrib_to_select = {'f': 'g', 'h': 'i'} | |
313 | + Select key attribute: tag_attrib_key_to_get = 'j' | |
314 | + Call the method: | |
315 | + result = ConfigPyros.get_attribute_level1(xpath,attrib_to_select,tag_to_get,tag_attrib_to_select tag_attrib_key_to_get) | |
316 | + """ | |
317 | + if self._config_contents_valid == False: | |
318 | + return "" | |
319 | + root = self._root | |
320 | + tree = self._tree | |
321 | + # | |
322 | + # 1) get the path of /a/b with a given attribute c="d" | |
323 | + # -- | |
324 | + #print("============== xpath {}".format(xpath)) | |
325 | + nb = 0 | |
326 | + for elem in root.xpath(xpath): | |
327 | + if str(type(elem)) != "<class 'lxml.etree._Element'>": | |
328 | + continue | |
329 | + nbitems = len(attrib_to_select) | |
330 | + nb = 0 | |
331 | + for key in attrib_to_select.keys(): | |
332 | + value = attrib_to_select[key] | |
333 | + vxml = elem.attrib.get(key,None) | |
334 | + #print("key={} value={} vxml={}".format(key,value,vxml)) | |
335 | + if value == vxml: | |
336 | + nb += 1 | |
337 | + #print("nb={} nbitems={}".format(nb,nbitems)) | |
338 | + if nb == nbitems: | |
339 | + path = tree.getpath(elem) | |
340 | + #print("tree.getpath(elem) = {}".format(tree.getpath(elem))) | |
341 | + if nb==0: | |
342 | + nb = 1 | |
343 | + break | |
344 | + # | |
345 | + # 2) get the list of params correspondong to the selected 'b' | |
346 | + attrib_value_to_gets = [] | |
347 | + if nb==0: | |
348 | + return attrib_value_to_gets | |
349 | + #print("---------------") | |
350 | + for elem in root.xpath(path+"/*"): | |
351 | + if str(type(elem)) != "<class 'lxml.etree._Element'>": | |
352 | + continue | |
353 | + #print(" elem.tag= {}".format(elem.tag)) | |
354 | + if elem.tag == tag_to_get: | |
355 | + if tag_attrib_to_select == "" and tag_attrib_key_to_get == "": | |
356 | + attrib_value_to_gets.append(elem.attrib) | |
357 | + #print(" elem.attrib = {}".format(elem.attrib)) | |
358 | + else: | |
359 | + nbitems = len(tag_attrib_to_select) | |
360 | + #print(" elem.attrib = {}".format(elem.attrib)) | |
361 | + nb = 0 | |
362 | + for key in tag_attrib_to_select.keys(): | |
363 | + value = tag_attrib_to_select[key] | |
364 | + vxml = elem.attrib.get(key,None) | |
365 | + #print("key={} value={} vxml={}".format(key,value,vxml)) | |
366 | + if value == vxml: | |
367 | + nb += 1 | |
368 | + #print("nb={} nbitems={}".format(nb,nbitems)) | |
369 | + if nb == nbitems: | |
370 | + if tag_attrib_key_to_get == "": | |
371 | + attrib_value_to_gets.append( elem.attrib ) | |
372 | + else: | |
373 | + attrib_value_to_gets.append( elem.attrib.get(tag_attrib_key_to_get,None) ) | |
374 | + return attrib_value_to_gets | |
375 | + | |
376 | +# ===================================================================== | |
377 | +# ===================================================================== | |
378 | +# Methods for users | |
379 | +# ===================================================================== | |
380 | +# ===================================================================== | |
381 | + | |
25 | 382 | def get_last_errno(self): |
26 | 383 | """ Get the last error code |
27 | 384 | """ |
28 | 385 | return self._last_errno |
29 | - | |
386 | + | |
387 | + def get_last_errmsg(self): | |
388 | + """ Get the last error message | |
389 | + """ | |
390 | + msg = "Unknown error" | |
391 | + if self._last_errno == self.NO_ERROR: msg = "No error" | |
392 | + elif self._last_errno == self.ERR_FILE_NOT_EXISTS: msg = "File does not exists" | |
393 | + elif self._last_errno == self.ERR_XML_FILE_ERROR: msg = "XML file error" | |
394 | + elif self._last_errno == self.ERR_A_SUBTAG_UNIT_HAVE_NO_ATTRIBUTE_ALIAS: msg = "Tags <{}> have no attribute alias".format(self._last_errparam1) | |
395 | + elif self._last_errno == self.ERR_ASSEMBLED_ALIAS_NOT_DEFINED: msg = "Instantiated {} not defined in a <{}>".format(self._last_errparam1,self._last_errparam1) | |
396 | + elif self._last_errno == self.ERR_NO_MOUNT_ASSEMBLED: msg = "No mount assembled" | |
397 | + elif self._last_errno == self.ERR_ONLY_ONE_MOUNT_CAN_BE_ASSEMBLED: msg = "Only one mount can be assembled" | |
398 | + elif self._last_errno == self.ERR_NO_CHANNEL_ASSEMBLED: msg = "No channel assembled" | |
399 | + elif self._last_errno == self.ERR_NO_DATABASE_ASSEMBLED: msg = "No database assembled" | |
400 | + | |
401 | + return msg | |
402 | + | |
30 | 403 | def set_configfile(self, config_filename:str ): |
31 | 404 | """ To set the config file name |
32 | 405 | |
... | ... | @@ -36,8 +409,9 @@ class ConfigPyros: |
36 | 409 | if config_filename == "" or config_filename != self._config_filename: |
37 | 410 | self._config_filename = config_filename |
38 | 411 | self._config_filename_mtime = 0 |
39 | - self._unit_component_params_valid = False | |
40 | - self._unit_component_params = [] | |
412 | + self._config_contents_valid = False | |
413 | + self._tree = None | |
414 | + self._root = None | |
41 | 415 | self._configfile_verify() |
42 | 416 | return |
43 | 417 | |
... | ... | @@ -46,22 +420,7 @@ class ConfigPyros: |
46 | 420 | """ |
47 | 421 | return self._config_filename |
48 | 422 | |
49 | - def _configfile_verify(self): | |
50 | - """ Update parameters of the configuration file (existing, modification date) | |
51 | - """ | |
52 | - self._config_filename_need_to_be_read = False | |
53 | - self._last_errno = self.NO_ERROR | |
54 | - if os.path.isfile(self._config_filename): | |
55 | - # --- verify the date of last modification of the file | |
56 | - config_filename_mtime = os.path.getmtime(self._config_filename) | |
57 | - if config_filename_mtime > self._config_filename_mtime: | |
58 | - self._config_filename_need_to_be_read = True | |
59 | - #### self._config_filename_mtime = config_filename_mtime | |
60 | - else: | |
61 | - self._last_errno = self.ERR_FILE_NOT_EXISTS | |
62 | - | |
63 | - | |
64 | - def load(self, verbose:bool = False): | |
423 | + def load(self, verbose:bool = False, force:bool = False): | |
65 | 424 | """ To load the config file if necessary |
66 | 425 | |
67 | 426 | :Example: |
... | ... | @@ -69,134 +428,235 @@ class ConfigPyros: |
69 | 428 | ConfigPyros().load() |
70 | 429 | """ |
71 | 430 | |
431 | + # --- Verify the existence and the last modification of the XML file | |
72 | 432 | self._configfile_verify() |
73 | 433 | errno = self.get_last_errno() |
74 | 434 | if errno != self.NO_ERROR: |
435 | + if (verbose==True): | |
436 | + print("Load Error = {}".format(errno)) | |
75 | 437 | return |
76 | - if self._config_filename_need_to_be_read == False: | |
438 | + if self._config_filename_need_to_be_read == False and force == False: | |
77 | 439 | return |
78 | 440 | |
79 | 441 | # --- Read the configuration file and parse it |
80 | 442 | self._last_errno = self.NO_ERROR |
81 | - unit_component_params = [] | |
82 | 443 | try: |
444 | + # --- Save the current tree and root as '_old' | |
445 | + self._tree_old = self._tree | |
446 | + self._root_old = self._root | |
447 | + | |
448 | + # --- Parse the XML file into DOM | |
83 | 449 | tree = etree.parse(self._config_filename) |
450 | + | |
84 | 451 | # --- Get root from the tree |
85 | 452 | root = tree.getroot() |
86 | 453 | |
87 | - # === Verify the root tag is 'unit' | |
88 | - verify_unit = root.tag | |
89 | - if (verify_unit != "unit"): | |
90 | - self._last_errno = self.ERR_TAG_ROOT_IS_NOT_UNIT | |
91 | - return | |
92 | - | |
93 | - # === Get the alias value of the root tag 'unit' | |
94 | - alias_unit = root.attrib['alias'] | |
95 | - if (alias_unit == ""): | |
96 | - self._last_errno = self.ERR_TAG_ROOT_HAS_NO_ATTRIBUTE_ALIAS | |
97 | - return | |
98 | - | |
99 | - # === Get the mount aliases | |
100 | - alias_mounts = [] | |
101 | - for elem in root.xpath("/unit/mount"): | |
102 | - # print(elem.tag, elem.attrib) | |
103 | - alias_mounts.append(elem.attrib['alias']) | |
104 | - if (verbose==True): | |
105 | - print("alias_mounts = {}".format(alias_mounts)) | |
454 | + # --- Set the new tree and root | |
455 | + self._tree = tree | |
456 | + self._root = root | |
106 | 457 | |
107 | - # === Get the channel aliases | |
108 | - alias_channels = [] | |
109 | - for elem in root.xpath("/unit/channel"): | |
110 | - # print(elem.tag, elem.attrib) | |
111 | - alias_channels.append(elem.attrib['alias']) | |
112 | - if (verbose==True): | |
113 | - print("alias_channels = {}".format(alias_channels)) | |
114 | - | |
115 | - # === Get the association of channels for this mount | |
116 | - unit_components = [] | |
117 | - for elem in root: | |
118 | - if elem.tag == "param": | |
119 | - attributes = elem.attrib | |
120 | - if attributes['section'] != "instanciation": | |
121 | - continue | |
122 | - alias_param_unit = attributes['value'] | |
123 | - for alias_mount in alias_mounts: | |
124 | - if alias_param_unit == alias_mount: | |
125 | - key = attributes['key'] | |
126 | - dico = {'tag':'mount','instanciation':key,'alias':alias_param_unit} | |
127 | - unit_components.append(dico) | |
128 | - for alias_channel in alias_channels: | |
129 | - if alias_param_unit == alias_channel: | |
130 | - key = attributes['key'] | |
131 | - dico = {'tag':'channel','instanciation':key,'alias':alias_param_unit} | |
132 | - unit_components.append(dico) | |
133 | - if (verbose==True): | |
134 | - print("unit_components = {}".format(unit_components)) | |
135 | - | |
136 | - # === Get detailed informations about the unit components | |
137 | - for unit_component in unit_components: | |
138 | - tag = unit_component['tag'] | |
139 | - instanciation = unit_component['instanciation'] | |
140 | - alias = unit_component['alias'] | |
141 | - params = [] | |
142 | - for elem in root: | |
143 | - if (elem.tag == tag) and (elem.attrib['alias'] == alias): | |
144 | - for el in elem: | |
145 | - if (el.tag == "param"): | |
146 | - params.append(el.attrib) | |
147 | - unit_component_params.append({'component':tag, 'instanciation':instanciation, 'alias':alias, 'params':params}) | |
148 | - if (verbose==True): | |
149 | - print("unit_component_params = {}".format(unit_component_params)) | |
150 | - self._unit_component_params = unit_component_params | |
151 | - self._unit_component_params_valid = True | |
152 | - self._config_filename_mtime = os.path.getmtime(self._config_filename) | |
458 | + # --- Parse the DOM into usable lists | |
459 | + self._config_contents_valid = True | |
460 | + valid = self._parse_xml2lists(verbose) | |
461 | + | |
462 | + # --- Validation step | |
463 | + if valid == True: | |
464 | + self._config_filename_mtime = os.path.getmtime(self._config_filename) | |
465 | + else: | |
466 | + # --- Se the current tree and root from '_old' | |
467 | + self._config_contents_valid = False | |
468 | + self._tree = self._tree_old | |
469 | + self._root = self._root_old | |
470 | + | |
153 | 471 | except: |
154 | - self._last_errno = self.ERR_LOAD_ERROR | |
472 | + self._last_errno = self.ERR_XML_FILE_ERROR | |
155 | 473 | return |
156 | - | |
157 | - def get_paramvalue(self, instanciation:str, section:str, key:str): | |
158 | - if self._unit_component_params_valid == False: | |
474 | + | |
475 | + def get_unit_subtags(self): | |
476 | + if self._config_contents_valid == False: | |
477 | + return "" | |
478 | + return self._unit_subtags | |
479 | + | |
480 | + def get_aliases(self, unit_subtag): | |
481 | + if self._config_contents_valid == False: | |
159 | 482 | return "" |
160 | - unit_component_params = self._unit_component_params | |
161 | - paramvalue = "" | |
162 | - for unit_component_param in unit_component_params: | |
163 | - component_instanciation = unit_component_param['instanciation'] | |
164 | - if (component_instanciation == instanciation): | |
165 | - for param in unit_component_param['params']: | |
166 | - param_section = param['section'] | |
167 | - param_key = param['key'] | |
168 | - if (param_section == section) and (param_key == key): | |
169 | - paramvalue = param['value'] | |
170 | - break | |
171 | - if (paramvalue != ""): | |
172 | - break | |
173 | - return paramvalue | |
483 | + return self._tag_aliases[unit_subtag] | |
484 | + | |
485 | + def get_unit_subtag(self, alias): | |
486 | + if self._config_contents_valid == False: | |
487 | + return "" | |
488 | + for unit_subtag in self._tag_aliases: | |
489 | + aliases = self.get_aliases(unit_subtag) | |
490 | + #print("alias={} in aliases={}".format(alias,aliases)) | |
491 | + if alias in aliases: | |
492 | + return unit_subtag | |
493 | + return None | |
174 | 494 | |
495 | + def get_params(self, alias, subtag=""): | |
496 | + """ Select the tag corresponding to alias | |
497 | + Return the list of dictionaries of all attributes | |
498 | + """ | |
499 | + if self._config_contents_valid == False: | |
500 | + return "" | |
501 | + # --- search the tag from its alias | |
502 | + xpath = self._alias2xpath(alias, subtag) | |
503 | + attrib_to_select = {'alias': alias} | |
504 | + tag_to_get = "param" | |
505 | + tag_attrib_to_select = "" | |
506 | + tag_attrib_key_to_get = "" | |
507 | + #print("get_params alias={} subtag={} xpath={}".format(alias,subtag,xpath)) | |
508 | + value = config.get_attribute_level1(xpath,attrib_to_select,tag_to_get,tag_attrib_to_select,tag_attrib_key_to_get) | |
509 | + #print("{} <{} {}> = {}".format(attrib_to_select, tag_to_get, tag_attrib_to_select, value)) | |
510 | + if (len(value)>0): | |
511 | + return value | |
512 | + return None | |
513 | + | |
514 | + def get_param(self, alias, section, key, subtag=""): | |
515 | + """ Select the tag corresponding to alias, and <param> tag with attributes section=, key= | |
516 | + Return the dictionary of all attributes | |
517 | + """ | |
518 | + if self._config_contents_valid == False: | |
519 | + return "" | |
520 | + # --- search the tag from its alias | |
521 | + xpath = self._alias2xpath(alias, subtag) | |
522 | + attrib_to_select = {'alias': alias} | |
523 | + tag_to_get = "param" | |
524 | + tag_attrib_to_select = {'section': section, 'key': key} | |
525 | + tag_attrib_key_to_get = "" | |
526 | + #print("get_param alias={} subtag={} xpath={}".format(alias,subtag,xpath)) | |
527 | + value = config.get_attribute_level1(xpath,attrib_to_select,tag_to_get,tag_attrib_to_select,tag_attrib_key_to_get) | |
528 | + #print("{} <{} {}> = {}".format(attrib_to_select, tag_to_get, tag_attrib_to_select, value)) | |
529 | + if (len(value)>0): | |
530 | + return value[0] | |
531 | + return None | |
532 | + | |
533 | + def get_paramvalue(self, alias, section, key, subtag=""): | |
534 | + """ Select the tag corresponding to alias, and <param> tag with attributes section=, key= | |
535 | + Return only the value= | |
536 | + """ | |
537 | + if self._config_contents_valid == False: | |
538 | + return "" | |
539 | + # --- search the tag from its alias | |
540 | + xpath = self._alias2xpath(alias, subtag) | |
541 | + attrib_to_select = {'alias': alias} | |
542 | + tag_to_get = "param" | |
543 | + tag_attrib_to_select = {'section': section, 'key': key} | |
544 | + tag_attrib_key_to_get = 'value' | |
545 | + #print("get_paramvalue alias={} subtag={} xpath={}".format(alias,subtag,xpath)) | |
546 | + value = config.get_attribute_level1(xpath,attrib_to_select,tag_to_get,tag_attrib_to_select,tag_attrib_key_to_get) | |
547 | + #print("{} <{} {}> = {}".format(attrib_to_select, tag_to_get, tag_attrib_to_select, value)) | |
548 | + if (len(value)>0): | |
549 | + return value[0] | |
550 | + return None | |
551 | + | |
552 | + def get_plan(self, alias): | |
553 | + """ Select the tag corresponding to alias, and <param> tag with attributes section=, key= | |
554 | + Return the dictionary of all attributes | |
555 | + """ | |
556 | + if self._config_contents_valid == False: | |
557 | + return "" | |
558 | + # --- search the tag from its alias | |
559 | + subtag = 'plan' | |
560 | + xpath = self._alias2xpath(alias, subtag) | |
561 | + #attrib_to_select = {'alias': 'current'} | |
562 | + attrib_to_select = {} | |
563 | + tag_to_get = "param" | |
564 | + tag_attrib_to_select = "" | |
565 | + tag_attrib_key_to_get = "" | |
566 | + #print("get_plan alias={} subtag={} xpath={}".format(alias,subtag,xpath)) | |
567 | + value = config.get_attribute_level1(xpath,attrib_to_select,tag_to_get,tag_attrib_to_select,tag_attrib_key_to_get) | |
568 | + #print("{} <{} {}> = {}".format(attrib_to_select, tag_to_get, tag_attrib_to_select, value)) | |
569 | + if (len(value)>0): | |
570 | + return value | |
571 | + return None | |
572 | + | |
573 | + def get_computer_alias(self): | |
574 | + if self._config_contents_valid == False: | |
575 | + return "" | |
576 | + return self._this_computer_alias | |
577 | + | |
578 | + def encode(self, text:str, method:str = 'crypted1'): | |
579 | + return self._encode(text,method) | |
580 | + | |
581 | + def decode(self, crypted:str, method:str = 'crypted1'): | |
582 | + return self._decode(crypted,method) | |
583 | + | |
584 | +# ===================================================================== | |
585 | +# ===================================================================== | |
586 | +# Special methods | |
587 | +# ===================================================================== | |
588 | +# ===================================================================== | |
589 | + | |
175 | 590 | def __init__(self, config_filename:str = ""): |
176 | 591 | self._last_errno = self.NO_ERROR |
177 | 592 | self._unit_component_params = [] |
178 | 593 | self.set_configfile(config_filename) |
594 | + | |
595 | +# ===================================================================== | |
596 | +# ===================================================================== | |
597 | +# Test if main | |
598 | +# ===================================================================== | |
599 | +# ===================================================================== | |
179 | 600 | |
180 | 601 | if __name__ == "__main__": |
602 | + cwd = os.getcwd() | |
181 | 603 | # --- Set the filename of the configuration |
182 | - config_filename = 'c:/srv/develop/pyros/config/config_unit_simulunit1.xml' | |
183 | - #config_filename = '/PROJECTS/GFT/SOFT/PYROS_SOFT/CURRENT/config/config_unit_simulunit1.xml' | |
604 | + config_filename = cwd + '/config_unit_simulunit1.xml' | |
605 | + print("config_filename = {}\n".format(config_filename)) | |
606 | + | |
184 | 607 | # --- Instanciate an object for configuration |
185 | - config = ConfigPyros(config_filename) | |
186 | - #config.set_configfile(config_filename) | |
608 | + config = ConfigPyros() | |
609 | + config.set_configfile(config_filename) | |
610 | + | |
187 | 611 | if config.get_last_errno() != config.NO_ERROR: |
188 | - print("Error code = {}".format(config.get_last_errno())) | |
612 | + | |
613 | + print("Error {}. {}".format(config.get_last_errno(),config.get_last_errmsg())) | |
614 | + | |
189 | 615 | else: |
616 | + | |
190 | 617 | # --- Load the configuration file if needed only (i.e. modified) |
191 | 618 | config.load() |
192 | - # --- get the parameter value of <mount1/localization/home> | |
193 | - instanciation = 'mount1' | |
194 | - section = 'localization' | |
195 | - key = 'home' | |
196 | - paramvalue = config.get_paramvalue(instanciation, section, key) | |
197 | - print("paramvalue <{}/{}/{}> = {}".format(instanciation, section, key,paramvalue)) | |
198 | - # | |
199 | - #print("unit_component_params = {}".format(unit_component_params)) | |
200 | - #component = unit_component_params[0] | |
201 | - #params = component['params'] | |
202 | - #print("params = {}".format(params)) | |
619 | + | |
620 | + if config.get_last_errno() != config.NO_ERROR: | |
621 | + | |
622 | + print("Error {}. {}".format(config.get_last_errno(),config.get_last_errmsg())) | |
623 | + | |
624 | + else: | |
625 | + | |
626 | + # --- Get the home of the mount[0] | |
627 | + mount_alias = config.get_aliases('mount')[0] | |
628 | + home = config.get_param(mount_alias,'MountPointing','home') | |
629 | + print("home= {}\n".format(home)) | |
630 | + | |
631 | + # --- Get the serial number of the optics of the channel[0] | |
632 | + channel_alias = config.get_aliases('channel')[0] | |
633 | + optsn = config.get_paramvalue(channel_alias,'optic','serial_number') | |
634 | + print("Serial number {}\n".format(optsn)) | |
635 | + | |
636 | + # --- Get the startmode of the AgentX | |
637 | + agent_alias = 'AgentX' | |
638 | + stmod = config.get_paramvalue(agent_alias,'general','startmode') | |
639 | + print("startmode {}\n".format(stmod)) | |
640 | + | |
641 | + # --- Get all the assembly of this unit[0] (mount + channels) | |
642 | + unit_alias = config.get_aliases('unit')[0] | |
643 | + params = config.get_params(unit_alias) | |
644 | + print("params {} = {}\n".format(unit_alias,params)) | |
645 | + | |
646 | + # --- Get the plan parameters for web pages of the channel[0] | |
647 | + channel_alias = config.get_aliases('channel')[0] | |
648 | + plans = config.get_plan(channel_alias) | |
649 | + print("Plan form = {}\n".format(plans)) | |
650 | + | |
651 | + # --- Get the alias of this computer | |
652 | + print("Alias of this computer = {}\n".format(config.get_computer_alias())) | |
653 | + | |
654 | + # --- Get the password of the database | |
655 | + database_alias = config.get_aliases('database')[0] | |
656 | + paswds = config.get_param(database_alias,'access','pswd') | |
657 | + if paswds.get('unit',None) == 'crypted1': | |
658 | + paswd = config.decode(paswds['value']) | |
659 | + else: | |
660 | + paswd = paswds['value'] | |
661 | + print("db paswd = {}\n".format(paswd)) | |
662 | + | |
203 | 663 | \ No newline at end of file | ... | ... |