# Upgrade guide

!!! Warning
    You must use the same upgrade technique as your initial install! For
    example, if you used pip to install WeeWX, then you should use pip to
    upgrade. If you used a DEB or RPM package to install, then you should
    upgrade using the same package type.

!!! Warning
    If you are upgrading from an old `setup.py` installation, see the
    instructions [_Migrating setup.py installs to Version 5.0_](https://github.com/weewx/weewx/wiki/v5-upgrade).

The instructions for upgrading WeeWX are in the quick start guides:

* [Upgrading using Debian DEB](quickstarts/debian.md#upgrade)
* [Upgrading using Redhat RPM](quickstarts/redhat.md#upgrade)
* [Upgrading using SUSE RPM](quickstarts/suse.md#upgrade)
* [Upgrading using pip](quickstarts/pip.md#upgrade)
* [Upgrading using git](quickstarts/git.md#upgrade)

The rest of this document describes the changes in each WeeWX release.


## Upgrading the WeeWX configuration file

It does not happen very often, but occasionally a new release will
_require_ changes to the WeeWX configuration file. When this happens,
the installer takes care of upgrading the file, and you do not need to worry
about it.

However, there are some occasions when you may need to upgrade the file
yourself. In particular, this happens when you run several instances of
`weewxd` on the same machine, each with its own configuration file. The
configuration file named `weewx.conf` will get upgraded, but what about
the others?

The answer is to use `weectl station upgrade` with the `--config` option
pointing to the configuration file to be upgraded. For example, this would
upgrade the configuration file `/etc/weewx/other.conf`:

```
sudo weectl station upgrade --config=/etc/weewx/other.conf
```

## Upgrading to V5.0

There have been many changes with Version 5, but only a handful are likely to
affect users. With that in mind, we have broken this section down into two
sub-sections: breaking changes, and [non-breaking changes](#non-breaking-changes).

### Breaking changes

Changes in this category may require your attention.

#### Python 2.7 no longer supported

It has now been over 4 years since the end-of-life of Python 2.7. It's time to
move on. WeeWX V5.x requires Python 3.6 (released 7 years ago) or greater. These
days, all but the most ancient of operating systems offer Python 3, although you
may have to install it.

#### New utilities

The old utilities have been collected and put under one master utility,
`weectl`. This make it easy to use `weectl --help` to see which one you want.

| Old utility     | New utility        |
|-----------------|--------------------|
| `wee_database`  | `weectl database`  |
| `wee_debug`     | `weectl debug`     |
| `wee_device`    | `weectl device`    |
| `wee_extension` | `weectl extension` |
| `wee_import`    | `weectl import`    |
| `wee_reports`   | `weectl report`    |
| `wee_config`    | `weectl station`   |

#### pip installs to new location

The default location for a `setup.py` install was `/home/weewx`. The new pip
install method installs to a directory called `weewx-data` in the home directory
of the user doing the install. However, old installations can continue to use
`/home/weewx` by following the guide [_Migrating setup.py installs to Version
5.0_](https://github.com/weewx/weewx/wiki/v5-upgrade).

#### WeeWX runs as non-root user

For new installations and most upgrades, `weewxd` will now run as a non-root
user.  The configuration files, skins, databases, and reports are no longer
owned by root.  This means that root privilege is no longer required to modify
the WeeWX configuration and the WeeWX daemon no longer runs with escalated
privileges.  Escalated privilege is still required to start/stop the daemon.

For installations that use `apt`, `yum`, or `zypper` (installs that use the
DEB or RPM packages), the WeeWX user is `weewx` and the group is `weewx`.  The
home directory of the `weewx` user is `/var/lib/weewx`. The installer puts the
user who does the installation into the `weewx` group.  For upgrades, the
installer checks the ownership of `/var/lib/weewx`.  If the ownership was other
than `root:root`, the installer will respect the previous configured user and
not change it.

For installations that use `pip` or `git`, the WeeWX user is whoever created
the station data.

There are a few places where this change to permissions may affect an existing
WeeWX installation:

* access to USB and/or serial devices
* access to network ports, specifically binding to port 80
* creation and updating of reports

If you encounter problems when upgrading to V5, please see the wiki article
[*What you should know about permissions*](https://github.com/weewx/weewx/wiki/Understanding-permissions)

#### Changes in the utility `import`

The use of a field map by the `import` utility has been revised and is now 
more consistent across import sources. The result is the `import` utility now 
requires a field map definition stanza for all import sources with the field 
map defining the mapping from import source field to WeeWX archive field in 
addition to defining source field units and identifying cumulative and text 
fields. The expanded field map has resulted in the `rain` and `[[Units]]` 
import configuration file options being  deprecated. Refer to the `import` 
utility documentation and comments in the example import configuration files 
for further details.

#### Chinese language code changed to `zh`

Previously, the non-standard code "`cn`" was used for Chinese language
translations. V5 changes this to `zh`. This will require manually changing any
option that looks like this

    lang = cn

to this

    lang = zh

### Non-breaking changes

Changes in this category involve new functionality, or are not of interest to
existing users, or the upgrade process takes care of old configurations
transparently.

#### Utility `wunderfixer` has been removed.

The Weather Underground no longer allows past-dated posts, so the utility is
no longer useful.

#### setup.py installs no longer possible

The package `distutils`, and the imperative approach on which the WeeWX
`setup.py` install method depends, [has been
deprecated](https://peps.python.org/pep-0632/) and will ultimately be removed.
The future is clearly pip installs using `pyproject.toml`. See the wiki article
on [Version 5](https://github.com/weewx/weewx/wiki/Version-5) for the technical
reasons why.

#### `WEEWX_ROOT` is now relative to the configuration file

In previous versions, `WEEWX_ROOT` was specified in the configuration file as an
absolute path. That requirement has been relaxed and refined.  In V5,
`WEEWX_ROOT` can be specified in the configuration file as a _relative_ path,
or not at all.  If it is specified as a relative path, it will be relative to
the directory of the configuration file. If it is not specified at all (the
default for new installs), it defaults to the directory of the configuration
file.

This has the advantage that it allows the entire station data area to be rooted
anywhere in the file tree &mdash; one need only specify the location of the
configuration file to locate everything, for example, using the `--config` to
`weectl` or `weewxd`.

Old configuration files with an absolute path will continue to function as
before.

#### `SQLITE_ROOT` is now relative to `WEEWX_ROOT`

Previously, `SQLITE_ROOT` was expected to be an absolute path, but now relative
paths are accepted. A relative path is considered relative to `WEEWX_ROOT`.
Because this is _less restrictive_, it is not expected to affect any users.

#### New script to configure a daemon

This affects WeeWX installations that use `pip`.  Installations that use `apt`,
`yum`, or `zypper` (installs that use the DEB or RPM packages) are not affected.

There is a new script `setup-daemon.sh` that will install the files necessary to
run WeeWX as a daemon.  This script recognizes many operating systems, including
Linux (with or without systemd), BSD, and macOS.

This script is not run automatically - you must invoke it explicitly after you
install or upgrade using `pip`.

For upgrades, if you already have a systemd unit in `/etc/systemd/system`, a
SysV script in `/etc/init.d/weewx`, a launchd plist in `/Library/LaunchDaemons`,
or BSD rc in `/usr/local/etc/rc.d`, the setup script will move that aside.

#### New location for `user` directory

This affects WeeWX installations that use `apt`, `yum`, or `zypper` (installs
that use the DEB or RPM packages). Installations that use a `setup.py` or `pip`
install are not affected.

Previous versions of WeeWX would install code used by extensions alongside
other WeeWX code, usually in `/usr/share/weewx/user`.

With version 5, the `user` directory is kept with other station data, separate
from the WeeWX code.  For DEB and RPM installations, the `user` directory is
now `/etc/weewx/bin/user`.  If you upgrade a DEB or RPM installation, any
extensions that were installed in `/usr/share/weewx/user` will be copied to
`/etc/weewx/bin/user`, and the old `user` directory will be moved aside.

#### Use of systemd units for services

This affects users who use a DEB or RPM package install, and are running on
operating systems that use systemd, Installations that use a `setup.py` or `pip`
install are not affected.

For these package installers, two systemd unit files will be installed: the
standard service unit `weewx.service`, and the template service unit
`weewx@.service`.   The template unit makes it very easy to run multiple
instances of `weewxd` (for example, if you have more than one weather station or
multiple sets of sensors).

If you upgrade from V4, the init script `/etc/init.d/weewx` will remain - you
can safely delete it, since the new systemd unit files have precedence.  If you
modified the init script, you will have to migrate your changes to the systemd
methods for running daemons.

If you added a systemd unit file `/etc/systemd/system/weewx.service` to a V4
installation, then you upgrade from V4, you might want to remove the unit file
then `sudo systemctl daemon-reload` followed by `sudo systemctl enable weewx`.
Until you do this, the unit file in `/etc/systemd` will have precedence over
the unit and unit template that are installed by the installer.  If you just
want to override behavior of the units installed by the installer, you should
use the `.d` pattern instead.  See the systemd documentation for details.

#### WeeWX runs as the `weewx` user

This affects WeeWX installations that use `apt`, `yum`, or `zypper` (installs
that use the DEB or RPM packages). Installations that use a `setup.py` or `pip`
install are not affected.

For new installations, `weewxd` will run as the user `weewx`.  The configuration
files, skins, databases, and reports are owned by the `weewx` group.  This makes
it easier to manage a WeeWX installation. Put yourself into the `weewx` group,
then you will not have to `sudo` to make changes to skins or configurations.
You *will* have to `sudo` to start/stop `weewxd`.

For upgrades, the installer will check the ownership of `/var/lib/weewx`.  If
the ownership is `root:root`, the installer will create the `weewx` user and
run `weewxd` as that user and group. Otherwise, `weewxd` will run as the
previously configured user.

#### udev rules installed for core hardware

Version 5 includes a small change to the `udev` rules for hardware that is
supported by WeeWX. The rules include permissions that make any hardware that
uses USB or serial ports accessible to non-root users.

If you install WeeWX using `apt`, `yum`, or `zypper`, the udev rules are
installed as part of the installation process.  In this case, the rules make
the devices accessible to anyone in the `weewx` group.  So if you put yourself
in the `weewx` group, you will not have to `sudo` to communicate with a
supported USB or serial device.

If you install using `pip`, the rules are installed by the same script that
installs the files necessary to run as a daemon.

## Upgrading to V4.10

### Breaking changes for skins that use delta times

A "delta time" is the difference between two times, for example the amount of
uptime (difference between start and current time), or the amount of daylight
(difference between sunrise and sunset). In previous versions, delta times were
treated as a special case, which limited their flexibility. With <a
href="https://github.com/weewx/weewx/pull/807">PR #807</a>, a delta time is
treated like any other scalar, which gives you access to all the regular
formatting tools. However, a side effect is that if you want to format the time
in the "long form", that is, so the results look like <code>4
hours, 15 minutes</code>, rather than <code>15300 seconds</code>,
then you will have to say so explicitly.

If you use the <em>Seasons</em> skin, you will have to make these four changes.
Add the text in <span class="added">green</span>:

<div class="wide-table">
  <table>
    <tr class="first_row">
      <td style='width:50%'>V4.9 and earlier Seasons skin</td>
      <td>4.10 Seasons skin</td>
    </tr>
    <tr>
      <td colspan="2" style="text-align: center"><span class="code">Seasons/about.inc</span> starting at
        line 31
      </td>
    </tr>
    <tr>
      <td>
        <pre class="tty">&lt;tr&gt;
  &lt;td class="label"&gt;$gettext("Server uptime")&lt;/td&gt;
  &lt;td class="data"&gt;$station.os_uptime&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class="label"&gt;$gettext("WeeWX uptime")&lt;/td&gt;
  &lt;td class="data"&gt;$station.uptime&lt;/td&gt;
&lt;/tr&gt;</pre>
      </td>
      <td>
        <pre class="tty">&lt;tr&gt;
  &lt;td class="label"&gt;$gettext("Server uptime")&lt;/td&gt;
  &lt;td class="data"&gt;$station.os_uptime<span class="added">.long_form</span>&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td class="label"&gt;$gettext("WeeWX uptime")&lt;/td&gt;
  &lt;td class="data"&gt;$station.uptime<span class="added">.long_form</span>&lt;/td&gt;
&lt;/tr&gt;</pre>
      </td>
    </tr>
    <tr>
      <td colspan="2" style="text-align: center"><span class="code">Seasons/celestial.inc</span>
        starting at line 94
      </td>
    </tr>
    <tr>
      <td>
        <pre class="tty">&lt;tr&gt;
  &lt;td class="label"&gt;$gettext("Total daylight")&lt;/td&gt;
  &lt;td class="data"&gt;$almanac.sun.visible&lt;br/&gt;$sun_visible_change $change_str&lt;/td&gt;
&lt;/tr&gt;</pre>
      </td>
      <td>
        <pre class="tty">&lt;tr&gt;
  &lt;td class="label"&gt;$gettext("Total daylight")&lt;/td&gt;
  &lt;td class="data"&gt;$almanac.sun.visible<span class="added">.long_form</span>&lt;br/&gt;$sun_visible_change<span class="added">.long_form</span> $change_str&lt;/td&gt;
&lt;/tr&gt;</pre>
      </td>
    </tr>
  </table>
</div>

<p>
  In a similar manner, if you use the <em>Standard</em> skin, you will have to
  make these two changes. 
</p>

<div class="wide-table">
  <table>
    <tr class="first_row">
      <td style='width:50%'>V4.9 and earlier Standard skin</td>
      <td>4.10 Standard skin</td>
    </tr>
    <tr>
      <td colspan="2" style="text-align: center"><span class="code">Standard/index.html.tmpl</span>
        starting at line 309
      </td>
    </tr>
    <tr>
      <td>
        <pre class="tty">&lt;p&gt;$gettext("WeeWX uptime"):  $station.uptime&lt;br/&gt;
$gettext("Server uptime"): $station.os_uptime&lt;br/&gt;</pre>
      </td>
      <td>
        <pre class="tty">&lt;p&gt;$gettext("WeeWX uptime"):  $station.uptime<span class="added">.long_form</span>&lt;br/&gt;
$gettext("Server uptime"): $station.os_uptime<span class="added">.long_form</span>&lt;br/&gt;</pre>
      </td>
    </tr>
  </table>
</div>

<p>
  In both cases, the new formatting directive <span class="code">.long_form</span>
  has been used to explicitly request that the delta time be formatted into its
  constituent components. The advantage of this approach is that the delta time
  can be treated like any other scalar. Here are some examples: 
</p>

<table>
  <tr class="first_row">
    <td style='width:50%'>Tag</td>
    <td>Results</td>
  </tr>
  <tr>
    <td>
      <pre class="tty">$almanac.sun.visible</pre>
    </td>
    <td>
      <pre class="tty">45000 seconds</pre>
    </td>
  </tr>
  <tr>
    <td>
      <pre class="tty">$almanac.sun.visible.hour</pre>
    </td>
    <td>
      <pre class="tty">12.5 hours</pre>
    </td>
  </tr>
  <tr>
    <td>
      <pre class="tty">$almanac.sun.visible.hour.format("%.2f")</pre>
    </td>
    <td>
      <pre class="tty">12.50 hours</pre>
    </td>
  </tr>
  <tr>
    <td>
      <pre class="tty">$almanac.sun.visible.long_form</pre>
    </td>
    <td>
      <pre class="tty">12 hours, 30 minutes, 0 seconds</pre>
    </td>
  </tr>
</table>

### Changes for custom delta time formats

<p>
  Fixing issue <a href="https://github.com/weewx/weewx/issues/808">#808</a>
  required introducing a separate dictionary for members of group <span
  class="code">group_deltatime</span>. This means that if you specified custom
  formats under <span class="code">[Units]/[[TimeFormats]]</span>, then you will
  have to move them to the new section <span
  class="code">[Units]/[[DeltaTimeFormats]]</span>. Very few users should be
  affected by this change because the ability to set custom delta time formats is
  an undocumented feature. 
</p>

<p>
  The good news is that the contexts they now use have more standard names. The 
  table below summarizes:
</p>

<div class="wide-table">
  <table>
    <tr class="first_row">
      <td>V4.9 and earlier</td>
      <td>4.10</td>
    </tr>
    <tr>
      <td>
        <pre class='tty'>  [[TimeFormats]]
    ...
    current     = %x %X
    ephem_day   = %X
    ephem_year  = %x %X
    <span class="removed">brief_delta = "%(minute)d%(minute_label)s, %(second)d%(second_label)s"</span>
    <span class="removed">short_delta = "%(hour)d%(hour_label)s, %(minute)d%(minute_label)s, %(second)d%(second_label)s"</span>
    <span class="removed">long_delta  = "%(day)d%(day_label)s, %(hour)d%(hour_label)s, %(minute)d%(minute_label)s"</span>
    <span class="removed">delta_time  = "%(day)d%(day_label)s, %(hour)d%(hour_label)s, %(minute)d%(minute_label)s"</span></pre>
      </td>
      <td>
        <pre class='tty'>  [[TimeFormats]]
    ...
    current     = %x %X
    ephem_day   = %X
    ephem_year  = %x %X

    <span class="added">[[DeltaTimeFormats]]</span>
    <span class="added">current = "%(minute)d%(minute_label)s, %(second)d%(second_label)s"</span>
    <span class="added">hour    = "%(minute)d%(minute_label)s, %(second)d%(second_label)s"</span>
    <span class="added">day     = "%(hour)d%(hour_label)s, %(minute)d%(minute_label)s, %(second)d%(second_label)s"</span>
    <span class="added">week    = "%(day)d%(day_label)s, %(hour)d%(hour_label)s, %(minute)d%(minute_label)s"</span>
    <span class="added">month   = "%(day)d%(day_label)s, %(hour)d%(hour_label)s, %(minute)d%(minute_label)s"</span>
    <span class="added">year    = "%(day)d%(day_label)s, %(hour)d%(hour_label)s, %(minute)d%(minute_label)s"</span></pre>
      </td>
    </tr>
  </table>
</div>

<h4>Elapsed time calls may have to be changed</h4>
<p>
  The fix for Issue #808 also affects the API.
</p>

<table>
  <tr class="first_row">
    <td style='width:50%'>V4.9 and earlier</td>
    <td>4.10</td>
  </tr>
  <tr>
    <td>
      <pre class='tty'># Create an elapsed time of 1655 seconds
vt = ValueTuple(1655, 'second', 'group_deltatime')
vh = ValueHelper(vt,
                 formatter=self.generator.formatter,
                 converter=self.generator.converter,
                 <span class="changed">context='short_delta'</span>)
      </pre>
    </td>
    <td>
      <pre class='tty'># Create an elapsed time of 1655 seconds
vt = ValueTuple(1655, 'second', 'group_deltatime')
vh = ValueHelper(vt,
                 formatter=self.generator.formatter,
                 converter=self.generator.converter,
                 <span class="changed">context='day'</span>)
      </pre>
    </td>
  </tr>
</table>

<p>
  In summary, because <span class="code">group_deltatime</span> now uses the same context names as any other
  time, you will have to change the call to use one of the conventional contexts.
</p>


## Upgrading to V4.9
### <span class="code">wee_reports</span> may require <span class="code">--epoch</span> option.
<p>
  In previous versions, the utility <span class="code">wee_reports</span> could take an optional position
  argument that specified the reporting time in unix epoch time. For example,
</p>
<pre class="tty cmd">wee_reports /home/weewx/weewx.conf 1645131600</pre>
<p>
  would specify that the reporting time should be 1645131600, or 17-Feb-2022 13:00 PST.
</p>
<p>
  Starting with V4.9, the unix epoch time must be specified using the <span class="code">--epoch</span> flag,
  so the command becomes
</p>
<pre class="tty cmd">wee_reports /home/weewx/weewx.conf --epoch=1645131600</pre>
<p>
  Alternatively, the reporting time can be specified by using <span class="code">--date</span> and <span
												     class="code">--time</span> flags:
</p>
<pre class="tty cmd">wee_reports /home/weewx/weewx.conf --date=2022-02-17 --time=13:00</pre>

### Init function of class <span class="code">WXXTypes</span> has changed
<p>
  In earlier versions, ET was calculated in class <span class="code">WXXTypes</span>. Now it has its own
  class, <span class="code">ETXType</span>. As a result, some initialization parameters are no longer needed
  and have been removed.
</p>
<p>
  Note also that the parameter <span class="code">heat_index_algo</span> was changed to <span class="code">heatindex_algo</span>
  in keeping with the rest of the code.
</p>
<p>
  Unless you have been writing specialized code that required direct access to <span
										 class="code">WXXTypes</span> you are very unlikely to be affected.
</p>
<table>
  <tr class="first_row">
    <td style='width:50%'>V4.8 and earlier</td>
    <td>4.9</td>
  </tr>
  <tr>
    <td>
      <pre class='tty'>def __init__(self, altitude_vt, latitude_f, longitude_f,
        <span class="removed">et_period=3600,</span>
        atc=0.8,
        nfac=2,
        <span class="removed">wind_height=2.0,</span>
        force_null=True,
        maxSolarRad_algo='rs',
        <span class="changed">heat_index_algo</span>='new')
      </pre>
    </td>
    <td>
      <pre class='tty'>def __init__(self, altitude_vt, latitude_f, longitude_f,
        atc=0.8,
        nfac=2,
        force_null=True,
        maxSolarRad_algo='rs',
        <span class="changed">heatindex_algo</span>='new')
      </pre>
    </td>
  </tr>
</table>

### Calling signature of some archive span functions has changed

<p>
  The calling signature of the following functions has changed. In general, the parameter <span class="code">grace</span>
  has been removed in favor of a more robust method for figuring out which time span a timestamp belongs to.
</p>

<table>
  <tr class="first_row">
    <td style='width:50%'>V4.8 and earlier</td>
    <td>4.9</td>
  </tr>
  <tr>
    <td>
      <pre class='tty'>def archiveHoursAgoSpan(time_ts, hours_ago=0<span class="removed">, grace=1</span>)</pre>
    </td>
    <td>
      <pre class='tty'>def archiveHoursAgoSpan(time_ts, hours_ago=0)</pre>
    </td>
  </tr>
  <tr>
    <td>
      <pre class='tty'>def archiveDaySpan(time_ts, <span class="removed">grace=1,</span> days_ago=0)</pre>
    </td>
    <td>
      <pre class='tty'>def archiveDaySpan(time_ts, days_ago=0)</pre>
    </td>
  </tr>
  <tr>
    <td>
      <pre class='tty'>def archiveWeekSpan(time_ts, startOfWeek=6, <span class="removed">grace=1,</span> weeks_ago=0)</pre>
    </td>
    <td>
      <pre class='tty'>def archiveWeekSpan(time_ts, startOfWeek=6, weeks_ago=0)</pre>
    </td>
  </tr>
  <tr>
    <td>
      <pre class='tty'>def archiveMonthSpan(time_ts, <span class="removed">grace=1,</span> months_ago=0)</pre>
    </td>
    <td>
      <pre class='tty'>def archiveMonthSpan(time_ts, months_ago=0)</pre>
    </td>
  </tr>
  <tr>
    <td>
      <pre class='tty'>def archiveYearSpan(time_ts, <span class="removed">grace=1,</span> years_ago=0)</pre>
    </td>
    <td>
      <pre class='tty'>def archiveYearSpan(time_ts, years_ago=0)</pre>
    </td>
  </tr>
  <tr>
    <td>
      <pre class='tty'>def archiveRainYearSpan(time_ts, sory_mon<span class="removed">, grace=1</span>)</pre>
    </td>
    <td>
      <pre class='tty'>def archiveRainYearSpan(time_ts, sory_mon)</pre>
    </td>
  </tr>
</table>

## Upgrading to V4.6
### Ordering of search list changed
<p>
  In previous versions, user-supplied search list extensions were <em>appended</em> to the search list.
  Starting with V4.6, they are now <em>prepended</em> to the list. This means that when Cheetah is evaluating
  the list, looking for a tag, it will encounter user-supplied extensions first, allowing extensions to
  override the built-in tags and change their behavior.
</p>
### Tag <span class="code">$alltime</span>
<p>
  The tag <span class="code">$alltime</span>, formerly included as an example, is now a part of the core of
  WeeWX. This means you may no longer need to include the "stats" example as a Cheetah search list extension,
  although leaving it in will do no harm.
</p>


## Upgrading to V4.5
<p>
  Version 4.5 changes are unlikely to affect anyone, except extension writers who are deep in the internals of
  WeeWX.
</p>

### API changes
<p>
  There have been a number of changes in the WeeWX API. None of them are likely to affect end users. Overall,
  the biggest change is that the data held internally in class <span class="code">ValueHelper</span> is now
  held in the target unit system, rather than being converted at time of use.
</p>

<h4>Defaults for <span class="code">ValueHelper</span> have changed</h4>
<p>
  Before, when constructing a new <span class="code">ValueHelper</span>, if no converter was included in the
  constructor, a default converter, which converts to US Units, was supplied. Now, if no converter is included
  in the constructor, no default converter at all is supplied, and the data remain in the original units. This
  is unlikely to affect most extension writers because the usual case is to supply a converter to the <span
													class="code">ValueHelper</span> constructor.
</p>

<h4>Function <span class="code">as_value_tuple()</span> may raise <span class="code">KeyError</span></h4>
<p>
  Previously, if the function <span class="code">as_value_tuple()</span> was asked to return a <span
												 class="code">ValueTuple</span> of a non-existent type, it returned a <span class="code">ValueTuple</span>
  with values <span class="code">(None, None, None)</span>. Now it raises a <span class="code">KeyError</span>
  exception.
</p>

## Upgrading to V4.4

### Auto patch of daily summaries

<p>
  The V4.2 daily summary patch inadvertently introduced a bug which caused the <span class="code">wind</span>
  daily summary to be incorrectly weighted. See issue <a
							href="https://github.com/weewx/weewx/issues/642">#642</a>. V4.4 includes a patch to automatically fix the
  defective daily summary. It is run only once on the first use of a database (usually by <span class="code">weewxd</span>)
  and takes only a few seconds.
</p>

## Upgrading to V4.3

### Auto patch of daily summaries

<p>
  Version 4.2 inadvertently introduced a bug, which prevented the sums that are kept in the daily summaries
  from being weighted by the archive interval. See issue <a href="https://github.com/weewx/weewx/issues/623">#623</a>.
  V4.3 includes a patch, which will fix any defective daily summaries automatically. It is run only once on
  the first use of a database (usually by <span class="code">weewxd</span>) and takes only a few seconds.
</p>

### Option <span class="code">ignore_zero_wind</span> has been renamed and moved

<p>
  Normally, WeeWX sets wind direction to undefined when wind speed is zero. While it was never documented,
  some users used option <span class="code">ignore_zero_wind</span> to prevent this: if set to <span
												 class="code">False</span>, wind direction will not be set to undefined when wind speed is zero. However, the
  option's location and name has changed. It is now called <span class="code">force_null</span>, and it is now
  located under <span class="code">[StdWXCalculate] / [[WXXTypes]] / [[[windDir]]]</span>. The old name and
  location has been deprecated, but still honored.
</p>

<table>
  <tr class="first_row">
    <td style='width:50%'>V4.2 and earlier</td>
    <td>4.3</td>
  </tr>
  <tr>
    <td>
      <pre class='tty'>[StdWXCalculate]
    <span class="removed">ignore_zero_wind = False</span>
    [[Calculations]]
        ...</pre>
    </td>
    <td>
      <pre class='tty'>[StdWXCalculate]
    [[Calculations]]
        ...
    [[WXXTypes]]
    [[[windDir]]]
        <span class="added">force_null = False</span></pre>
    </td>
  </tr>
</table>

### Option <span class="code">log_failure</span> set to <span class="code">True</span>
<p>
  The option <span class="code">log_failure</span> under <span class="code">[StdReport]</span> controls
  whether to log failures into the system log. It was previously set to <span class="code">False</span>. The
  upgrade process will set it to <span class="code">True</span>, so that users can better see failure modes.
</p>

<table>
  <tr class="first_row">
    <td style='width:50%'>V4.2 and earlier</td>
    <td>4.3</td>
  </tr>
  <tr>
    <td>
      <pre class='tty'>[StdReport]
	...
	<span class="changed">log_failure = False</span>
	...</pre>
    </td>
    <td>
      <pre class='tty'>[StdReport]
	...
	<span class="changed">log_failure = True</span>
	...</pre>
    </td>
  </tr>
</table>

## Upgrading to V4.2

<p>
  For the most part, V4.2 is backwards compatible with previous versions. There is one small exception.
</p>

### Type <span class="code">beaufort</span> deprecated
<p>
  The type <span class="code">beaufort</span> has been deprecated, although there are no immediate plans to
  remove it &mdash; using it will put a warning in the log. Instead, it has become a new unit, which can be
  used as part of <span class="code">group_speed</span>. Here's an example:
</p>
<table>
  <tr class="first_row">
    <td style='width:50%'>V4.1 and earlier</td>
    <td>4.2</td>
  </tr>
  <tr>
    <td>
      <pre class='tty'>&lt;p&gt;
The current wind speed is $current.windSpeed,
which is <span class="changed">$current.beaufort</span> on the beaufort scale.
&lt;/p&gt;</pre>
    </td>
    <td>
      <pre class='tty'>&lt;p&gt;
The current wind speed is $current.windSpeed,
which is <span class="changed">$current.windSpeed.beaufort</span> on the beaufort scale.
&lt;/p&gt;</pre>
    </td>
  </tr>
</table>

## Upgrading to V4.0

<p>
  For the most part, V4.0 is backwards compatible with previous versions.
</p>
### Python 2.5 and 2.6
<p>
  Support for Python 2.5 and 2.6 has been dropped. It has now been well over 10 years since these versions
  were introduced, and 6+ years since they were supported by the Python Software Foundation. If you are using
  Python 2.5 or 2.6, then you should either upgrade your copy of Python, or stay with your old version of
  WeeWX.
</p>
### [StdWXCalculate]
<p>
  In earlier versions of WeeWX, many derived types were calculated by default by the service <span
											       class="code">StdWXCalculate</span>. By contrast, in WeeWX V4, no derived types are calculated by default
  &mdash; all desired types must be explicitly listed in <span class="code">weewx.conf</span>. For most users,
  this will not cause a problem because most types were already listed in <span class="code">weewx.conf</span>.
  However if you deleted one of the following types in the clause <span class="code">[StdWXCalculate]</span>,
  and started to depend on the default calculations, then the type will no longer be calculated in V4.
</p>
<table class="tty" style="width:50%">
  <tr>
    <td>pressure</td>
    <td>barometer</td>
    <td>altimeter</td>
  </tr>
  <tr>
    <td>windchill</td>
    <td>heatindex</td>
    <td>dewpoint</td>
  </tr>
  <tr>
    <td>inDewpoint</td>
    <td>rainRate</td>
  </tr>
</table>
<p>
  In this case, you should add the type to <span class="code">[StdWXCalculate]</span>. For example, if for
  some reason you deleted <span class="code">dewpoint</span>, then you would need to add the following
</p>
<pre class="tty" style="width:50%">[StdWXCalculate]
  [[Calculations]]
    ...
    <span class="added">dewpoint = prefer_hardware</span>
</pre>

## Upgrading to V3.9

### New skins
<p>
  Version 3.9 introduces and installs a new skin, <em>Seasons</em>, and promotes two old skins,
  <em>Mobile</em> and <em>Smartphone</em>, previously part of <em>Standard</em>, to first-class, independent,
  skins.
</p>

<ul>
  <li>
    If you are installing fresh (not an upgrade), then all four skins, <em>Seasons</em>, <em>Standard</em>,
    <em>Mobile</em>, and <em>Smartphone</em> will be installed, but only <em>Seasons</em> will be activated.
  </li>
  <li>
    If you are upgrading, then the three new skins, <em>Seasons</em>, <em>Mobile</em>, and
    <em>Smartphone</em> will be installed, but none will be activated. Your existing <em>Standard</em> will
    be left untouched and activated. For most people, your website will continue to look as expected (the
    exception is explained below in section <a href="#do-you-need-to-change-anything"><em>Do you need to change anything?</em></a>).
  </li>
</ul>

!!! Note
    If you are upgrading, and you wish to try the new skin <em>Seasons</em>,
    then activate it, but <em>be sure to deactivate Standard</em>. Otherwise,
    both will get generated, and they will compete with each other for
    placement in your HTML directory.

### Skin defaults
<p>
  Version 3.9 introduces a new section, <span class="code">[StdReport]/[[Defaults]]</span> in <span
												class="code">weewx.conf</span>. Options in this section apply to <em>all</em> reports. For example, if you
  set a unit group here, it will be applied everywhere. This makes it easy to set the units across all
  reports, or to ensure that the labels for observations are the same in every report.
</p>
<p>
  It also adds a file <span class="code">defaults.py</span>, in which the fallback values for every report
  parameter are specified. Although the defaults file is currently useful only to developers, in the future it
  may be extended to facilitate translations and localization.
</p>

### Do you need to change anything?

<p>
  The introduction of the new section, <span
  class="code">[StdReport]/[[Defaults]]</span> in <span
  class="code">weewx.conf</span>, can change which units are applied to reports
  because it has a higher precedence than what is in <span
  class="code">skin.conf</span>. See the section <a
  href="../custom/custom-reports/#how-to-specify-options"><em>How to specify options</em></a> for
  details of the ordering in which an option is considered. 
</p>

<p>
  Most users will be unaffected by these changes because they depend on specific report overrides. There is,
  however, one exception:
</p>

!!! Note
    If your installation does not use overrides, and you changed to metric
    units in your `skin.conf` file, you will be affected.

<p>
  Your reports will start appearing in U.S. Customary units. The reason is that
  the new section, <span class="code">[StdReport]/[[Defaults]]</span> has higher
  priority than options in <span class="code">skin.conf</span>, and thus will
  start asserting itself. </p>

<p>
  The fix is simple: modify the <span class="code">[StdReport]/[[Defaults]]</span> to suit your preferences.
</p>

<p>
  However, users who specified what unit system to use as part of the automated install using a package
  installer or <span class="code">setup.py</span>, will have an override section, and therefore will be
  unaffected. This is because the override section has the highest priority.
</p>

## Upgrading to V3.7


### Changes to daily summaries
<p>Perhaps the most significant change in V3.7 is a fix for how daily summary values are calculated and stored.
</p>

<p>Daily summaries were introduced in V3.0 (December 2014), to speed up certain kinds of aggregation
  calculations. They were designed to "weight" values depending on the time length of the archive record that
  contributed them. For example, shorter intervals contributed less than longer intervals. This was intended
  to enable changes to the length of the archive interval.
</p>

<p>Unfortunately, a bug caused the weightings to all be one (1), regardless of what the actual archive interval
  length might be. This means all archive records, long and short, contribute the same amount, instead of
  being weighted by their length. So, if the archive interval were to change, averages would be calculated
  incorrectly.
</p>

<p>
  This bug will only affect you if you have changed the length of your archive interval, or if you plan to. If
  you have not changed your archive interval length, and have no plans to do so, then there is nothing you
  need to do.
</p>

!!! Note
    Your archive may have interval values of different sizes if
    <ul>
    <li> you have imported data using `wee_import`</li>
    <li> your hardware has a data logger, your configuration uses `record_generation=software`, and the `archive_interval` is different from that in the hardware</li>
    <li> your archive contains data from more than one type of hardware</li>
    </ul>

<p>The <a href="../utilities/weectl-database/#update"><span class="code">weectl
database update</span></a> utility can fix this problem by recalculating the
weights in the daily summary, on the basis of the actual archive interval
lengths. On a Raspberry Pi 1, model B, it takes about 10 minutes to fix a
database with 10 years of data. On faster machines, it takes much less time.
</p>

<pre class="tty cmd">weectl database update</pre>

<p>
  If you have multiple databases, consider recalculating the weights in each database. Interval weighting will
  only need to be applied to databases that have daily summaries, i.e., the binding uses
</p>
<pre class="tty">manager = weewx.wxmanager.WXDaySummaryManager</pre>
<p>
  To apply interval weighting to a database other than the default <span class="code">wx_binding</span>, use
  the <span class="code">--binding=BINDING_NAME</span> option.
</p>
<pre class="tty cmd">weectl database update --binding=cmon_binding</pre>

### Recalculation of <span class="code">windSpeed</span> maximum values

<p>Version 3.7 changes how maximum <span class="code">windSpeed</span> is calculated for aggregations of a day
  or more. Previously, if option <span class="code">use_hilo</span> was set to <span class="code">True</span>
  (the usual case), maximum <span class="code">windSpeed</span> for a day was set to the maximum value seen in
  the LOOP packets for the day. In practice this is the same value as <span class="code">windGust</span>. That
  is, these two tags would supply the same value:
</p>

<pre class="tty">$day.windSpeed.max
  $day.windGust.max</pre>

<p>
In Version 3.7, this has been changed so the maximum <span class="code">windSpeed</span> is now set to the
  maximum <em>archive</em> value seen during the day &mdash; usually a slightly smaller number. However, older
  daily max values will still contain the max LOOP packet values. If you wish to update your older values and
  have them use the max archive record value, use the utility <a href="../utilities/weectl-database/#update"><span class="code">weectl
  database update</span></a> .
</p>


### Change in the name and locations of examples
<p>
  In earlier versions, examples were located with the WeeWX code base, and packaged as a Python module. This
  is categorically and semantically incorrect.
</p>
<p>
  The examples now live in their own directory, <a href="../usersguide/where">whose location
    is dependent on the installation method</a>. If you use an example, you should copy it to the <span
												    class="code">user</span> subdirectory, modify it if necessary, then use it there. Your copy will be retained
  across version upgrades.
</p>

<table>
  <tr class="first_row">
    <td style='width:50%'>3.6</td>
    <td>3.7</td>
  </tr>
  <tr>
    <td>
      <pre class='tty'><span class="changed">examples.alarm.MyAlarm
examples.lowBattery.MyAlarm
examples.xsearch.MyXSearch</span></pre>
    </td>
    <td>
      <pre class='tty'><span class="changed">user.alarm.MyAlarm
user.lowBattery.BatteryAlarm
user.stats.MyStats</span></pre>
    </td>
  </tr>
</table>

<p>Finally, note that the name of one example has been changed:</p>

<table>
  <tr class="first_row">
    <td style='width:50%'>3.6</td>
    <td>3.7</td>
  </tr>
  <tr>
    <td>
      <pre class='tty'><span class="changed">xsearch.py</span></pre>
    </td>
    <td>
      <pre class='tty'><span class="changed">stats.py</span></pre>
    </td>
  </tr>
</table>


### Changes to sensor mapping
<p>
  The mapping of sensors to database fields was formalized in Version 3.7, resulting in changes to the
  configuration for some of the drivers, including <span class="code">cc3000</span>, <span
										       class="code">te923</span>, <span class="code">wmr100</span>, <span class="code">wmr200</span>, <span
																							class="code">wmr300</span>, and <span class="code">wmr9x8</span>.
</p>
<p>
  For the <span class="code">wmr200</span> driver, until Version 3.6, the fields extraTemp1 and extraHumid1
  were not usable. Version 3.6.1 shifted the extraTemp and extraHumid mappings down one channel, so that
  extraTemp1 corresponded to channel 2, extraTemp2 corresponded to channel 3, and so on. The mappings can now
  be modified by a change to the configuration file, and the default mappings are as follows:
</p>
<table>
  <tr class="first_row">
    <td style='width:50%'>3.6</td>
    <td>3.7</td>
  </tr>
  <tr>
    <td>
      <pre class='tty'>** hard-coded in the driver **

	outTemp = temperature_1
	# extraTemp1 is not usable
	extraTemp2 = temperature_2
	extraTemp3 = temperature_3
	extraTemp4 = temperature_4
	extraTemp5 = temperature_5
	extraTemp6 = temperature_6
	extraTemp7 = temperature_7
	extraTemp8 = temperature_8
	outHumidity = humidity_1
	# extraHumid1 is not usable
	extraHumid2 = humidity_2
	extraHumid3 = humidity_3
	extraHumid4 = humidity_4
	extraHumid5 = humidity_5
	extraHumid6 = humidity_6
	extraHumid7 = humidity_7
	extraHumid8 = humidity_8</pre>
    </td>
    <td>
      <pre class='tty'>[WMR200]
	<span class="added">[[sensor_map]]
          altimeter = altimeter
          pressure = pressure
          windSpeed = wind_speed
          windDir = wind_dir
          windGust = wind_gust
          windBatteryStatus = battery_status_wind
          inTemp = temperature_0
          outTemp = temperature_1
          extraTemp1 = temperature_2
          extraTemp2 = temperature_3
          extraTemp3 = temperature_4
          extraTemp4 = temperature_5
          extraTemp5 = temperature_6
          extraTemp6 = temperature_7
          extraTemp7 = temperature_8
          inHumidity = humidity_0
          outHumidity = humidity_1
          extraHumid1 = humidity_2
          extraHumid2 = humidity_3
          extraHumid3 = humidity_4
          extraHumid4 = humidity_5
          extraHumid5 = humidity_6
          extraHumid6 = humidity_7
          extraHumid7 = humidity_8
          outTempBatteryStatus = battery_status_out
          rain = rain
          rainTotal = rain_total
          rainRate = rain_rate
          hourRain = rain_hour
          rain24 = rain_24
          rainBatteryStatus = battery_status_rain
          UV = uv
          uvBatteryStatus = battery_status_uv
          windchill = windchill
          heatindex = heatindex
          forecastIcon = forecast_icon
          outTempFault = out_fault
          windFault = wind_fault
          uvFault = uv_fault
          rainFault = rain_fault
          clockUnsynchronized = clock_unsynchronized</span></pre>
    </td>
  </tr>
</table>
<p>
  For the <span class="code">te923</span> driver:
</p>
<table>
  <tr class="first_row">
    <td style='width:50%'>3.6</td>
    <td>3.7</td>
  </tr>
  <tr>
    <td>
      <pre class='tty'>[TE923]
	<span class="changed">[[map]]
          link_wind = windLinkStatus
          bat_wind = windBatteryStatus
          link_rain = rainLinkStatus
          bat_rain = rainBatteryStatus
          link_uv = uvLinkStatus
          bat_uv = uvBatteryStatus
          uv = UV
          t_in = inTemp
          h_in = inHumidity
          t_1 = outTemp
          h_1 = outHumidity
          bat_1 = outBatteryStatus
          link_1 = outLinkStatus
          t_2 = extraTemp1
          h_2 = extraHumid1
          bat_2 = extraBatteryStatus1
          link_2 = extraLinkStatus1
          t_3 = extraTemp2
          h_3 = extraHumid3
          bat_3 = extraBatteryStatus2
          link_3 = extraLinkStatus2
          t_4 = extraTemp3
          h_4 = extraHumid3
          bat_4 = extraBatteryStatus3
          link_4 = extraLinkStatus3
          t_5 = extraTemp4
          h_5 = extraHumid4
          bat_5 = extraBatteryStatus4
          link_5 = extraLinkStatus4</span></pre>
    </td>
    <td>
      <pre class='tty'>[TE923]
	<span class="changed">[[sensor_map]]
          windLinkStatus = link_wind
          windBatteryStatus = bat_wind
          rainLinkStatus = link_rain
          rainBatteryStatus = bat_rain
          uvLinkStatus = link_uv
          uvBatteryStatus = bat_uv
          inTemp = t_in
          inHumidity = h_in
          outTemp = t_1
          outHumidity = h_1
          outTempBatteryStatus = bat_1
          outLinkStatus = link_1
          extraTemp1 = t_2
          extraHumid1 = h_2
          extraBatteryStatus1 = bat_2
          extraLinkStatus1 = link_2
          extraTemp2 = t_3
          extraHumid2 = h_3
          extraBatteryStatus2 = bat_3
          extraLinkStatus2 = link_3
          extraTemp3 = t_4
          extraHumid3 = h_4
          extraBatteryStatus3 = bat_4
          extraLinkStatus3 = link_4
          extraTemp4 = t_5
          extraHumid4 = h_5
          extraBatteryStatus4 = bat_5
          extraLinkStatus4 = link_5</span></pre>
    </td>
  </tr>
</table>


## Upgrading to V3.6

### Changes to <span class="code">weewx.conf</span>
<p>
  In Version 3.6, the list of options that describe how derived variables are to be calculated have been moved
  to a new subsection called <span class="code">[[Calculations]]</span>. The upgrade process will
  automatically make this change for you.
</p>

<table>
  <tr class="first_row">
    <td style='width:50%'>3.5</td>
    <td>3.6</td>
  </tr>
  <tr>
    <td>
      <pre class='tty'>[StdWXCalculate]
	pressure = prefer_hardware
	barometer = prefer_hardware
	altimeter = prefer_hardware
	windchill = prefer_hardware
	heatindex = prefer_hardware
	dewpoint = prefer_hardware
	inDewpoint = prefer_hardware
	rainRate = prefer_hardware

      </pre>
    </td>
    <td>
      <pre class='tty'>[StdWXCalculate]
	<span class="changed">[[Calculations]]</span>
        pressure = prefer_hardware
        barometer = prefer_hardware
        altimeter = prefer_hardware
        windchill = prefer_hardware
        heatindex = prefer_hardware
        dewpoint = prefer_hardware
        inDewpoint = prefer_hardware
        rainRate = prefer_hardware</pre>
    </td>
  </tr>
</table>


## Upgrading to V3.2

### New utilities

<p>
  Version 3.2 includes new utilities to facilitate configuration.
</p>
<table>
  <tr class="first_row">
    <td style='width:30%'>3.2</td>
    <td style='width:30%'>3.1 and earlier</td>
    <td></td>
  </tr>
  <tr>
    <td><span class='code'>wee_config</span></td>
    <td></td>
    <td>Change driver or other station parameters</td>
  </tr>
  <tr>
    <td><span class='code'>wee_extension</span></td>
    <td><span class='code'>setup.py</span> or <span class='code'>wee_setup</span></td>
    <td>Install, list, and remove extensions</td>
  </tr>
  <tr>
    <td><span class='code'>wee_database</span></td>
    <td><span class='code'>wee_config_database</span></td>
    <td>Manipulate the database</td>
  </tr>
  <tr>
    <td><span class='code'>wee_device</span></td>
    <td><span class='code'>wee_config_device</span></td>
    <td>Get and set parameters on the hardware</td>
  </tr>
  <tr>
    <td><span class='code'>wee_reports</span></td>
    <td><span class='code'>wee_reports</span></td>
    <td>Run reports</td>
  </tr>
</table>

### Changes to weewx.conf

<p>Release 3.2 introduces a new section <span class='code'>[DatabaseTypes]</span>. This section defines the
  default settings for each type of database. For example, the host, user, and password for MySQL databases
  can be specified once in the <span class='code'>DatabaseTypes</span> section instead of repeating in each
  <span class='code'>Database</span> section. The defaults in <span class='code'>DatabaseTypes</span> can be
  overridden in each <span class='code'>Database</span> section as needed.
</p>

<table>
  <tr class="first_row">
    <td style='width:50%'>3.1</td>
    <td>3.2</td>
  </tr>
  <tr>
    <td>
      <pre class='tty'>[DataBindings]
    [[wx_binding]]
        database = archive_sqlite
        manager = weewx.wxmanager.WXDaySummaryManager
        table_name = archive
        schema = schemas.wview.schema
[Databases]
    [[archive_sqlite]]
<span class='changed'>        root = %(WEEWX_ROOT)s
        database = archive/weewx.sdb
        driver = weedb.sqlite</span>
    [[archive_mysql]]
<span class='changed'>        host = localhost
        user = weewx
        password = weewx
        database = weewx
        driver = weedb.mysql</span>









      </pre>
    </td>
    <td>
      <pre class='tty'>[DataBindings]
    [[wx_binding]]
        database = archive_sqlite
        manager = weewx.wxmanager.WXDaySummaryManager
        table_name = archive
        schema = schemas.wview.schema
[Databases]
    [[archive_sqlite]]
<span class='changed'>        database_name = weewx.sdb
        database_type = SQLite</span>

    [[archive_mysql]]
<span class='changed'>        database_name = weewx
        database_type = MySQL</span>



	<span class='added'>[DatabaseTypes]
    [[SQLite]]
          driver = weedb.sqlite
          SQLITE_ROOT = %(WEEWX_ROOT)s/archive
    [[MySQL]]
          driver = weedb.mysql
          host = localhost
          user = weewx
          password = weewx</span></pre>
    </td>
  </tr>
</table>

## Upgrading to V3.0

### Overview

<p>While a lot has changed with Version 3, the upgrade process should take care of most changes for most users.
  However, if you have installed an extension or, especially, if you have written a custom service, search
  list extension, or uploader, you will have to make some changes.
</p>

### Database contents

<p>
  With Version 3, there is no longer a separate "stats" database. Instead, "daily summaries" have been
  included in the same database as the archive data &mdash; everything is under one name. For example, if you
  are using sqlite, both the archive data and the daily summaries will be inside file <span class="code">weewx.sdb</span>.
  With MySQL, everything is inside the database <span class="code">weewx</span>. This makes it easier to keep
  all data together when working with multiple databases.
</p>

<p>This change in database structure should be transparent to you. On startup, WeeWX will automatically backfill
  the new internal daily summaries from the archive data. Your old "stats" database will no longer be used and
  may safely set aside or even deleted.
</p>

### Pressure calibration

<p>
  Since the new <span class="code">StdWXCalculate</span> service is applied after the <span class="code">StdCalibrate</span>
  services, the <span class='code'>pressure_offset</span> parameter is no longer necessary; pressure
  calibration can be applied just like any other calibration. If your pressure was calibrated using the <span
													  class='code'>pressure_offset</span> parameter, move the calibration to the <span
																						       class="code">[StdCalibrate]</span> section. This applies only to CC3000, FineOffsetUSB, Ultimeter, WS1,
  WS23xx, and WS28xx hardware.
</p>

### <span class="code">weewx.conf</span>

<p>
  A version 2.X <span class="code">weewx.conf</span> file is not compatible with Version 3.X. However, the
  upgrade process should automatically update the file. Nevertheless, the changes are documented below:
</p>
<table>
  <tr class="first_row">
    <td style='width:50%'>2.7</td>
    <td>3.0</td>
  </tr>
  <tr>
    <td></td>
    <td>
      <pre class='tty'>[StdReport]
<span class='added'>    data_binding = wx_binding</span></pre>
    </td>
  </tr>
  <tr>
    <td>
      <pre class='tty'>[StdArchive]
<span class='removed'>    archive_database = archive_sqlite
    stats_database = stats_sqlite
    archive_schema = user.schemas.defaultArchiveSchema
    stats_schema = user.schemas.defaultStatsSchema</span></pre>
    </td>
    <td>
      <pre class='tty'>[StdArchive]
<span class='added'>    data_binding = wx_binding</span></pre>
    </td>
  </tr>
  <tr>
    <td></td>
    <td>
      <pre class='tty'><span class='added'>[DataBindings]
    [[wx_binding]]
        database = archive_sqlite
        manager = weewx.wxmanager.WXDaySummaryManager
        table_name = archive
        schema = schemas.wview.schema</span></pre>
    </td>
  </tr>
  <tr>
    <td>
      <pre class='tty'>[Databases]
	[[archive_sqlite]]
        root = %(WEEWX_ROOT)s
        <span class='changed'>database</span> = archive/weewx.sdb
        driver = weedb.sqlite
<span class='removed'>    [[stats_sqlite]]
        root = %(WEEWX_ROOT)s
        database = archive/stats.sdb
        driver = weedb.sqlite</span>
    [[archive_mysql]]
        host = localhost
        user = weewx
        password = weewx
        <span class='changed'>database</span> = weewx
        driver = weedb.mysql
<span class='removed'>    [[stats_mysql]]
        host = localhost
        user = weewx
        password = weewx
        database = stats
        driver = weedb.mysql</span></pre>
    </td>
    <td>
      <pre class='tty'>[Databases]
    [[archive_sqlite]]
        root = %(WEEWX_ROOT)s
        <span class='changed'>database_name</span> = archive/weewx.sdb
        driver = weedb.sqlite

	
	
	
    [[archive_mysql]]
        host = localhost
        user = weewx
        password = weewx
        <span class='changed'>database_name</span> = weewx
        driver = weedb.mysql
	
	
	
	
	
	
      </pre>
    </td>
  </tr>
  <tr>
    <td>
      <pre class='tty'>[<span class='changed'>Engines</span>]
    [[<span class='changed'>WxEngine</span>]]
        prep_services = \
          weewx.<span class='changed'>wxengine</span>.StdTimeSynch
        process_services = \
          weewx.<span class='changed'>wxengine</span>.StdConvert, \
          weewx.<span class='changed'>wxengine</span>.StdCalibrate, \
          weewx.<span class='changed'>wxengine</span>.StdQC
	
        archive_services = \
          weewx.<span class='changed'>wxengine</span>.StdArchive
        restful_services = \
          weewx.restx.StdStationRegistry, \
          weewx.restx.StdWunderground, \
          weewx.restx.StdPWSweather, \
          weewx.restx.StdCWOP, \
          weewx.restx.StdWOW, \
          weewx.restx.StdAWEKAS
        report_services = \
          weewx.<span class='changed'>wxengine</span>.StdPrint, \
          weewx.<span class='changed'>wxengine</span>.StdReport</pre>
    </td>
    <td>
      <pre class='tty'>[<span class='changed'>Engine</span>]
    [[<span class='changed'>Services</span>]]
        prep_services = \
          weewx.<span class='changed'>engine</span>.StdTimeSynch
        process_services = \
          weewx.<span class='changed'>engine</span>.StdConvert, \
          weewx.<span class='changed'>engine</span>.StdCalibrate, \
          weewx.<span class='changed'>engine</span>.StdQC<span class='added'>, \
          weewx.wxservices.StdWXCalculate</span>
        archive_services = \
          weewx.<span class='changed'>engine</span>.StdArchive
        restful_services = \
          weewx.restx.StdStationRegistry, \
          weewx.restx.StdWunderground, \
          weewx.restx.StdPWSweather, \
          weewx.restx.StdCWOP, \
          weewx.restx.StdWOW, \
          weewx.restx.StdAWEKAS
        report_services = \
          weewx.<span class='changed'>engine</span>.StdPrint, \
          weewx.<span class='changed'>engine</span>.StdReport</pre>
    </td>
  </tr>
</table>

### Custom data sources in skins

<p>The mechanism for specifying non-default data sources in skins has changed. If you modified the Standard
  skin, or created or used other skins that draw data from a database other than the weather database, you
  must change how the other sources are specified.
</p>

<p>For example, in the <span class='code'>cmon</span> extension:</p>
<table>
  <tr class="first_row">
    <td style='width:50%'>2.7</td>
    <td>3.0</td>
  </tr>
  <tr>
    <td>
      <pre class='tty'>[ImageGenerator]
	...
	[[day_images]]
        ...
        [[[daycpu]]]
            <span class='changed'>archive_database = cmon_sqlite</span>
        [[[cpu_user]]]
        [[[cpu_idle]]]
        [[[cpu_system]]]</pre>
    </td>
    <td>
      <pre class='tty'>[ImageGenerator]
	...
	[[day_images]]
        ...
        [[[daycpu]]]
            <span class='changed'>data_binding = cmon_binding</span>
        [[[cpu_user]]]
        [[[cpu_idle]]]
        [[[cpu_system]]]</pre>
    </td>
  </tr>
</table>

### Extensions

<p>
  Many skins will work in v3 with no modification required. However, every search list extension will have to
  be upgraded, every restful extension must be upgraded, and some other services must be upgraded.
</p>

<p>
  There is no automated upgrade system for extensions; if an extension must be upgraded, you must do it
  manually. If the extension has any python code, this will mean replacing any v2-compatible code with
  v3-compatible code. In some cases parts of the configuration file <span class='code'>weewx.conf</span> must
  be modified.
</p>

<p>
  For example, to update the <span class='code'>pmon</span> extension, replace <span class='code'>bin/user/pmon.py</span>
  with the v3-compatible <span class='code'>pmon.py</span> and modify <span class='code'>weewx.conf</span> as
  shown in this table:
</p>
<table>
  <tr class="first_row">
    <td style='width:50%'>2.7</td>
    <td>3.0</td>
  </tr>
  <tr>
    <td>
      <pre class='tty'>[ProcessMonitor]
	<span class='changed'>database = pmon_sqlite</span></pre>
    </td>
    <td>
      <pre class='tty'>[ProcessMonitor]
	<span class='changed'>data_binding = pmon_binding</span></pre>
    </td>
  </tr>
  <tr>
    <td></td>
    <td>
      <pre class='tty'><span class='added'>[DataBindings]
	  [[pmon_binding]]
          database = pmon_sqlite
          manager = weewx.manager.DaySummaryManager
          table_name = archive
          schema = user.pmon.schema</span></pre>
    </td>
  </tr>
  <tr>
    <td>
      <pre class='tty'>[Databases]
	[[pmon_sqlite]]
        root = %(WEEWX_ROOT)s
        <span class='changed'>database</span> = archive/pmon.sdb
        driver = weedb.sqlite</pre>
    </td>
    <td>
      <pre class='tty'>[Databases]
	[[pmon_sqlite]]
        root = %(WEEWX_ROOT)s
        <span class='changed'>database_name</span> = archive/pmon.sdb
        driver = weedb.sqlite</pre>
    </td>
  </tr>
</table>
<p>
  For other extensions, see the extension's documentation or contact the author of the extension.
</p>

### Search list extensions

<p>
  The introduction of <em>data bindings</em> has meant a change in the calling signature of <em>search list
    extensions.</em> By way of example, here's the example from the document <a href="../sle"><i>Writing
      search list extensions</i></a>, but with the differences highlighted.
</p>
<table>
  <tbody>
    <tr class="first_row">
      <td>2.7</td>
      <td>3.0</td>
    </tr>
    <tr>
      <td><pre class="tty">def <span class="changed">get_extension</span>(self, timespan, <span
											    class="changed">archivedb, statsdb</span>):

	  all_stats = <span class="changed">TimeSpanStats</span>(
          timespan,
          <span class="changed">statsdb</span>,
          formatter=self.generator.formatter,
          converter=self.generator.converter)
	  week_dt = datetime.date.fromtimestamp(timespan.stop) - \
          datetime.timedelta(weeks=1)
	  week_ts = time.mktime(week_dt.timetuple())
	  seven_day_stats = <span class="changed">TimeSpanStats</span>(
          TimeSpan(week_ts, timespan.stop),
          <span class="changed">statsdb</span>,
          formatter=self.generator.formatter,
          converter=self.generator.converter)
	  
	  search_list_extension = {'alltime'   : all_stats,
          'seven_day' : seven_day_stats}
          
	  return search_list_extension</pre>
      </td>
      <td><pre class="tty">def <span class="changed">get_extension_list</span>(self, timespan, <span
												 class="changed">db_lookup</span>):
	  
	  all_stats = <span class="changed">TimespanBinder</span>(
          timespan, 
          <span class="changed">db_lookup</span>,
          formatter=self.generator.formatter,
          converter=self.generator.converter)
	  week_dt = datetime.date.fromtimestamp(timespan.stop) - \
          datetime.timedelta(weeks=1)
	  week_ts = time.mktime(week_dt.timetuple())
	  seven_day_stats = <span class="changed">TimespanBinder</span>(
          TimeSpan(week_ts, timespan.stop),
          <span class="changed">db_lookup</span>,
          formatter=self.generator.formatter,
          converter=self.generator.converter)
	  
	  search_list_extension = {'alltime'   : all_stats,
          'seven_day' : seven_day_stats}
          
	  return <span class="added">[</span>search_list_extension<span class="added">]</span></pre>
      </td>
    </tr>
  </tbody>
</table>
<p>A few things to note:</p>
<ul>
  <li>The name of the extension function has changed from <span class="code">get_extension</span> to <span
												       class="code">get_extension_list</span>.
  </li>
  <li>The calling signature has changed. Instead of an archive database and a stats database being passed in,
    a single <em>database lookup function</em> is passed in.
  </li>
  <li>The name of the top-level class in the tag chain has changed from <span
									  class="code">TimeSpanStats</span> to <span class="code">TimespanBinder</span>. See the <i>Customizing
      Guide</i> for details.
  </li>
  <li>Instead of returning a single search list extension, the function should now return a Python <span
												     class="code">list</span> of extensions. The list will be searched in order.
  </li>
</ul>

### Derived quantities

<p>Some calculations that were done in drivers or in hardware are now done consistently by the new
  StdWXCalculate service. Drivers should no longer calculate derived quantities such as windchill, heatindex,
  dewpoint, or rain rate.
</p>

### Driver APIs

<p>The base class for drivers has been renamed, and new, optional, methods have been defined to provide hooks
  for configuring hardware and producing default and upgraded configuration stanzas.
</p>

<p>These changes affect only those who have written custom drivers.</p>
<table>
  <tr class="first_row">
    <td style='width:50%'>2.7</td>
    <td>3.0</td>
  </tr>
  <tr>
    <td>
      <pre class='tty'>import weewx.<span class="changed">abstractstation</span>
	
	class ACME960(weewx.<span class="changed">abstractstation.AbstractStation</span>):
	...</pre>
    </td>
    <td>
      <pre class='tty'>import weewx.<span class="changed">drivers</span>
	
	class ACME960(weewx.<span class="changed">drivers.AbstractDevice</span>):
	...</pre>
    </td>
  </tr>
</table>

### Service APIs

<p>The base class for services has moved.</p>

<p>This affects only those who have written custom services.</p>
<table>
  <tr class="first_row">
    <td style='width:50%'>2.7</td>
    <td>3.0</td>
  </tr>
  <tr>
    <td>
      <pre class='tty'>import weewx.<span class="changed">wxengine</span>
	
	class BetterMousetrapService(weewx.<span class="changed">wxengine</span>.StdService):
	...</pre>
    </td>
    <td>
      <pre class='tty'>import weewx.<span class="changed">engine</span>
	
	class BetterMousetrapService(weewx.<span class="changed">engine</span>.StdService):
	...</pre>
    </td>
  </tr>
</table>

### RESTful APIs

<p>Some of the methods internal to RESTful services have changed, specifically those that relate to getting
  configuration options from <span class='code'>weewx.conf</span> and configuring databases.
</p>

<p>This affects only those who have written custom RESTful services.</p>

<p>Here is an example of obtaining the database dictionary for use in the RESTful service thread.</p>
<table>
  <tr class="first_row">
    <td style='width:50%'>2.7</td>
    <td>3.0</td>
  </tr>
  <tr>
    <td><pre class="tty">site_dict = weewx.restx.get_dict(config_dict, 'Uploader')
	db_name = config_dict['StdArchive']['archive_database']
	db_dict = config_dict['Databases'][db_name]
	site_dict.setdefault('database_dict', db_dict)</pre>
    </td>
    <td><pre class="tty">site_dict = config_dict['StdRESTful']['Uploader']
	site_dict = accumulateLeaves(site_dict, max_level=1)
	manager_dict = weewx.manager.open_manager_with_config(
	config_dict, 'wx_binding')</pre>
    </td>
  </tr>
</table>

### Database APIs

<p>The methods for obtaining, opening, and querying databases have changed. This affects only those who have
  written code that accesses databases.
</p>

<p>
  The class <span class="code">Manager</span> and its subclasses have replaced the old <span class="code">Archive</span>
  class. The table name is no longer hard-coded, so developers should use the table name from the database
  binding. There is no longer a separate <span class="code">StatsDb</span> class, its functions having been
  subsumed into the <span class="code">Manager</span> class and its subclasses.
</p>

<p>
  A new class <span class="code">DBBinder</span> is the preferred way of getting a <span
										     class="code">Manager</span> class, as it will automatically take care of instantiating the right class, as
  well as caching instances of <span class="code">Manager</span>. An instance of <span
										   class="code">DBBinder</span> is held by the engine as attribute <span class="code">db_binder</span>. Here's
  an example of making a simple query.
</p>
<table>
  <tr class="first_row">
    <td style='width:50%'>2.7</td>
    <td>3.0</td>
  </tr>
  <tr>
    <td><pre class="tty">db = config_dict['StdArchive']['archive_database']
self.database_dict = config_dict['Databases'][db]
with weewx.archive.Archive.open(self.database_dict) as archive:
    val = archive.getSql("SELECT AVG(windSpeed) FROM archive"
        " WHERE dateTime&gt;? AND dateTime&lt;=?",
        (start_ts, end_ts))</pre>
    </td>
    <td><pre class="tty">with self.engine.db_binder.get_manager('wx_binding') as mgr:
    val = mgr.getSql("SELECT AVG(windSpeed) FROM %s"
        " WHERE dateTime&gt;? AND dateTime&lt;=?" %
        mgr.table_name, (start_ts, end_ts))</pre>
    </td>
  </tr>
</table>

### Generator APIs

<p>
  The base class for report generators has changed. The old class <span
								    class="code">CachedReportGenerator</span> no longer exists; its functionality has been replaced by an
  instance of <span class="code">DBBinder</span>, held by the generator superclass. This affects only those
  who have written customer generators.
</p>

<p>Here's an example:</p>
<table>
  <tr class="first_row">
    <td style='width: 50%'>2.7</td>
    <td>3.0</td>
  </tr>
  <tr>
    <td><pre class="tty">class GaugeGenerator(weewx.reportengine.<span
								   class='changed'>CachedReportGenerator</span>)
	def run(self):
        archive_name = self.config_dict['GaugeGenerator']['archive_name']
        archive = self._getArchive(archive_name)
        results = archive.getSql(...)</pre>
    </td>
    <td><pre class="tty">class GaugeGenerator(weewx.reportengine.<span
								   class='changed'>ReportGenerator</span>)
	def run(self):
        mgr = self.generator.db_binder.get_manager()
        results = mgr.getSql(...)</pre>
    </td>
  </tr>
</table>

### Extension installer

<p>The <span class='code'>setup.py</span> utility is now included in the installation; it is no longer necessary
  to keep a copy of the WeeWX source tree just for the <span class='code'>setup.py</span> utility.
</p>

<p>For .deb and .rpm installations, the command <span class='code'>wee_setup</span> is a symlink to <span
												      class='code'>setup.py</span>.
</p>

<p>The options for installing extensions changed slightly to be more consistent with the rest of the options to
  <span class='code'>setup.py</span>.
</p>
<table>
  <tr class="first_row">
    <td style='width:50%'>2.7</td>
    <td>3.0</td>
  </tr>
  <tr>
    <td>
      <pre class='tty'>setup.py --extension --install extensions/basic
setup.py --extension --install basic.tar.gz
setup.py --extension --uninstall basic
setup.py --extension --list
setup.py --extension --install basic.tar.gz --dryrun</pre>
    </td>
    <td>
      <pre class='tty'>setup.py install --extension extensions/basic
setup.py install --extension basic.tar.gz
setup.py uninstall --extension basic
setup.py list-extensions
setup.py install --extension basic.tar.gz --dry-run</pre>
    </td>
  </tr>
</table>

## Upgrading to V2.7

<p>Version 2.7 is backwards compatible with earlier versions with one minor exception.</p>

<p>
It now includes the ability to localize the WeeWX and server uptimes. Previously, the labels <span class="code">days</span>, <span class="code">hours</span>, and <span class="code">minutes</span> were hardcoded in a Python utility. There was no way of changing them. Now, like any other labels, they are taken from the skin configuration file, <span class="code">skin.conf</span>, section <span class="code">[[Labels]]</span>. Older configuration files had a definition for <span class="code">hour</span>, but none for <span class="code">day</span>, and <span class="code">minute</span>. Also, the old definition for <span class="code">hour</span> used an abbreviation <span class="code">hrs</span> instead of <span class="code">hours</span>.
</p>

<p>If you do nothing, your WeeWX and station uptimes will look like:</p>
<pre class="tty">Weewx uptime:  1 day, 1 hrs, 41 minutes
Server uptime: 2 days, 10 hrs, 22 minutes</pre>
<p>
Note how the label for hours is abbreviated and always uses the plural. If you want the previous behavior, or if you want to localize the labels, you should update your skin configuration file. Remove the old entries for <span class="code">hour</span> and <span class="code">second</span> and replace them with:
</p>
<pre class="tty">day               = " day",    " days"
hour              = " hour",   " hours"
minute            = " minute", " minutes"
second            = " second", " seconds"</pre>

<p>The first item is the singular spelling, the second the plural. This will result in the desired</p>
<pre class="tty">Weewx uptime:  1 day, 1 hour, 41 minutes
Server uptime: 2 days, 10 hours, 22 minutes</pre>

## Upgrading to V2.6

<p>Version 2.6 is backwards compatible with earlier versions, with a couple of small exceptions.</p>
<ul>
  <li>If you have written a custom WeeWX service, the install routine will try to insert its name into an
    appropriate place in one of the five new lists of services to be run. You should check section <span
												     class="code">[Engines][[WxEngine]]</span> to make sure it made a reasonable guess.
  </li>
  <li>If you have written a custom RESTful service, the architecture for these services has completely
    changed. They are now first class services, and are treated like any other WeeWX service. There are some
    guides to writing RESTful services using the new architecture at the top of the file <span class='code'>bin/weewx/restx.py</span>.
    I can also help you with the transition.
  </li>
  <li>Option <span class='code'>interval</span> in the CWOP configuration section has become option <span
												      class='code'>post_interval</span>. This change should be done automatically by the install routine.
  </li>
  <li>The mechanism for specifying RESTful services has changed. To activate a RESTful service, put the driver
    in the <span class="code">restful_services</span> list in <span
								class="code">[Engines][[WxEngine]]</span>. The <span class="code">driver</span> parameter is no
    longer necessary in the RESTful service's configuration stanza. These changes should be done
    automatically by the install routine.
  </li>
</ul>

## Upgrading to V2.4

<p>The option <span class="code">time_length</span> will now be the exact length of the resultant plot. Before,
  a plot with <span class="code">time_length</span> equal to 24 hours would result in a plot of 27 hours, now
  it's 24 hours. If you want the old behavior, set it equal to 27 hours. To do this, change your section in
  <span class="code">skin.conf</span> from
</p>

<pre class="tty">[[day_images]]
  x_label_format = %H:%M
  bottom_label_format = %m/%d/%y %H:%M
  time_length = 86400 # == 24 hours</pre>

<p>to</p>

<pre class="tty">[[day_images]]
  x_label_format = %H:%M
  bottom_label_format = %m/%d/%y %H:%M
  <span class="highlight">time_length = 97200 # == 27 hours</span></pre>

<p>The service <span class="code">StdTimeSync</span> now synchronizes the console's onboard clock on startup.
  This is nice because if the clock failed, perhaps because the battery was taken out, the time is corrected
  first <em>before</em> data is downloaded from the logger's memory. To take advantage of this, you can move
  service <span class="code">StdTimeSync</span> to the front of the list of services to be run. For example:
</p>

<pre class="tty">[[WxEngine]]
  # The list of services the main weewx engine should run:
  service_list = <span class="highlight">weewx.wxengine.StdTimeSynch</span>, weewx.wxengine.StdConvert,
  weewx.wxengine.StdCalibrate, weewx.wxengine.StdQC, weewx.wxengine.StdArchive, weewx.wxengine.StdPrint,
  weewx.wxengine.StdRESTful, weewx.wxengine.StdReport</pre>

## Upgrading to V2.3

<p>The signature of the function "<span class="code">loader</span>", used to return an instance of the station
  device driver, has changed slightly. It has changed from
</p>

<pre class="tty">loader(config_dict)</pre>

<p>to</p>

<pre class="tty">loader(config_dict, engine)</pre>

<p>That is, a second parameter, <span class="code">engine</span>, has been added. This is a reference to the
  WeeWX engine.
</p>

<p>This change will affect only those who have written their own device driver.</p>

## Upgrading to V2.2

<p>Version 2.2 introduces a schema, found in <span class="code">
    bin/user/schemas.py</span>, for the stats database. This schema is used only when initially creating the
  database. If you have a specialized stats database, that is, one that saves types other than the default
  that comes with WeeWX, you should edit this file to reflect your changes before attempting to rebuild the
  database.
</p>

## Upgrading to V2.0

<p>Version 2.0 introduces many new features, including a revamped internal engine. There are two changes that
  are not backwards compatible:
</p>
<ul>
  <li>The configuration file, <span class="code">weewx.conf</span>. When upgrading from V1.X, the setup
    utility will install a new, fresh copy of <span class="code">weewx.conf</span>, which you will then have
    to edit by hand. Thereafter, V2.X upgrades should be automatic.
  </li>
  <li>Custom services. If you have written a custom service, it will have to be updated to use the new engine.
    The overall architecture is very similar, except that functions must be <em>bound</em> to events, rather
    than get called implicitly. See the sections <a href="customizing.htm#Customizing_a_service">Customizing
      a Service</a> and <a href="customizing.htm#Adding_a_service">Adding a Service</a> in the <a
												 href="customizing.htm">Customization Guide</a> for details on how to do this.
  </li>
</ul>
<p>All skins should be completely backwards compatible, so you should not have to change your templates or skin
  configuration file, <span class="code">skin.conf</span>.
</p>

<p>If you have written a custom report generator it should also be backwards compatible.</p>

## Upgrading to V1.14

<p>Version 1.14 introduces some new webpages that have been expressly formatted for the smartphone by using <a
													      href="http://jquery.com/">jQuery</a>.
</p>

<p>The skins shipped with the distribution take advantage of these features. If you do nothing, your old skins
  will continue to work, but you will not be taking advantage of these new webpages.
</p>

<p>If you want them, then you have two choices:</p>
<ol>
  <li>Rename your old skin directory (call it &quot;<span class="code">skins.old</span>&quot;) then do the install. This will install the new skin distribution. You can then modify it to reflect any changes you have made, referring to <span class="code"> skins.old</span> for guidance. If you have not changed many things, this approach will be the easiest.
  </li>
  <li>Alternatively, change the contents of your existing skin directory to include the new webpages. If you take this approach, you will need to copy over the contents of the subdirectory <span class="code"> skins/Standard/smartphone</span> from the distribution into your <span class="code">skins/Standard</span> directory. You will then need to modify your <span class="code">skin.conf</span>.
    <p>After the section that looks like</p>

    <pre class='tty'>[[[Mobile]]]
      template = mobile.html.tmpl</pre>

    <p>add the following directives:</p>

    <pre class='tty'>[[[MobileSmartphone]]]
      template = smartphone/index.html.tmpl
[[[MobileTempOutside]]]
      template = smartphone/temp_outside.html.tmpl
[[[MobileRain]]]
      template = smartphone/rain.html.tmpl
[[[MobileBarometer]]]
      template = smartphone/barometer.html.tmpl
[[[MobileWind]]]
      template = smartphone/wind.html.tmpl
[[[MobileRadar]]]
      template = smartphone/radar.html.tmpl</pre>

    <p>Then modify section <span class="code">[CopyGenerator]</span> to add the <span class="highlight">highlighted</span> files:
    </p>

    <pre class='tty'>[CopyGenerator]
      #
      # This section is used by the generator CopyGenerator
      #
      
      # List of files that are to be copied at the first invocation of the generator only
      copy_once = backgrounds/*, weewx.css, mobile.css, favicon.ico, <span class="highlight">smartphone/icons/*, smartphone/custom.js</span></pre>
  </li>
</ol>
<p>Whichever approach you chose, the generated files will appear in <span class="code">public_html/smartphone</span>. The start of the document root will be at <span class="code">public_html/smartphone/index.html</span>. You may want to add a link to this in the template for your main index page <span class="code">skins/Standard/index.html.tmpl</span>.
</p>

## Upgrading to V1.13

<p>Version 1.13 changed the way binding happens to the databases used in reports so that it happens much later. The upshot is that the signature of a few functions changed. Most you are unlikely to encounter. The exception is if you have written custom template <em>search lists</em>, as described in the <a href="customizing.htm">Customizing weewx guide</a>. This section has been updated to reflect the new function signatures. As a side effect, the illustrated example actually has become much simpler!
</p>

<p>No changes to skins.</p>

## Upgrading to V1.10

<p>Version 1.10 introduced several new features.</p>

### New almanac features, icon, and mobile template

<p>Version 1.10 introduces some extra almanac features, such as the azimuth and elevation of the sun and moon, or when the next solstice will be. It also includes a template formatted for smartphones, as well as an icon (&quot;<span class="code">favicon.ico</span>&quot;) that displays in your browser toolbar. The skins shipped with the distribution take advantage of these features. If you do nothing, your old skins will continue to work, but you will not take advantage of these new features.
</p>

<p>If you want these new features then you have two choices:</p>
<ol>
  <li>Rename your old skin directory (call it &quot;<span class="code">skin.old</span>&quot;) then do the install. This will install the new skin distribution. You can modify it to reflect any changes you have made, referring to <span class="code">skin.old</span> for guidance.
  </li>
  <li>Alternatively, change the contents of your existing skin directory to take advantage of the new features. If you take this approach, you will need to copy over files <span class="code">favicon.ico, mobile.css</span>, and <span class="code">mobile.html.tmpl</span> from the distribution into your <span class="code">skin/Standard</span> directory. Modify <span class="code">skins/Standard/index.html.tmpl</span> to take advantage of the new almanac features, using the version shipped with the distribution for guidance. You will then need to modify your <span class="code">skin.conf</span>.
    <p>Add a new <span class="code">[[[Mobile]]]</span> section:</p>

    <pre class="tty">[FileGenerator]
  ...
  [[ToDate]]
      ...
      [[[Mobile]]]
          template = mobile.html.tmpl</pre>

    <p>Then add <span class="code">mobile.css</span> and <span class="code"> favicon.ico</span> to the list of files to be copied on report generation:
    </p>

    <pre class="tty">[CopyGenerator]
      copy_once = backgrounds/*, weewx.css, mobile.css, favicon.ico</pre>
  </li>
</ol>
<p>Which approach you should take will depend on how extensively you have modified the stock skin distribution. If the modifications are slight, approach #1 will be easier, otherwise use approach #2.
</p>

### Backwards compatibility

<p>With the introduction of explicit control of output units in the templates such as</p>

<pre class="tty">$day.outTemp.max.degree_C</pre>

<p>the calling signature of the following two Python classes was changed</p>
<ul>
  <li><span class="code">weewx.stats.TaggedStats</span></li>
  <li><span class="code">weewx.stats.TimeSpanStats</span></li>
</ul>
<p>The example of writing a custom generator <span class="code">MyFileGenerator</span> (which produced &quot;all time&quot; statistics) has been changed to reflect the new signatures.
</p>

<p>This will only affect you if you have written a custom generator.</p>

## Upgrading to V1.8

<p>With the introduction of a standard archiving service, <span class="code"> StdArchive</span>, the names of some events have changed. This will not affect you unless you have written a custom service.
</p>

## Upgrading to V1.7

<p>V1.7 introduces <em>skins</em>. The skins live in subdirectory <span class="code">skins</span>. They are <em>not</em> compatible with the old <span class="code">template</span> subdirectory --- you can&#39;t simply rename <span class="code">templates</span> to <span class="code">skins</span>.
</p>

<p>The part of the configuration file dealing with the presentation layer has been split off into a separate file <span class="code">skin.conf</span>. Hence, once again, the installation script <span class="code">setup.py</span> will NOT merge your old <span class="code"> weewx.conf</span> configuration file into the new one. You will have to re-edit <span class="code">weewx.conf</span> to put in your customizations. You may also have to edit <span class="code"> skin.conf</span> for whatever skin you choose (right now, only one skin, <em>Standard</em>, comes with the distribution).
</p>

<p>However, a reinstall of V1.7 <em>will</em> merge your changes for <span class="code">weewx.conf</span>. It will also merge any changes you have made to <span class="code">skin.conf</span> as well.
</p>

<p>Please check the following:</p>
<ul>
  <li>Option &quot;<span class="code">altitude</span>&quot; in section <span class="code">[Station]</span> now takes a unit. Hence, it should look something like:
    <pre class='tty'>altitude = 120, meter</pre>

  </li>
  <li>In a similar manner, options <span class="code">heating_base</span> and <span
										class="code">cooling_base</span> in <span class="code">skin.conf</span> also take units:
    <pre class='tty'>heating_base = 65, degree_F
cooling_base = 65, degree_F</pre>
  </li>
</ul>
<p>The directory &#39;<span class="code">templates</span>&#39; is no longer used; it has been replaced with directory &#39;<span class="code">skins</span>&#39;. You may delete it if you wish:
</p>

<pre class="tty cmd">rm -r templates</pre>

## Upgrading to V1.5

<p>Because the configuration file <span class="code">weewx.conf</span> changed significantly going from V1.4 to V1.5, the installation script <span class="code">setup.py</span> will NOT merge your old configuration file into the new one. You will have to re-edit <span class="code">weewx.conf</span> to put in your customizations.
</p>

## Upgrading to V1.4

<p>Option <span class="code">clock_check</span>, previously found in the <span class="code">[VantagePro]</span> section, is now found in the <span class="code">[Station]</span> section. The install program will put a default value in the new place, but it will not delete nor move your old value over. If you have changed this value or if you cannot stand the thought of <span class="code">clock_check</span> appearing in two different places, you should delete the old one found under <span class="code">[VantagePro]</span> and make sure the new value, found under <span class="code">[Station]</span> is correct.
</p>

<p>Two Python files are no longer used, so they may be deleted from your installation if you wish:</p>

<pre class="tty cmd">rm bin/weewx/processdata.py
rm bin/weewx/mainloop.py</pre>

<p>In addition, file <span class="code">readme.htm</span> has been moved to subdirectory <span class='code'>docs</span>, so the old one can be deleted:
</p>

<pre class="tty cmd">rm readme.htm</pre>
