Skip to content

Commit bfe79e3

Browse files
authored
Merge pull request #32 from pvlib/examples
Updates of example files
2 parents 07027f1 + 4d60928 commit bfe79e3

10 files changed

+2813
-2441
lines changed
Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,65 @@
1+
# .github/workflows/validate_xml_with_xsd.yml
12
name: Validate PVCollada XML examples
23

34
on:
45
push:
56
paths:
6-
- schema/pvcollada_schema_0.1.xsd
7-
- schema/collada_schema_1_5.xsd
7+
- Examples/**
8+
- schema/**
89
- .github/workflows/validate_xml_with_xsd.py
910
- .github/workflows/validate_xml_with_xsd.yml
1011

11-
- Examples/05 - VerySimpleFixedPVC2_with_electrical_layout_v3.pvc
1212
pull_request:
1313
paths:
14-
- schema/pvcollada_schema_0.1.xsd
15-
- schema/collada_schema_1_5.xsd
14+
- Examples/**
15+
- schema/**
1616
- .github/workflows/validate_xml_with_xsd.py
1717
- .github/workflows/validate_xml_with_xsd.yml
1818

19-
- Examples/05 - VerySimpleFixedPVC2_with_electrical_layout_v3.pvc
2019
workflow_dispatch:
2120

2221
jobs:
22+
discover:
23+
name: Discover *.pv2 example files
24+
runs-on: ubuntu-latest
25+
outputs:
26+
matrix: ${{ steps.build.outputs.matrix }}
27+
steps:
28+
- uses: actions/checkout@v4
29+
- id: build
30+
shell: bash
31+
run: |
32+
python3 - <<'PY' > matrix.json
33+
import json, re, pathlib
34+
root = pathlib.Path("Examples")
35+
pattern = re.compile(r".+\.pv2$", re.IGNORECASE)
36+
files = []
37+
if root.exists():
38+
for p in sorted(root.iterdir()):
39+
if p.is_file() and pattern.match(p.name):
40+
files.append(f"{root}/{p.name}")
41+
print(json.dumps({"xml_doc": files}))
42+
PY
43+
echo "matrix=$(cat matrix.json)" >> "$GITHUB_OUTPUT"
44+
2345
validate-schema:
24-
strategy:
25-
matrix:
26-
xml_doc:
27-
- Examples/05 - VerySimpleFixedPVC2_with_electrical_layout_v3.pvc
2846
name: Validate XML
47+
needs: discover
2948
runs-on: ubuntu-latest
49+
# Skip job cleanly if no files matched (prevents a matrix on an empty list)
50+
if: ${{ fromJSON(needs.discover.outputs.matrix).xml_doc && join(fromJSON(needs.discover.outputs.matrix).xml_doc) != '' }}
51+
strategy:
52+
fail-fast: false
53+
matrix: ${{ fromJSON(needs.discover.outputs.matrix) }}
3054
steps:
3155
- name: Install Python 3.10
3256
uses: actions/setup-python@v5
3357
with:
3458
python-version: "3.10"
59+
3560
- name: Install lxml Python dependency
3661
run: pip3 install lxml==5.3.1
62+
3763
- name: Checkout PVCollada and COLLADA schemas, the validation script, and the XML doc
3864
uses: actions/checkout@v4
3965
with:
@@ -43,6 +69,10 @@ jobs:
4369
.github/workflows/validate_xml_with_xsd.py
4470
${{ matrix.xml_doc }}
4571
sparse-checkout-cone-mode: false
72+
4673
- name: Run validation
4774
working-directory: schema
48-
run: python3 "$GITHUB_WORKSPACE"/.github/workflows/validate_xml_with_xsd.py pvcollada_schema_0.1.xsd "$GITHUB_WORKSPACE"/"${{ matrix.xml_doc }}"
75+
run: |
76+
python3 "$GITHUB_WORKSPACE"/.github/workflows/validate_xml_with_xsd.py \
77+
pvcollada_schema_0.1.xsd \
78+
"$GITHUB_WORKSPACE"/"${{ matrix.xml_doc }}"
Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<COLLADA xmlns:xsd="http://www.w3.org/2001/XMLSchema"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xmlns:pv="http://www.example.com/pvcollada"
5+
version="1.5.0" xmlns="http://www.collada.org/2008/03/COLLADASchema">
6+
<asset>
7+
<contributor>
8+
<author>PVsyst</author>
9+
<comments>First PVC 2.0 sample file : 1 terrain and 3 tables, all based on the same model. No electrical components</comments>
10+
</contributor>
11+
<coverage>
12+
<geographic_location>
13+
<longitude>15.3</longitude>
14+
<latitude>10.1</latitude>
15+
<altitude mode="absolute">150</altitude>
16+
</geographic_location>
17+
</coverage>
18+
<created>2024-06-06T13:32:31Z</created>
19+
<modified>2025-09-16T10:12:18Z</modified>
20+
<unit meter="0.01" name="cm" />
21+
<up_axis>Z_UP</up_axis>
22+
<extra>
23+
<technique profile="PVCollada-2.0">
24+
<!-- software tag -->
25+
<pv:software>
26+
<pv:source>Helios 3D</pv:source>
27+
<pv:target>PVsyst</pv:target>
28+
</pv:software>
29+
<!-- project tag -->
30+
<pv:project>
31+
<pv:name>First example</pv:name>
32+
</pv:project>
33+
<!-- components tag -->
34+
<pv:components>
35+
<!-- List of modules -->
36+
<pv:modules>
37+
<!-- module tag, would usually contain a link to a PAN file or its content
38+
as CDATA -->
39+
<pv:module id="ModuleModel1">
40+
<pv:manufacturer>Generic</pv:manufacturer>
41+
<pv:name>Generic 300W bifacial</pv:name>
42+
<pv:module_type>bifacial</pv:module_type>
43+
<pv:nom_power>300</pv:nom_power>
44+
<pv:length>1992</pv:length>
45+
<pv:width>1000</pv:width>
46+
<pv:depth>6</pv:depth>
47+
</pv:module>
48+
</pv:modules>
49+
</pv:components>
50+
</technique>
51+
</extra>
52+
</asset>
53+
<library_materials>
54+
<material id="Material1" name="Dummy Material">
55+
<instance_effect url="#Material1EffectId" />
56+
</material>
57+
</library_materials>
58+
<library_effects>
59+
<effect id="Material1EffectId" name="Dummy Material Effect">
60+
<profile_COMMON>
61+
<technique sid="standard">
62+
<lambert>
63+
<emission>
64+
<color sid="emission">0.000000 0.000000 0.000000 1.000000</color>
65+
</emission>
66+
<ambient>
67+
<color sid="ambient">0.200000 0.200000 0.200000 1.000000</color>
68+
</ambient>
69+
<diffuse>
70+
<color sid="diffuse">0.250000 0.500000 0.000000 1.000000</color>
71+
</diffuse>
72+
<transparent opaque="RGB_ZERO">
73+
<color sid="transparent">0.000000 0.000000 0.000000 1.000000</color>
74+
</transparent>
75+
<transparency>
76+
<float sid="transparency">0</float>
77+
</transparency>
78+
</lambert>
79+
</technique>
80+
</profile_COMMON>
81+
</effect>
82+
</library_effects>
83+
<library_geometries>
84+
<!-- We define a terrain -->
85+
<geometry id="Terrain1">
86+
<mesh>
87+
<source id="terrain1MeshSource">
88+
<float_array id="terrain1FloatArray" count="12">
89+
2000 -2500 0
90+
-2000 -2500 0
91+
-2000 2500 0
92+
2000 2500 0
93+
</float_array>
94+
<technique_common>
95+
<accessor count="4" source="#terrain1FloatArray" stride="3">
96+
<param name="X" type="float" />
97+
<param name="Y" type="float" />
98+
<param name="Z" type="float" />
99+
</accessor>
100+
</technique_common>
101+
</source>
102+
<vertices id="terrain1VerticesSource">
103+
<input semantic="POSITION" source="#terrain1MeshSource" />
104+
</vertices>
105+
<polylist material="CommonMaterial" count="1">
106+
<input offset="0" semantic="VERTEX" source="#terrain1VerticesSource" />
107+
<vcount>5</vcount>
108+
<p>0 1 2 3 0</p>
109+
</polylist>
110+
</mesh>
111+
<extra>
112+
<technique profile="PVCollada-2.0">
113+
<!-- terrain tag -->
114+
<pv:terrain sid="Terrain">
115+
<pv:vertex_count>4</pv:vertex_count>
116+
<pv:triangle_count>2</pv:triangle_count>
117+
<pv:bounding_box_min>-10.0 -20.0 -30.0</pv:bounding_box_min>
118+
<pv:bounding_box_max>10.0 20.0 30.0</pv:bounding_box_max>
119+
</pv:terrain>
120+
</technique>
121+
</extra>
122+
</geometry>
123+
<!-- We define the model for a rack -->
124+
<geometry id="Rack1Model">
125+
<mesh>
126+
<source id="rack1MeshSource">
127+
<float_array id="rack1FloatArray" count="12">
128+
0 0 0
129+
-1500 0 0
130+
-1500 -500 200
131+
0 -500 200
132+
</float_array>
133+
<technique_common>
134+
<accessor count="4" source="#rack1FloatArray" stride="3">
135+
<param name="X" type="float" />
136+
<param name="Y" type="float" />
137+
<param name="Z" type="float" />
138+
</accessor>
139+
</technique_common>
140+
</source>
141+
<vertices id="rack1VerticesSource">
142+
<input semantic="POSITION" source="#rack1MeshSource" />
143+
</vertices>
144+
<triangles count="2" material="CommonMaterial">
145+
<input offset="0" semantic="VERTEX" source="#rack1VerticesSource" />
146+
<p>3 1 2 1 3 0</p>
147+
</triangles>
148+
</mesh>
149+
<extra>
150+
<technique profile="PVCollada-2.0">
151+
<!-- rack tag -->
152+
<pv:rack>
153+
<pv:rack_type>fixed_tilt</pv:rack_type>
154+
<pv:module_rows>1</pv:module_rows>
155+
<pv:module_columns>4</pv:module_columns>
156+
<pv:tilt>0</pv:tilt>
157+
<pv:azimuth>0</pv:azimuth>
158+
<pv:module_id>ModuleModel1</pv:module_id>
159+
</pv:rack>
160+
</technique>
161+
</extra>
162+
</geometry>
163+
</library_geometries>
164+
<library_nodes>
165+
<!-- We define the model for a table with 1 rack -->
166+
<node id="TableModel1">
167+
<!-- We instantiate the rack model -->
168+
<instance_geometry url="#Rack1Model">
169+
<bind_material>
170+
<technique_common>
171+
<instance_material symbol="CommonMaterial" target="#Material1" />
172+
</technique_common>
173+
</bind_material>
174+
<extra>
175+
<technique profile="PVCollada-2.0">
176+
<!-- instance_rack tag -->
177+
<pv:instance_rack id="rackInstance1" />
178+
</technique>
179+
</extra>
180+
</instance_geometry>
181+
<extra>
182+
<technique profile="PVCollada-2.0">
183+
<!-- table tag -->
184+
<pv:table>
185+
<pv:type>fixed</pv:type>
186+
</pv:table>
187+
</technique>
188+
</extra>
189+
</node>
190+
</library_nodes>
191+
<library_visual_scenes>
192+
<visual_scene id="VisualSceneNode" name="Visual Scene">
193+
<!-- We instantiate the terrain -->
194+
<node id="TerrainNode1" name="TerrainNode1" sid="TerrainNode1">
195+
<instance_geometry url="#Terrain1">
196+
<extra>
197+
<technique profile="PVCollada-2.0">
198+
<!-- instance_terrain tag, might not have any child tags at the start but can be useful in the future -->
199+
<pv:instance_terrain />
200+
</technique>
201+
</extra>
202+
</instance_geometry>
203+
</node>
204+
<!-- We instantiate a first fixed tilt table, without any transformation -->
205+
<node id="PVnode1" name="PVnode1" sid="PVnode1">
206+
<instance_node url="#TableModel1">
207+
<extra>
208+
<technique profile="PVCollada-2.0">
209+
<!-- instance_table tag -->
210+
<pv:instance_table>
211+
<pv:instance_racks_array>
212+
<pv:instance_rack_ref id="rackId1" url="#rackInstance1" />
213+
</pv:instance_racks_array>
214+
</pv:instance_table>
215+
</technique>
216+
</extra>
217+
</instance_node>
218+
</node>
219+
<!-- We instantiate a second fixed tilt table (with a translation) -->
220+
<node id="PVnode2" name="PVnode2" sid="PVnode2">
221+
<translate>0 -800 0</translate>
222+
<instance_node url="#TableModel1">
223+
<extra>
224+
<technique profile="PVCollada-2.0">
225+
<!-- instance_table tag -->
226+
<pv:instance_table>
227+
<pv:instance_racks_array>
228+
<pv:instance_rack_ref id="rackId2" url="#rackInstance1" />
229+
</pv:instance_racks_array>
230+
</pv:instance_table>
231+
</technique>
232+
</extra>
233+
</instance_node>
234+
</node>
235+
<!-- We instantiate a third fixed tilt table (with another translation) -->
236+
<node id="PVnode3" name="PVnode3" sid="PVnode3">
237+
<translate>0 -1600 0</translate>
238+
<instance_node url="#TableModel1">
239+
<extra>
240+
<technique profile="PVCollada-2.0">
241+
<!-- instance_table tag -->
242+
<pv:instance_table>
243+
<pv:instance_racks_array>
244+
<pv:instance_rack_ref id="rackId3" url="#rackInstance1" />
245+
</pv:instance_racks_array>
246+
</pv:instance_table>
247+
</technique>
248+
</extra>
249+
</instance_node>
250+
</node>
251+
</visual_scene>
252+
</library_visual_scenes>
253+
<scene>
254+
<instance_visual_scene url="#VisualSceneNode" />
255+
</scene>
256+
</COLLADA>

0 commit comments

Comments
 (0)