Merge branch 'snotel-hn24'
[infoex-autowx.git] / README.md
1 InfoEx AutoWx (IEAW)
2 =============
3
4 This program fetches data from an NRCS SNOTEL or MesoWest station, or
5 your own custom data source, and pushes it into the InfoEx system using
6 the new automated weather system implementation.
7
8 Licensed under the ISC license (see file: LICENSE).
9
10 Disclaimer
11 ----------
12
13 Your usage of the NRCS, MesoWest, and/or InfoEx systems is bound by
14 their respective terms and this software makes no attempt or claim to
15 abide by any such terms.
16
17 Installation
18 ------------
19
20 It's recommended to use venv and pip with this program. Here's a typical
21 sequence of commands for a new setup:
22
23 `$ cd /path/to/src`
24 `$ python3 -m venv env`
25 `$ . env/bin/activate`
26 `$ pip install -r requirements.txt`
27
28 How to use it
29 -------------
30
31 This program is designed to be run from the command line (or via
32 cron(8)) and administered via a simple, concise configuration file.
33
34 This design allows you to run a separate program instance for each NRCS
35 or MesoWest weather station from which you'd like to automate the
36 importation of data into your InfoEx subscriber account.
37
38 To get started, copy the included example config file
39 (`config.ini.example` in the root source directoy) and modify the values
40 for your own use.
41
42 To run ad-hoc (be sure to activate the virtual environment, as detailed in the
43 Installation section):
44
45 `./infoex-autowx.py --config path/to/config-file.ini [--dry-run] [--log-level debug|info|warning]`
46
47 **NOTE: Specifying --dry-run will not clean up the generated CSV file.**
48 This is so that you can more easily debug any issues that arise in the
49 setup process.
50
51 You can also specify `--log-level` as debug, info, warning. The
52 log messages produced by the program will try to be logged to journald,
53 but if that's not available, they will be printed to stdout. This output
54 can be helpful early on in the setup process.
55
56 Automation
57 ----------
58
59 Here's an example of a crontab(5) with two SNOTEL sites, each of which
60 will run once per hour (note that this will activate the virtual environment
61 created earlier):
62
63 `2 * * * * /usr/bin/env bash -c 'cd /home/user/infoex-autowx && source env/bin/activate && ./infoex-autowx.py --config laurance-lake.ini'`
64 `4 * * * * /usr/bin/env bash -c 'cd /home/user/infoex-autowx && source env/bin/activate && ./infoex-autowx.py --config mud-ridge.ini'`
65
66 Configuration File
67 ------------------
68
69 The configuration file is separated into two parts, the [station]
70 portion, and the [infoex] portion.
71
72 The [station] values describe which weather station's data you're after.
73 See the next section in this README for instructions on obtaining these
74 values.
75
76 The [infoex] values describe your credentials for the InfoEx automated
77 weather station FTP server and other InfoEx-related configuration
78 options.
79
80 `[station]`
81 `type = # mesowest, nrcs, or python #`
82 `token = # MesoWest API token -- only applies when type is mesowest #`
83 `station_id = # the NRCS/MesoWest identifier for a particular station #`
84 `desired_data = # a comma-delimited list of fields you're interested in #`
85 `units = # either english or metric -- only applies when type is mesowest #`
86 `tz = # any entry from the Olson tz database e.g. America/Denver #`
87 `path = # the filesystem path to the Python program -- only applies when type is python #`
88 `wind_mode = # normal or average -- only applies when type is mesowest #`
89 `hn24 = # true or false -- only applies when type is mesowest #`
90
91 `[infoex]`
92 `host = # InfoEx FTP host address #`
93 `uuid = # InfoEx-supplied UUID #`
94 `api_key = # InfoEx-supplied API Key #`
95 `csv_filename = # arbitrary name of the file that will be uploaded to InfoEx #`
96 `location_uuid = # the UUID used by InfoEx to identify your automated Wx site #`
97
98 Finding your NRCS `station` values
99 ----------------------------------
100
101 To complete the [station] configuration section for an NRCS station, you
102 must fill in the attributes of the NRCS SNOTEL site from which you want
103 to import data.
104
105 Here are the steps to do that:
106
107 1. Find your station by clicking through this website:
108
109 https://www.wcc.nrcs.usda.gov/snow/sntllist.html
110
111 Or by using the interactive map:
112
113 https://www.nrcs.usda.gov/wps/portal/wcc/home/quicklinks/imap
114
115 2. Once you've found your station, look for the "Station ID" (a 3- or
116 4-digit number).
117
118 3. Combine your Station ID, state abbreviation, and the network type
119 "SNTL" to get your NRCS station triplet (`station_id`, in the
120 configuration file). For example:
121
122 655:OR:SNTL
123
124 would represent the Mud Ridge station (Station ID 655) in the state
125 of Oregon (OR). SNTL just represents that the station is in the
126 SNOTEL network and is used internally by NRCS.
127
128 Once you have your station ID, fill in the field in your configuration
129 file. Now you must select which data you'd like to pull from NRCS to
130 push into InfoEx.
131
132 For that, visit the NRCS web service:
133
134 https://wcc.sc.egov.usda.gov/awdbWebService/webservice/testwebservice.jsf?webserviceName=/awdbWebService
135
136 Click "getElements" on the left, and then click, "Test Operation." This
137 will return a long list of elements to your web browser from which you
138 can choose. Each returned element has its identifier and a description.
139
140 Once you've chosen your elements, combine all of their respective
141 "elementCd" values into a comma-delimited string and put that into your
142 configuration file as the `desired_data` value.
143
144 A complete [station] section example:
145
146 `[station]`
147 `type = nrcs`
148 `station_id = 655:OR:SNTL`
149 `desired_data = TOBS,PREC`
150
151 indicates that I'd like to import "AIR TEMPERATURE OBSERVED" and
152 "PRECIPITATION ACCUMULATION" from the NRCS SNOTEL site at Mud Ridge, OR,
153 into InfoEx.
154
155 Finding your MesoWest `station` values
156 --------------------------------------
157
158 MesoWest has great documentation which can be found here:
159
160 https://developers.synopticdata.com/mesonet/v2/getting-started/
161
162 To complete the [station] configuration section for a MesoWest station,
163 you must fill in the attributes of the MesoWest station ID from which
164 you want to import data. Here are the steps to do that:
165
166 1. Firstly, get set up with MesoWest's API by going to the above
167 'Getting Started' link. Once you're set up, you can copy a token from
168 the MesoWest web portal into your configuration file's `token` value.
169
170 2. Next, you will want to find the Station ID for the MesoWest weather
171 station of interest and copy it to the `station_id` value.
172
173 3. Finally, you must choose what data types you want to push into
174 InfoEx and compile them into a comma-separated list. MesoWest refers
175 to these as 'field names' or 'station variables' and a list is
176 available here:
177
178 https://developers.synopticdata.com/about/station-variables/
179
180 The MesoWest API supports on-the-fly unit conversion. If desired, that
181 can be specified to infoex-autowx via the configuration option `units`.
182 This can be either 'english' or 'metric', with 'english' meaning
183 imperial units as used in the United States.
184
185 A complete [station] section example:
186
187 `[station]`
188 `type = mesowest`
189 `token = # token id copied from MesoWest web account #`
190 `station_id = OD110`
191 `desired_data = air_temp,snow_depth`
192 `units = english`
193
194 indicates that I'd like to import "Temperature" and "Precipitation
195 accumulated" from the MesoWest station at Santiam Pass, OR, into InfoEx,
196 and that I want that data in imperial units.
197
198 Three- versus 24-hour ranges
199 ----------------------------
200
201 By default, this program will fetch three hours of data from the
202 provider. This way, if the most recent record has any missing data, it
203 can examine the two hours prior, using whatever data it can find.
204
205 There are two features which will cause the program to expand the time
206 range of fetched data from three to 24 hours. Please be aware of this
207 expansion as it may cause a rise in data/API usage.
208
209 **NOTE: Only MesoWest stations have the benefit of wind averaging and
210 HN24 calculation at this time, because generally NRCS SNOTEL
211 stations do not provide wind data. HN24 support for NRCS SNOTEL
212 is planned.
213
214 ### Wind mode
215 If you go to submit a Wx observation in InfoEx at e.g. 05:05, and have
216 so configured InfoEx, it will take the wind speed, wind gust speed, and
217 wind direction, from that hour and auto-fill it for the observation.
218
219 Some operations may find it more important to know the averages for
220 those values over the prior 24 hour period. Setting `wind_mode` to
221 `average` will enable that.
222
223 ### HN24
224 As most stations do not provide HN24 on their own, this program provides
225 a configuration option for calculating this. Simply add `hn24 = true` to
226 the configuration file.
227
228 *NOTE: This is its own configuration option, rather than a new value for
229 desired_data, because it's not technically provided by MesoWest
230 or NRCS SNOTEL.*
231
232 Custom weather station support
233 ------------------------------
234
235 This program supports custom weather station data by allowing the user
236 to specify the path to an external Python program. The external Python
237 program should emit its data in the form expected by infoex-autowx.
238
239 This is a powerful feature which enables the user to upload data from
240 any source imaginable into InfoEx. Common examples are a local database
241 or a remote web page which requires some custom parsing.
242
243 Please see the program located at examples/custom-wx.example.py for a
244 complete description of what's required.
245
246 A note on time zones
247 --------------------
248
249 This program is aware of time zones via the pytz library. The way in
250 which NRCS and MesoWest deal with time zones differs as follows:
251
252 NRCS expects the request to come in the appropriate time zone, and the
253 data retrieved will be in the same time zone (no transformation
254 required before sending to InfoEx).
255
256 MesoWest expects the request to come in UTC, and the data retrieved will
257 be in the same time zone (transformation from UTC to the desired time
258 zone is required before sending to InfoEx).
259
260 As long as you specify the correct timezone in your configuration file,
261 all will be handled correctly. The list of time zones comes from the
262 Olson tz database. See that for more information.
263
264 If you specify an invalid time zone, the program will exit and inform
265 you of such.
266
267 Lastly, InfoEx itself is timezone aware. If you notice that the data
268 which makes it into your operation is inaccurate, start your
269 investigation with time zone-related issues and move on only once you've
270 ruled this out as a cause of the inaccuracy.
271
272 Unit conversions
273 ----------------
274
275 Desired units may be specified in the configuration file.
276
277 For MesoWest, the desired unit will be passed along in the API request
278 and the conversion will take place through the MesoWest/Synoptic API.
279
280 For NRCS, this program will do the conversion manually, as NRCS does not
281 permit specifying the desired unit.
282
283 A note on supported measurements
284 --------------------------------
285
286 While this program supports several measurements, and will faithfully
287 request all of the ones you specify (provided they're supported), the
288 weather station may not record them. In this case, the data will simply
289 be ignored (i.e. it will NOT log "0" when there's no measurement
290 available).
291
292 InfoEx provides a mechanism for inspecting your automated weather
293 station data, so use that after setting this program up and compare it
294 with the data you see in your web browser.
295
296 Here's the list of measurements currently supported:
297
298 **NRCS:**
299 PREC
300 TOBS
301 SNWD
302 PRES
303 RHUM
304 WSPD
305 WDIR
306
307 **MesoWest:**
308 precip\_accum
309 air\_temp
310 snow\_depth
311 pressure
312 relative\_humidity
313 wind\_speed
314 wind\_direction
315 wind\_gust
316
317 **Custom Wx program**
318 *infoex-autowx expects a custom Wx data provider to provide at least one
319 of the following:*
320 precipitationGauge
321 tempPres
322 tempMaxHour
323 tempMinHour
324 hS
325 baro
326 rH
327 windSpeedNum
328 windDirectionNum
329 windGustSpeedNum
330
331 Version history
332 ---------------
333
334 - 3.4.0 (Mar 2022)
335
336 Implement HN24 for NRCS SNOTEL stations.
337
338 - 3.3.1 (Jan 2022)
339
340 Fix bug in which HN24 values under certain circumstances could be
341 inaccurate.
342
343 - 3.3.0 (Nov 2021)
344
345 Implement wind averaging and auto-calculation of HN24. These are
346 opt-in via two new configuration options.
347
348 - 3.2.4 (Mar 2021)
349
350 Fix a small bug that allowed MesoWest HS values to flow through in
351 millimeters when metric was the specified unit. MesoWest metric HS
352 values are now correctly in centimeters.
353
354 - 3.2.3 (Feb 2021)
355
356 Fix a small bug that allowed a TypeError to be raised with some
357 regularity.
358
359 - 3.2.2 (Feb 2021)
360
361 Various small fixes.
362
363 - Round precipitation accumulation values to 2 decimal places.
364 - Catch requests' ConnectionException.
365 - Improve logging output when using stdout.
366
367 - 3.2.1 (Feb 2021)
368
369 Fix config validation bug with units and custom Python program.
370
371 - 3.2.0 (Feb 2021)
372
373 Implement NRCS unit conversion.
374
375 - 3.1.1 (Feb 2021)
376
377 Fix relative humidity rounding.
378
379 - 3.1.0 (Jan 2021)
380
381 Implement time zone support.
382
383 - 3.0.2 (Jan 2021)
384
385 Use UTC time when asking MesoWest for data.
386
387 - 3.0.1 (Jan 2021)
388
389 General fixes.
390
391 - MesoWest wind data (speed and gust speed) units are now transformed
392 from their origin unit (meters per second) to the unit expected by
393 InfoEx (miles per hour).
394
395 - Relative humidity is now rounded to one decimal place, preventing
396 InfoEx from reddening the auto-filled value.
397
398 - 3.0.0 (Nov 2020)
399
400 Implement Custom Wx data providers.
401
402 This release enables the user to write their own Python programs and
403 specify them to infoex-autowx as a data provider.
404
405 This in turn enables the user to pull data from e.g. a local database
406 or an HTML page and push it into their InfoEx auto station data,
407 limited only by the imagination.
408
409 - 2.2.0 (Nov 2020)
410
411 Add support for Tmin/Tmax values (directly from MesoWest/NRCS).
412
413 - 2.1.0 (Nov 2020)
414
415 Adjust precision of certain values before sending them to InfoEx.
416
417 - 2.0.2 (Jul 2020)
418
419 Fix issues shown by pylint(1).
420
421 - 2.0.1 (Jul 2020)
422
423 Major restructuring, but nothing which should impact the end user.
424
425 - Took the monolithic main () routine and broke it out into logical
426 components.
427 - Improved the names of variables.
428
429 - 2.0.0 (Jul 2020)
430
431 Implement MesoWest integration.
432
433 This release also makes significant changes to the configuration file,
434 hence the major version bump. Such changes are not taken lightly but
435 given the desire to support multiple data sources, were necessary.
436
437 Other minor changes include:
438
439 - New switches: --log-level and --version.
440 - Better documentation.
441 - Expanded supported measurement types (from three to eight, in number).
442
443 - 1.0.0 (Jun 2020)
444
445 First released version. Cleaned up the program and design.
446 Implemented configuration file, added LICENSE, README, docs, etc.
447
448 - 0.8.0 (Apr 2020)
449
450 First finished (unreleased) version.
451
452 - pre-0.8.0 (Apr 2020)
453
454 First (private) finished implementation with successful importation of
455 NRCS data into InfoEx.