Deth

Fitness and everything else

Zola Template For My Ambient Weather Station Data

One of the first things I had to do when I decided I wanted to switch from Hugo to Zola was figure out if I could make it work with my PWS data. Obviously, if it worked with Hugo, I didn’t want to lose that functionality by switching. Having the data here was crucial to me, and not having the ability to do so was not an option for me.

I studied the Tera templating language a bit and managed to get it working in a day or two. Of course, over time, I’ve tweaked it and cleaned it up a bit. Over the past two days, I refactored it to take away the big outer loops and made assumptions based on the line counts and consistency of how the CSV files have been over the past three years. That seems to have sped it up a good bit.

I will admit that writing and rewriting this template went a lot faster than the original one did for Hugo. It’s a combination of the Tera language being much more intuitive to me, and the fact that the hard part of solving the problem in the first place is already done. This time, it was more a case of reimplementing it than writing it.

1,Date,Outdoor Temperature,Feels Like,Dew Point
2Average,2022-01-14,33.7,33.7,28.8
3High,2022-01-14,35.6,35.6,29.9
4High Datetime,2022-01-14,2022-01-14T04:57:00-05:00,2022-01-14T04:57:00-05:00,2022-01-14T04:41:00-05:00,
5Low,2022-01-14,32,30.2,28
6Low Datetime,2022-01-14,2022-01-14T02:21:00-05:00,2022-01-14T02:12:00-05:00,2022-01-14T00:13:00-05:00,2022-01-14T00:00:00-05:0

What I wound up doing was creating a variable for each line that I wanted. The highs, times, averages, and so forth for today and yesterday are all I wanted. The variable is just an array of that line broken up into fields. Using this, I could just pull the field I wanted from the array.

I could make the assumption that the first line is the newest. Since Ambient hasn’t changed that in nearly three years, I’ve used the CSV files, and I think it’s pretty safe that it’s not going to change. If anything, I see them dropping the CSV in favor of using only the JSON files available with the API. That allows me to just do some math using day numbers to figure out how many days from now I need, then multiply that by 5 to get the line number that I want.

