### Navigation

- index
- modules |
- next |
- previous |
- pywws 14.06.dev1238 documentation »
- Python programs and modules »

# pywws.Template

Create text data file based on a template

    usage: python -m pywws.Template [options] data_dir template_file output_file
    options are:
     --help    display this help
    data_dir is the root directory of the weather data
    template_file is the template text source file
    output_file is the name of the text file to be created

## Introduction

This is probably the most difficult to use module in the weather station software collection. It generates text files based on a “template” file plus the raw, hourly, daily & monthly weather station data. The template processing goes beyond simple substitution of values to include loops, jumps forwards or backwards in the data, processing of the data and substitution of missing values.

A template file can be any sort of text file (plain text, xml, html, etc.) to which “processing instructions” have been added. These processing instructions are delimited by hash (‘#’) characters. They are not copied to the output, but cause something else to happen: either a data value is inserted or one of a limited number of other actions is carried out.

Before writing your own template files, it might be useful to look at some of the examples in the example_templates directory.

## Processing instructions

Note that if the closing ‘#’ of a processing instruction is the last character on a line then the following line break is not outputted. This makes templates easier to edit as you can have a separate line for each processing instruction and still produce output with no line breaks. If you want to output a line break after a processing instruction, put a blank line immediately after it.

### `##`

output a single ‘#’ character.

### `#! comment text#`

a comment, no output generated. `comment text` can be any text without a line break.

### `#monthly#`

switch to “monthly” summary data. The index is reset to the most recent value.

### `#daily#`

switch to “daily” summary data. The index is reset to the most recent value.

### `#hourly#`

switch to “hourly” summary data. The index is reset to the most recent value.

### `#raw#`

switch to “raw” data. The index is reset to the most recent value.

Changed in version 11.09: This now selects “calibrated” data. The directive name remains unchanged for backwards compatibility.

### `#live#`

switch to “live” data. If the template is processed in the `[live]` section of `weather.ini` this will select the most up-to-date weather data, otherwise it will have the same effect as `#raw#`. Any `#jump#` will go to “raw” data.

### `#timezone name#`

convert all datetime values to time zone `name` before output. Permitted values for name are `utc` or `local`.

### `#locale expr#`

switch use of ‘locale’ on or off, according to `expr`. When locale is on floating point numbers may use a comma as the decimal separator instead of a point, depending on your localisation settings. Use `"True"` or `"False"` for expr.

### `#roundtime expr#`

switch time rounding on or off, according to `expr`. When time rounding is on, 30 seconds is added to each time value used. This is useful if you are only printing out hours and minutes, e.g. with a “%H:%M” format, and want time values such as 10:23:58 to appear as “10:24”. Use `"True"` or `"False"` for expr.

### `#jump count#`

jump `count` values. The data index is adjusted by `count` hours or days. Negative values jump back in time.

It is a good idea to put jumps within a loop at the end, just before the `#endloop#` instruction. The loop can then terminate cleanly if it has run out of data.

### `#goto date-time#`

go to `date-time`. The data index is adjusted to the record immediately after `date-time`. This can be in UTC or your local time zone, according to the setting of `timezone`, and must exactly match the ISO date format, for example `"2010-11-01 12:00:00"` is noon on 1st November 2010.

Parts of `date-time` can be replaced with strftime style % format characters to specify the current loop index. For example, `"%Y-%m-01 12:00:00"` is noon on 1st of this month.

### `#loop count#`

start a loop that will repeat `count` times. `count` must be one or more.

### `#endloop#`

end a loop started by `#loop count#`. The template processing will go back to the line containing the `#loop count#` instruction. Don’t try to nest loops.

### `#key fmt_string no_value_string conversion#`

output a data value. `key` is the data key, e.g. `temp_out` for outdoor temperature. `fmt_string` is a printf-like format string (actually Python’s % operator) except for datetime values, when it is input to datetime’s `strftime()` method. `no_value_string` is output instead of `fmt_string` when the data value is absent, e.g. if the station lost contact with the outside sensor. `conversion` is a Python expression to convert the data, e.g. to convert wind speed from m/s to mph you could use `"x * 3.6 / 1.609344"`, or the more convenient provided function `"wind_mph(x)"`. See the `pywws.conversions` module for details of the available functions.

All these values need double quotes ” if they contain spaces or other potentially difficult characters. All except `key` are optional, but note that if you want to specify a conversion, you also need to specify `fmt_string` and `no_value_string`.

### `#calc expression fmt_string no_value_string conversion#`

output a value computed from one or more data items. `expression` is any valid Python expression, e.g. `"dew_point(data['temp_out'], data['hum_out'])"` to compute the outdoor dew point. `fmt_string`, `no_value_string` and `conversion` are as described above. Note that it is probably more efficient to incorporate any conversion into expression.

In addition to the functions in the `pywws.conversions` module there are three more useful functions: `rain_hour(data)` returns the amount of rain in the last hour, `rain_day(data)` returns the amount of rain since midnight (local time) and `hour_diff(data, key)` returns the change in data item `key` over the last hour.

## Example

Here is an example snippet showing basic and advanced use of the template features. It is part of the 6hrs.txt example template file, which generates an HTML table of 7 hourly readings (which should span 6 hours).

    #hourly#
    #jump -6#
    #loop 7#
      <tr>
        <td>#idx "%Y/%m/%d" "" "[None, x][x.hour == 0 or loop_count == 7]"#</td>
        <td>#idx "%H%M %Z"#</td>
        <td>#temp_out "%.1f °C"#</td>
        <td>#hum_out "%d%%"#</td>
        <td>#wind_dir "%s" "-" "winddir_text(x)"#</td>
        <td>#wind_ave "%.0f mph" "" "wind_mph(x)"#</td>
        <td>#wind_gust "%.0f mph" "" "wind_mph(x)"#</td>
        <td>#rain "%0.1f mm"#</td>
        <td>#rel_pressure "%.0f hPa"#, #pressure_trend "%s" "" "pressure_trend_text(x)"#</td>
      </tr>
    #jump 1#
    #endloop#

The first three lines of this snippet do the following: select hourly data, jump back 6 hours, start a loop with a count of 7. A jump forward of one hour appears just before the end of the repeated segment. As this last jump (of one hour) happens each time round the loop, a sequence of 7 data readings will be output. The last line marks the end of the loop — everything between the `#loop 7#` and `#endloop#` lines is output 7 times.

The `#temp_out ...#`, `#hum_out ...#`, `#rain ...#` and `#rel_pressure ...#` instructions show basic data output. They each use a `fmt_string` to format the data appropriately. The `#wind_ave ...#` and `#wind_gust ...#` instructions show how to use a conversion expression to convert m/s to mph.

The `#wind_dir ...#` and `#pressure_trend ...#` instructions show use of the built-in functions `winddir_text` and `pressure_trend_text` to convert numerical values into text.

Finally we get to datetime values. The `#idx "%H%M"#` instruction simply outputs the time (in HHMM format) of the data’s index. The `#idx "%Y/%m/%d" "" "[None, x][x.hour == 0 or loop_count == 7]"#` instruction is a bit more complicated. It outputs the date, but only on the first line or if the date has changed. It does this by indexing the array `[None, x]` with a boolean expression that is true when `loop_count` is 7 (i.e. on the first pass through the loop) or `x.hour` is zero (i.e. this is the first hour of the day).

## Detailed API

Functions

`ApplicationLogger`(verbose[, logfile]) |
`Zambretti`(params, hourly_data) |
`ZambrettiCode`(params, hourly_data) |
`apparent_temp`(temp, rh, wind) | Compute apparent temperature (real feel), using formula from
`cadhumidex`(temp, humidity) | Calculate Humidity Index as per Canadian Weather Standards
`dew_point`(temp, hum) | Compute dew point, using formula from http://en.wikipedia.org/wiki/Dew_point.
`illuminance_wm2`(lux) | Approximate conversion of illuminance in lux to solar radiation in W/m2
`main`([argv]) |
`pressure_inhg`(hPa) | Convert pressure from hectopascals/millibar to inches of mercury
`pressure_trend_text`(trend) | Convert pressure trend to a string, as used by the UK met office.
`rain_inch`(mm) | Convert rainfall from millimetres to inches
`temp_f`(c) | Convert temperature from Celsius to Fahrenheit
`usaheatindex`(temp, humidity, dew) | Calculate Heat Index as per USA National Weather Service Standards
`wind_bft`(ms) | Convert wind from metres per second to Beaufort scale
`wind_chill`(temp, wind) | Compute wind chill, using formula from
`wind_kmph`(ms) | Convert wind from metres per second to kilometres per hour
`wind_kn`(ms) | Convert wind from metres per second to knots
`wind_mph`(ms) | Convert wind from metres per second to miles per hour
`winddir_degrees`(pts) | Convert wind direction from 0..15 to degrees
`winddir_text`(pts) | Convert wind direction from 0..15 to compass point text

Classes

`Template`(params, status, calib_data, ...[, ...]) |
`datetime` | datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])
`timedelta` | Difference between two datetime values.

class `pywws.Template.``Template`(params, status, calib_data, hourly_data, daily_data, monthly_data, use_locale=True)
  `process`(live_data, template_file)
  `make_text`(template_file, live_data=None)
  `make_file`(template_file, output_file, live_data=None)

`pywws.Template.``main`(argv=None)

Comments or questions? Please subscribe to the pywws mailing list http://groups.google.com/group/pywws and let us know.

### Navigation

- index
- modules |
- next |
- previous |
- pywws 14.06.dev1238 documentation »
- Python programs and modules »