1{%- extends "base.html" -%}
2{%- block head -%}
3{%- set Type = "page" -%}
4{%- if page.higher -%}
5{%- set Higher = page.higher -%}
6{%- set Prev = page.higher.permalink -%}
7{%- set Yesterday = Higher.date -%}
8{%- endif %}
9{%- if page.lower -%}
10{% set Lower = page.lower -%}
11{% set Next = page.lower.permalink -%}
12{%- endif -%}
13
14{%- set Date = page.date | date(format="%A, %B, %e %Y", timezone="America/New_York") -%}
15{%- set_global Title = "Mount Joy, Pennsylvania's Weather For "~Date -%}
16{%- set_global Description = "Here is the historical weather for Mount Joy , Pennsylvania on "~Date -%}
17
18
19{%- endblock -%}
20{%- block content -%}
21<article class="content">
22<h1 id="top" class="title"> {{- Title -}} </h1>
23{%- set TheDay = page.day -1 -%}
24{%- set T = page.date | date(format="%s") | int -%}
25{%- set T = T - 86400 -%}
26{#%- set_global Yesterday = T | date -%#}
27{%- set T = page.date | date(format="%y") | int -%}
28{%- set T = T - 1 -%}
29{%- set_global DaysSinceLastRain = 0 -%}
30{%- set_global LastHighDailyRain = 0 -%}
31{%- set_global DaysSinceLastLightning = 0 -%}
32{%- set_global LastHighLightning = 0 -%}
33{%- set TestYear = T | date(format="%Y") -%}
34{%- set_global ThisYear = page.date | date(format="%Y") -%}
35{%- if not TestYear == ThisYear and not ThisYear == "2021" -%}
36{%- set_global LastYear = TestYear -%}
37{%- endif -%}
38{%- set_global Current = 0 -%}
39{%- set_global HasWxData = False -%}
40
41{%- set_global Year = page.year -%}
42{%- set File = "/WxData/wx" ~ Year ~ ".csv" -%}
43{%- set data = load_data(path=File) -%}
44 {%- if LastYear -%}
45 {%- set TheYear = page.year - 1 -%}
46 {%- set File = "/WxData/wx" ~ TheYear ~ ".csv" -%}
47{%- set Past = load_data(path=File) -%}
48 {% endif %}
49{% for header in data.headers -%}
50 {%- set_global HasYesterday = false -%}
51
52{%- if header is starting_with("Outdoor Temperature") -%}
53{%- set_global Temperature = loop.index0 -%}
54{%- continue -%}
55{%- elif header is starting_with( "Feels Like") -%}
56{%- set_global FeelsLike = loop.index0 -%}
57{%- continue -%}
58{% elif header is starting_with("Dew Point") -%}
59{%- set_global DewPoint = loop.index0 -%}
60{%- continue -%}
61 {%- elif header is starting_with("Outdoor Humidity") %}
62 {%- set_global Humidity = loop.index0 -%}
63{%- continue -%}
64 {%- elif header is starting_with ("Humidity") -%}
65{%- set_global Humidity = loop.index0 -%}
66{%- continue -%}
67{% elif header is starting_with( "Ultra") -%}
68{%- set_global UVRadiation = loop.index0 -%}
69{%- continue -%}
70{%- elif header is starting_with("Solar") -%}
71{%- set_global SolarRadiation = loop.index0 -%}
72{%- continue -%}
73{%- elif header is starting_with("Lightning strikes per day") -%}
74{%- set_global StrikesPerDay = loop.index0 -%}
75{%- continue -%}
76{% elif header is starting_with( "Lightning strikes per hour") -%}
77{%- set_global StrikesPerHour = loop.index0 -%}
78{%- continue -%}
79{%- elif header is starting_with( "Wind Speed") -%}
80{%- set_global Wind = loop.index0 -%}
81{%- continue -%}
82{%- elif header is starting_with( "Wind Gust" )-%}
83{%- set_global WindGust = loop.index0 -%}
84{%- continue -%}
85{%- elif header is starting_with( "Relative Pressure") -%}
86{%- set_global Pressure = loop.index0 -%}
87{%- continue -%}
88{%- elif header is starting_with( "Avg Wind Direction") -%}
89{%- set_global WindDirection = loop.index0 -%}
90{%- continue -%}
91{%- elif header is starting_with( "Daily") -%}
92{%- set_global DailyRain = loop.index0 -%}
93{%- continue -%}
94{%- elif header is starting_with( "Hourly")-%}
95{%- set_global MaxHourly = loop.index0 -%}
96{%- continue -%}
97{%- elif header is starting_with( "Event") -%}
98{%- set_global EventRain = loop.index0 -%}
99{%- continue -%}
100{%- elif header is starting_with( "Weekly") -%}
101{%- set_global WeeklyRain = loop.index0 -%}
102{%- continue -%}
103{%- elif header is starting_with( "Monthly") -%}
104{%- set_global MonthlyRain = loop.index0 -%}
105{%- continue -%}
106{%- elif header is starting_with( "Yearly") -%}
107 {%- set_global YearlyRain = loop.index0 -%}
108{%- continue -%} {% endif %}
109{%- endfor -%}
110{% set FirstLine = data.records[0][1] | date(format="%-j") | int %}
111{% set TodaysDayNumber = page.date | date(format="%-j") | int %}
112{#%- set TodaysDate = TEST[1] | date(format="%m-%d-%Y") -%#}
113{% if FirstLine == TodaysDayNumber %}
114{%- set_global HasWxData = True -%}
115
116{%- set_global TodaysAverage = data.records[0] -%}
117{%- set TheHighs = 1 -%}
118{%- set_global TodaysHigh = data.records[TheHighs] -%}
119{%- set TheHighsTime = 2 -%}
120
121{%- set_global TodaysHighTime = data.records[TheHighsTime] -%}
122{%- set TheLows = 3 -%}
123{%- set_global TodaysLow = data.records[TheLows] -%}
124{%- set TheLowsTime = 4 -%}
125{%- set TodaysLowTime = data.records[TheLowsTime] -%}
126{% else %}
127{%- set_global HasWxData = True -%}
128
129{% set TheLine = (FirstLine - TodaysDayNumber) *5 -%}
130{%- set_global TodaysAverage = data.records[TheLine] -%}
131{%- set TheHighs = 1 + TheLine -%}
132{%- set_global TodaysHigh = data.records[TheHighs] -%}
133{%- set TheHighsTime = 2 + TheLine-%}
134
135{%- set_global TodaysHighTime = data.records[TheHighsTime] -%}
136{%- set TheLows = 3 + TheLine -%}
137{%- set_global TodaysLow = data.records[TheLows] -%}
138{%- set TheLows = 4 +TheLine -%}
139{%- set TodaysLowTime = data.records[TheLows] -%}
140{% endif %}
141{% set TheTest = (TodaysDayNumber *5) - 5%}
142{% if TodaysDayNumber == 1 -%}
143{% if Past -%}
144
145{%- set_global HasYesterday = true -%}
146
147{%- set_global HasWxData = True -%}
148{%- set YesterdaysAverageNumber = 0 %}
149{%- set_global YesterdaysAverage = Past.records[YesterdaysAverageNumber] -%}
150{%- set TheHighs =YesterdaysAverageNumber + 1 -%}
151{%- set_global YesterdaysHigh = Past.records[TheHighs] -%}
152{%- set TheHighsTime = YesterdaysAverageNumber+ 2 -%}
153
154{%- set_global YesterdaysHighTime = Past.records[TheHighsTime] -%}
155{%- set TheLows = YesterdaysAverageNumber + 3 -%}
156{%- set_global YesterdaysLow = Past.records[TheLows] -%}
157{%- set TheLowsTime = YesterdaysAverageNumber + 4 -%}
158{%- set YesterdaysLowTime = Past.records[TheLowsTime] -%}
159{% else %}
160
161{%- endif -%} {%- else %}
162
163{%- set_global HasYesterday = true -%}
164
165{%- set_global HasWxData = True -%}
166{%- set YesterdaysAverageNumber = (FirstLine - TodaysDayNumber +1 ) *5 -%}
167{% if data.records[YesterdaysAverageNumber] -%}
168{%- set_global YesterdaysAverage = data.records[YesterdaysAverageNumber] -%}
169{%- set TheHighs =YesterdaysAverageNumber + 1 -%}
170{%- set_global YesterdaysHigh = data.records[TheHighs] -%}
171{%- set TheHighsTime = YesterdaysAverageNumber+ 2 -%}
172
173{%- set_global YesterdaysHighTime = data.records[TheHighsTime] -%}
174{%- set TheLows = YesterdaysAverageNumber + 3 -%}
175{%- set_global YesterdaysLow = data.records[TheLows] -%}
176{%- set TheLowsTime = YesterdaysAverageNumber + 4 -%}
177{%- set YesterdaysLowTime = data.records[TheLowsTime] -%}
178{% endif %}
179{%- endif %}
180
181{%- if TodaysHigh[StrikesPerDay] == "0" -%}
182{%- set Current = (FirstLine - TodaysDayNumber ) *5 +1-%}
183{%- set Length = data.records | length -%}
184{%- for I in range(start=Current, end=Length, step_by=5) -%}
185{%- set TEST = data.records[I] -%}
186{%- set_global TestDate = TEST[1] | date(format="%-j") | int -%}
187{%- if not TEST[StrikesPerDay] == "0" -%}
188{%- set Temp = TEST[1] | date(format="%m-%d-%Y") -%}
189{%- set ThePath = "wx/history/"~Year~"/"~ Temp~".md" -%}
190{%- set_global LastHighLightningPage = get_page(path=ThePath) -%}
191{%- set_global DaysSinceLastLightning = loop.index0 -%}
192{%- set_global LastHighLightning = TEST[StrikesPerDay] -%}
193{%- break -%}
194{%- else -%}
195{%- set_global DaysSinceLastLightning = loop.index0 -%}
196{%- if loop.last and Past.headers -%}
197{%- set YearChanged = true -%}
198{%- set_global DaysSinceLastLightning = loop.index0 -%}
199{%- set_global TheStrikesPerDay = 0 -%}
200{%- for header in Past.headers -%}
201{%- if header is starting_with("Lightning strikes per day") -%}
202{%- set_global TheStrikesPerDay = loop.index0 -%}
203{%- break -%} {% endif %}
204{%- endfor -%}
205
206{%- set_global TheLength = Past.records | length -%}
207{%- for N in range(start=1, end=TheLength, step_by=5) -%}
208{%- set Temp = Past.records[N][TheStrikesPerDay] -%}
209{%- if not Temp == 0 or not Temp == "0" -%}
210{%- set_global DaysSinceLastLightning = loop.index + DaysSinceLastLightning -%}
211{%- set TheTemp = Past.records[N][1] | date(format="%m-%d-%Y") -%}
212{% set Year = Past.records[N][1] | date(format="%Y") %}
213{%- set ThePath = "wx/history/"~Year~"/"~ TheTemp~".md" -%}
214{%- set_global LastHighLightningPage = get_page(path=ThePath) -%}
215{%- set_global LastHighLightning = Past.records[N][TheStrikesPerDay] -%}
216{%- break -%}
217{%- endif -%} {# End Last year #}
218{%- endfor -%}
219{%- endif -%}
220{%- endif -%}
221
222{%- endfor -%}
223{%- endif -%}
224
225
226{%- if TodaysHigh[DailyRain] == "0" -%}
227{%- set Current = (FirstLine - TodaysDayNumber ) *5 -%}
228
229
230{%- set Length = data.records | length -%}
231
232{%- for I in range(start=Current, end=Length, step_by=5) -%}
233{%- set TEST = data.records[I] -%}
234{% set_global TestDate = TEST[1] | date(format="%-j") | int %}
235{%- set TheTemp = data.records[I][1] | date(format="%m-%d-%Y") -%}
236{% set Year = data.records[I][1] | date(format="%Y") %}
237{%- set ThePath = "wx/history/"~Year~"/"~ TheTemp~".md" -%}
238{% set_global LastDayWithRainPage = get_page(path=ThePath) %}
239
240{%- if not TEST[DailyRain] == "0" -%}
241{%- set_global DaysSinceLastRain = loop.index0 -%}
242{%- set_global LastHighDailyRain = TEST[DailyRain] -%}
243{%- break -%}
244{%- else -%}
245{%- set_global DaysSinceLastRain = loop.index0 -%}
246{%- if loop.last and Past.headers %} {% set YearChanged = true -%}
247{%- set_global DaysSinceLastRain = loop.index0 -%}
248{%- set_global LastHighDailyRain = 0 -%}
249{# Last Year's Headers #}
250
251{% for header in Past.headers -%}
252{%- if header is starting_with("Daily Rain") -%}
253{%- set_global LastHighDailyRain = loop.index0 -%}
254{%- break -%} {% endif %}
255{%- endfor -%}
256{# Last Year's Headers #}
257{%- set_global TheLength = Past.records | length -%}
258{# Last Year #}
259{%- for N in range(start=1, end=TheLength, step_by=5) -%}
260{%- set Temp = Past.records[N][LastHighDailyRain] -%}
261{%- if not Temp == 0 or not Temp == "0" -%}
262{%- set TheTemp = Past.records[N][1] | date(format="%m-%d-%Y") -%}
263{%- set Year = Past.records[N][1] | date(format="%Y") -%}
264{%- set ThePath = "wx/history/"~Year~"/"~ TheTemp~".md" -%}
265{% set_global LastDayWithRainPage = get_page(path=ThePath) %}
266
267{%- set_global DaysSinceLastRain = loop.index + DaysSinceLastRain -%}
268{%- set_global LastHighDailyRain = Past.records[N][LastHighDailyRain] -%}
269{%- break -%}
270{%- endif -%} {# End Last year #}
271{%- endfor -%}
272{# End Last Year #}
273
274{% endif %}
275{% endif %}
276{% endfor %}
277
278{% endif %}
279
280
281
282{{- page.content | safe -}}
283{%- if HasWxData -%}
284{%- include "Wx/Temperature.html" -%}
285{%- include "Wx/Humidity.html" -%}
286{%- include "Wx/Pressure.html" -%}
287{%- include "Wx/Solar.html" -%}
288{%- include "Wx/Wind.html" -%}
289{%- include "Wx/Rain.html" -%}
290{%-include "Wx/Lightning.html" -%}
291
292{%- else -%}
293No Weather data in CSV {{ File }} for {{ Date }}
294{%- endif -%}
295 </article>
296
297```
298
299Please don't hesitate to use this if it will help you, and modify it as you need to make it work for your requirements.