Hallo Gary,
have at test01.txt
root@acer:/home/weewx/bin/user# date
Sa 11. Mär 13:34:38 CET 2017
root@acer:/home/weewx/bin/user# ./weewxwd_config.py --clear-v2-data
--wx-binding=wx_binding
Using configuration file /home/weewx/weewx.conf
Using database binding 'wx_binding', which is bound to database
'archive_mysql'
Using database binding 'wd_binding', which is bound to database 'wd_mysql'
row [264897, 262985]
'extraTemp1' and 'extraTemp2' data in database 'weewxAlt' from 2013-10-31
22:19:00 CET (1383254340) to 2017-03-11 13:30:00 CET (14892
35400) (approx 1227 days) is about to be cleared. Any data in these fields
will be irretrievably lost.
Are you sure you wish to proceed (y/n)? y
Done. 'extraTemp1' and 'extraTemp2' cleared in 351365 records (approx 1227
days).
root@acer:/home/weewx/bin/user# date
Sa 11. Mär 13:50:26 CET 2017
Hartmut
#
#
# See the file LICENSE.txt for your full rights.
#
# air.py 2766 2015-05-09 02:45:36Z hes $
#
"""The air schema, which is also used by weewx."""
schema = [
('dateTime', 'INTEGER NOT NULL PRIMARY KEY'),
('usUnits', 'INTEGER NOT NULL'),
('interval', 'INTEGER NOT NULL'),
('air_sensor','INTEGER'),
('gas_sensor','INTEGER'),
('hcho_sensor','INTEGER'),
('water_sensor','INTEGER'),
('light_sensor','INTEGER'),
('uv_sensor','INTEGER'),
('gasC_sensor','INTEGER'),
('gasO_sensor','INTEGER'),
('gasN_sensor','INTEGER'),
('gasx_sensor','INTEGER'),
('lightD_sensor','INTEGER'),
('dust_sensor','INTEGER'),
('lightIn_sensor','INTEGER'),
('adc_sensor' 'INTEGER'),
('temp','INTEGER'),
('pressure','INTEGER'),
('altitude','INTEGER'),
]
#
# Copyright (c) 2011 Tom Keffer <[email protected]>
#
# See the file LICENSE.txt for your full rights.
#
# $Revision: 1459 $
# $Author: mwall $
# $Date: 2013-10-08 17:44:50 -0700 (Tue, 08 Oct 2013) $
#
"""Database schemas used by weewx"""
#===============================================================================
# This is a list containing the default schema of the archive database. It is
# identical to what is used by wview. It is only used for initialization ---
# afterwards, the schema is obtained dynamically from the database. Although a
# type may be listed here, it may not necessarily be supported by your weather
# station hardware.
#
# You may trim this list of any unused types if you wish, but it will not
# result in saving as much space as you may think --- most of the space is
# taken up by the primary key indexes (type "dateTime").
# =============================================================================
schema = [('dateTime', 'INTEGER NOT NULL UNIQUE PRIMARY KEY'),
('usUnits', 'INTEGER NOT NULL'),
('interval', 'INTEGER NOT NULL'),
('barometer', 'REAL'),
('pressure', 'REAL'),
('altimeter', 'REAL'),
('inTemp', 'REAL'),
('outTemp', 'REAL'),
('inHumidity', 'REAL'),
('outHumidity', 'REAL'),
('windSpeed', 'REAL'),
('windDir', 'REAL'),
('windGust', 'REAL'),
('windGustDir', 'REAL'),
('rainRate', 'REAL'),
('rain', 'REAL'),
('dewpoint', 'REAL'),
('windchill', 'REAL'),
('heatindex', 'REAL'),
('ET', 'REAL'),
('radiation', 'REAL'),
('UV', 'REAL'),
('extraTemp1', 'REAL'),
('extraTemp2', 'REAL'),
('extraTemp3', 'REAL'),
('soilTempO1', 'REAL'),
('soilTempO2', 'REAL'),
('soilTempO3', 'REAL'),
('soilTempO4', 'REAL'),
('soilTempO5', 'REAL'),
('leafTemp1', 'REAL'),
('leafTemp2', 'REAL'),
('extraHumid1', 'REAL'),
('extraHumid2', 'REAL'),
('soilMoist1', 'REAL'),
('soilMoist2', 'REAL'),
('soilMoist3', 'REAL'),
('soilMoist4', 'REAL'),
('leafWet1', 'REAL'),
('leafWet2', 'REAL'),
('rxCheckPercent', 'REAL'),
('txBatteryStatus', 'REAL'),
('consBatteryVoltage', 'REAL'),
('hail', 'REAL'),
('hailRate', 'REAL'),
('heatingTemp', 'REAL'),
('heatingVoltage', 'REAL'),
('supplyVoltage', 'REAL'),
('referenceVoltage', 'REAL'),
('windBatteryStatus', 'REAL'),
('rainBatteryStatus', 'REAL'),
('outTempBatteryStatus', 'REAL'),
('lighting', 'REAL'),
('extraTemp4', 'REAL'),
('extraTemp5', 'REAL'),
('extraTemp6', 'REAL'),
('extraTemp7', 'REAL'),
('extraTemp8', 'REAL'),
('extraTemp9', 'REAL'),
('maxSolarRad', 'REAL'),
('cloudbase', 'REAL'),
('humidex', 'REAL'),
('appTemp', 'REAL'),
('windrun', 'REAL'),
('beaufort', 'REAL'),
('inDewpoint', 'REAL'),
('inTempBatteryStatus', 'REAL'),
('sunshinehours', 'REAL'),
('sunshineS', 'REAL'),
('snow', 'REAL'),
('snowRate', 'REAL'),
('snowTotal', 'REAL'),
('wetBulb', 'REAL'),
('cbIndex', 'REAL'),
('airDensity', 'REAL'),
('windDruck', 'REAL'),
('soilTemp1', 'REAL'),
('soilTemp2', 'REAL'),
('soilTemp3', 'REAL'),
('soilTemp4', 'REAL'),
('soilTemp5', 'REAL')]
root@acer:/home/weewx/bin/user# date
Sa 11. Mär 13:34:38 CET 2017
root@acer:/home/weewx/bin/user# ./weewxwd_config.py --clear-v2-data
--wx-binding=wx_binding
Using configuration file /home/weewx/weewx.conf
Using database binding 'wx_binding', which is bound to database 'archive_mysql'
Using database binding 'wd_binding', which is bound to database 'wd_mysql'
row [264897, 262985]
'extraTemp1' and 'extraTemp2' data in database 'weewxAlt' from 2013-10-31
22:19:00 CET (1383254340) to 2017-03-11 13:30:00 CET (1489235400) (approx 1227
days) is about to be cleared. Any data in these fields will be irretrievably
lost.
Are you sure you wish to proceed (y/n)? y
Done. 'extraTemp1' and 'extraTemp2' cleared in 351365 records (approx 1227
days).
root@acer:/home/weewx/bin/user# date
Sa 11. Mär 13:50:26 CET 2017
root@acer:~# tail -f /var/log/syslog
Mar 11 13:35:16 acer weewx[27974]: manager: Added record 2017-03-11 13:35:00
CET (1489235700) to database 'weewxAlt'
Mar 11 13:35:17 acer weewx[27974]: manager: Added record 2017-03-11 13:35:00
CET (1489235700) to daily summary in 'weewxAlt'
Mar 11 13:35:17 acer weewx[27974]: manager: Added record 2017-03-11 13:35:17
CET (1489235717) to database 'cmonacer'
Mar 11 13:35:17 acer weewx[27974]: manager: Added record 2017-03-11 13:35:17
CET (1489235717) to daily summary in 'cmonacer'
Mar 11 13:35:17 acer weewx[27974]: manager: Added record 2017-03-11 13:35:00
CET (1489235700) to database 'weewxAltWD'
Mar 11 13:35:17 acer weewx[27974]: manager: Added record 2017-03-11 13:35:00
CET (1489235700) to daily summary in 'weewxAltWD'
Mar 11 13:35:18 acer weewx[27974]: WdSuppArchive: Downloaded updated Weather
Underground information for conditions/forecast
Mar 11 13:36:01 acer CRON[3380]: (root) CMD (/home/dwd/foredwd.py 1>/dev/null
2>&1)
Mar 11 13:36:01 acer CRON[3381]: (root) CMD (/home/bild/ip_cam.sh 1>/dev/null
2>&1)
Mar 11 13:37:01 acer CRON[3413]: (root) CMD (/home/bild/ip_cam.sh 1>/dev/null
2>&1)
Mar 11 13:38:01 acer CRON[3445]: (root) CMD (/home/bild/ip_cam.sh 1>/dev/null
2>&1)
Mar 11 13:38:26 acer weewx[27974]: cheetahgenerator: Generated 41 files for
report StandardReport in 188.43 seconds
Mar 11 13:38:29 acer weewx[27974]: imagegenerator: Generated 59 images for
StandardReport in 3.00 seconds
Mar 11 13:38:29 acer weewx[27974]: copygenerator: copied 0 files to
/home/weewx/public_html
Mar 11 13:38:29 acer weewx[27974]: imageStackedWindRose: Generated 2 images for
WindRose in 0.11 seconds
Mar 11 13:38:30 acer weewx[27974]: cheetahgenerator: Generated 6 files for
report simplicity in 1.06 seconds
Mar 11 13:38:31 acer weewx[27974]: imagegenerator: Generated 19 images for
simplicity in 0.90 seconds
Mar 11 13:38:31 acer weewx[27974]: copygenerator: copied 0 files to
/home/weewx/public_html/sc
Mar 11 13:39:01 acer CRON[3483]: (root) CMD (/home/bild/ip_cam.sh 1>/dev/null
2>&1)
Mar 11 13:39:01 acer CRON[3486]: (root) CMD ( [ -x /usr/lib/php5/sessionclean
] && /usr/lib/php5/sessionclean)
Mar 11 13:40:01 acer CRON[3567]: (root) CMD (if [ -x /etc/munin/plugins/apt_all
]; then /etc/munin/plugins/apt_all update 7200 12 >/dev/null; elif [ -x
/etc/munin/plugins/apt ]; then /etc/munin/plugins/apt update 7200 12
>/dev/null; fi)
Mar 11 13:40:01 acer CRON[3568]: (root) CMD (/home/bild/ip_cam.sh 1>/dev/null
2>&1)
Mar 11 13:40:16 acer weewx[27974]: manager: Added record 2017-03-11 13:40:00
CET (1489236000) to database 'weewxAlt'
Mar 11 13:40:17 acer weewx[27974]: manager: Added record 2017-03-11 13:40:00
CET (1489236000) to daily summary in 'weewxAlt'
Mar 11 13:40:17 acer weewx[27974]: manager: Added record 2017-03-11 13:40:18
CET (1489236018) to database 'cmonacer'
Mar 11 13:40:17 acer weewx[27974]: manager: Added record 2017-03-11 13:40:18
CET (1489236018) to daily summary in 'cmonacer'
Mar 11 13:40:17 acer weewx[27974]: manager: Added record 2017-03-11 13:40:00
CET (1489236000) to database 'weewxAltWD'
Mar 11 13:40:17 acer weewx[27974]: manager: Added record 2017-03-11 13:40:00
CET (1489236000) to daily summary in 'weewxAltWD'
#
# Copyright (c) 2011 Tom Keffer <[email protected]>
#
# See the file LICENSE.txt for your full rights.
#
# $Revision: 1459 $
# $Author: mwall $
# $Date: 2013-10-08 17:44:50 -0700 (Tue, 08 Oct 2013) $
#
"""Database schemas used by weewx"""
#===============================================================================
# This is a list containing the default schema of the archive database. It is
# identical to what is used by wview. It is only used for initialization ---
# afterwards, the schema is obtained dynamically from the database. Although a
# type may be listed here, it may not necessarily be supported by your weather
# station hardware.
#
# You may trim this list of any unused types if you wish, but it will not
# result in saving as much space as you may think --- most of the space is
# taken up by the primary key indexes (type "dateTime").
# =============================================================================
schema = [('dateTime', 'INTEGER NOT NULL UNIQUE PRIMARY KEY'),
('usUnits', 'INTEGER NOT NULL'),
('interval', 'INTEGER NOT NULL'),
('barometer', 'REAL'),
('pressure', 'REAL'),
('altimeter', 'REAL'),
('inTemp', 'REAL'),
('outTemp', 'REAL'),
('inHumidity', 'REAL'),
('outHumidity', 'REAL'),
('windSpeed', 'REAL'),
('windDir', 'REAL'),
('windGust', 'REAL'),
('windGustDir', 'REAL'),
('rainRate', 'REAL'),
('rain', 'REAL'),
('dewpoint', 'REAL'),
('windchill', 'REAL'),
('heatindex', 'REAL'),
('ET', 'REAL'),
('radiation', 'REAL'),
('UV', 'REAL'),
('extraTemp1', 'REAL'),
('extraTemp2', 'REAL'),
('extraTemp3', 'REAL'),
('soilTemp1', 'REAL'),
('soilTemp2', 'REAL'),
('soilTemp3', 'REAL'),
('soilTemp4', 'REAL'),
('leafTemp1', 'REAL'),
('leafTemp2', 'REAL'),
('extraHumid1', 'REAL'),
('extraHumid2', 'REAL'),
('soilMoist1', 'REAL'),
('soilMoist2', 'REAL'),
('soilMoist3', 'REAL'),
('soilMoist4', 'REAL'),
('leafWet1', 'REAL'),
('leafWet2', 'REAL'),
('rxCheckPercent', 'REAL'),
('txBatteryStatus', 'REAL'),
('consBatteryVoltage', 'REAL'),
('hail', 'REAL'),
('hailRate', 'REAL'),
('heatingTemp', 'REAL'),
('heatingVoltage', 'REAL'),
('supplyVoltage', 'REAL'),
('referenceVoltage', 'REAL'),
('windBatteryStatus', 'REAL'),
('rainBatteryStatus', 'REAL'),
('outTempBatteryStatus', 'REAL'),
('lighting', 'REAL'),
('extraTemp4', 'REAL'),
('extraTemp5', 'REAL'),
('soilTemp5', 'REAL'),
('extraTemp6', 'REAL'),
('extraTemp7', 'REAL'),
('extraTemp8', 'REAL'),
('extraTemp9', 'REAL'),
('maxSolarRad', 'REAL'),
('cloudbase', 'REAL'),
('humidex', 'REAL'),
('appTemp', 'REAL'),
('windrun', 'REAL'),
('beaufort', 'REAL'),
('inDewpoint', 'REAL'),
('inTempBatteryStatus', 'REAL'),
('sunshinehours', 'REAL'),
('sunshineS', 'REAL'),
('snow', 'REAL'),
('snowRate', 'REAL'),
('wetBulb', 'REAL'),
('cbIndex', 'REAL'),
('airDensity', 'REAL'),
('windDruck', 'REAL'),
('soilMoist01', 'REAL'),
('soilMoist02', 'REAL'),
('soilMoist03', 'REAL'),
('soilMoist04', 'REAL'),
('soilTemp01', 'REAL'),
('soilTemp02', 'REAL'),
('soilTemp03', 'REAL'),
('soilTemp04', 'REAL'),
('leafWet01', 'REAL')]
##
##This program is free software; you can redistribute it and/or modify it under
##the terms of the GNU General Public License as published by the Free Software
##Foundation; either version 2 of the License, or (at your option) any later
##version.
##
##This program is distributed in the hope that it will be useful, but WITHOUT
##ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
##FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
##details.
##
## Version: 1.2.0b1 Date: 1 August 2015
##
## Revision History
## ?? August 2015 v1.2.0 -removed Weewx-WD schema data from
## weewxwd3.py
##
"""The Weewx-WD schemas"""
# =============================================================================
# These lists contain the default schema of the Weewx-WD archive table and the
# supp table. They are only used for initialization, or in conjunction with the
# weewxwd_config --create-database and --reconfigure options. Otherwise, once
# the tables are created the schema is obtained dynamically from the database.
# Although a type may be listed here, it may not necessarily be supported by
# your weather station hardware.
#
# You may trim this list of any unused types if you wish, but it will not
# result in saving as much space as you may think --- most of the space is
# taken up by the primary key indexes (type "dateTime").
# =============================================================================
#
WDSCHEMA_VERSION = '1.2.0b1'
# Define schema for archive table
weewxwd_schema = [
('dateTime', 'INTEGER NOT NULL UNIQUE PRIMARY KEY'),
('usUnits', 'INTEGER NOT NULL'),
('interval', 'INTEGER NOT NULL'),
('humidex', 'REAL'),
('appTemp', 'REAL'),
('outTempDay', 'REAL'),
('outTempNight', 'REAL'),
('sunshinehours', 'REAL'),
('sunshineS', 'REAL'),
('maxSolarRad', 'REAL'),
('maxSolarRadV', 'REAL'),
('cloudbase', 'REAL'),
('windDruck', 'REAL'),
('airDensity', 'REAL'),
('wetBulb', 'REAL'),
('cbIndex', 'REAL'),
('beaufort', 'REAL'),
('windrun', 'REAL'),
]
# Define schema for supp table
wdsupp_schema = [
('dateTime', 'INTEGER NOT NULL UNIQUE PRIMARY KEY'),
('usUnits', 'INTEGER NOT NULL'),
('interval', 'INTEGER NOT NULL'),
('forecastIcon', 'INTEGER'),
('forecastText', 'VARCHAR(256)'),
('forecastTextMetric', 'VARCHAR(256)'),
('currentIcon', 'INTEGER'),
('currentText', 'VARCHAR(256)'),
('tempRecordHigh', 'REAL'),
('tempNormalHigh', 'REAL'),
('tempRecordHighYear', 'INTEGER'),
('tempRecordLow', 'REAL'),
('tempNormalLow', 'REAL'),
('tempRecordLowYear', 'INTEGER'),
('vantageForecastIcon', 'INTEGER'),
('vantageForecastRule', 'VARCHAR(256)'),
('stormRain', 'REAL'),
('stormStart', 'INTEGER'),
('maxSolarRad', 'REAL'),
('maxSolarRadV', 'REAL'),
('visibility_km', 'REAL'),
('pop', 'REAL'),
('vantageForecastNumber', 'REAL'),
]
# WEEWX CONFIGURATION FILE
#
# Copyright (c) 2009-2015 Tom Keffer <[email protected]>
# See the file LICENSE.txt for your rights.
##############################################################################
# This section is for general configuration information.
# Set to 1 for extra debug info, otherwise comment it out or set to zero
debug = 0
# Root directory of the weewx data file hierarchy for this station
WEEWX_ROOT = /home/weewx
# How long to wait before timing out a socket (FTP, HTTP) connection
socket_timeout = 20
# Do not modify this. It is used when installing and updating weewx.
version = 3.7.0b4
loop_on_init = True
##############################################################################
# This section is for information about the station.
[Station]
# Description of the station location
location = "Klein Rogahn, M-V, Deutschland"
# Latitude and longitude in decimal degrees
latitude = 53.6059563
longitude = 11.341407
# Altitude of the station, with unit it is in. This is downloaded from
# from the station if the hardware supports it.
altitude = 52.8, meter # Choose 'foot' or 'meter' for unit
# Set to type of station hardware. There must be a corresponding stanza
# in this file with a 'driver' parameter indicating the driver to be used.
#station_type = Vantage
station_type = Simulator
# The start of the rain year (1=January; 10=October, etc.). This is
# downloaded from the station if the hardware supports it.
rain_year_start = 1
# Start of week (0=Monday, 6=Sunday)
week_start = 0
# If you have a website, you may specify an URL
#station_url = http://wetter.hes61.de
wind_height = 10.6
###################################################################################
[Simulator]
# This section is for the weewx weather station simulator
# The time (in seconds) between LOOP packets.
loop_interval = 2.5
mode = simulator
#mode = generator
#start = 2011-01-01 00:00
driver = weewx.drivers.simulator
##############################################################################
[Vantage]
type = serial
port = /dev/ttyUSB0
driver = weewx.drivers.vantage
#############################################################################
# This section is for uploading data to Internet sites
[StdRESTful]
[[StationRegistry]]
# To register this weather station with weewx, set this to true
register_this_station = false
[[AWEKAS]]
# This section is for configuring posts to AWEKAS.
# If you wish to do this, set the option 'enable' to true,
# and specify a username and password.
enable = false
#username =
#password =
[[CWOP]]
# This section is for configuring posts to CWOP.
# If you wish to do this, set the option 'enable' to true,
# and specify the station ID (e.g., CW1234).
enable = false
#station = E
[[PWSweather]]
# This section is for configuring posts to PWSweather.com.
# If you wish to do this, set the option 'enable' to true,
# and specify a station and password.
enable = false
#station = h
#password =
[[WOW]]
# This section is for configuring posts to WOW.
# If you wish to do this, set the option 'enable' to true,
# and specify a station and password.
enable = false
#station = replace_me
#password = replace_me
[[Wunderground]]
# This section is for configuring posts to the Weather Underground.
# If you wish to do this, set the option 'enable' to true,
# and specify a station (e.g., 'KORHOODR3') and password.
enable = false
#station = I0
#password =
# Set the following to True to have weewx use the WU "Rapidfire"
# protocol. Not all hardware can support it. See the User's Guide.
rapidfire = False
[[WindFinder]]
#station_id = klein-rogahn
#password =
[[Wetter]]
#username =
#password =
[[WeatherCloud]]
#key = ef9a5006fa
[[OpenWeatherMap]]
#username =
#password =
#station_name = KleinRogahn
[[WindGuru]]
#station_id =
#password =
##############################################################################
# This section specifies what reports, using which skins, to generate.
[StdReport]
# Where the skins reside, relative to WEEWX_ROOT
SKIN_ROOT = skins
# Where the generated reports should go, relative to WEEWX_ROOT
HTML_ROOT = public_html
# The database binding indicates which data should be used in reports.
data_binding = wx_binding
# Each of the following subsections defines a report that will be run.
[[StandardReport]]
# See the customizing guide to change the units, plot types and line
# colors, modify the fonts, display additional sensor data, and other
# customizations. Many of those changes can be made here by overriding
# parameters, or by modifying templates within the skin itself.
# The StandardReport uses the 'Standard' skin, which contains the
# images, templates and plots for the report.
skin = Standard
[[[Units]]]
[[[[Groups]]]]
group_altitude = meter
group_speed2 = km_per_hour2
group_pressure = mbar
group_rain = mm
group_rainrate = mm_per_hour
group_temperature = degree_C
group_degree_day = degree_C_day
group_speed = km_per_hour
[[[CheetahGenerator]]]
search_list_extensions = user.xstats.ExtendedStatistics,
user.forecast.ForecastVariables, user.xlastrain.MyXLastrain,
user.xlastrain.MyXLastsnow, user.xseason.MyXSeason, user.xastro.MyXMoonApsis,
user.xastro.MyXEclipse, user.xastro.MyXEarthApsis, user.xyear.xMyEaster,
user.xwindrose.windroseData, user.xrainno.MyXRainNo
#[[SteelSeries]]
# skin = ss
# HTML_ROOT = public_html/ss
[[WindRose]]
skin = wr
HTML_ROOT = public_html/wr
[[simplicity]]
skin = simplicity
HTML_ROOT = public_html/sc
[[FTP]]
# FTP'ing the results to a webserver is treated as just another report,
# albeit one with an unusual report generator!
skin = Ftp
# If you wish to use FTP, uncomment and fill out the next four lines.
secure_ftp = False
# Most FTP servers use port 21
port = 21
# Set to 1 to use passive mode, zero for active mode
passive = 1
# To upload files from something other than what HTML_ROOT is set
# to above, specify a different HTML_ROOT here.
HTML_ROOT = public_html
# If you wish to use FTP, uncomment and fill out the next four lines:
#user =
#password =
#server =
#path = /
[[RSYNC]]
# rsync'ing to a webserver is treated as just another report
skin = Rsync
HTML_ROOT = /home/weewx/skins
# If you wish to use rsync, you must configure passwordless ssh using
# public/private key authentication from the user account that weewx
# runs as to the user account on the remote machine where the files
# will be copied.
#
# The following three lines determine where files will be sent.
#server = replace with the rsync server name, e.g, www.threefools.org
#path = replace with the rsync destination directory (e.g., /weather)
#user = replace with the rsync username
# Rsync can be configured to remove files from the remote server if
# they don't exist under HTML_ROOT locally. USE WITH CAUTION: if you
# make a mistake in the remote path, you could could unintentionally
# cause unrelated files to be deleted. Set to 1 to enable remote file
# deletion, zero to allow files to accumulate remotely.
delete = 0
#[[isswatch]]
# url =
https://spotthestation.nasa.gov/sightings/xml_files/Germany_None_Lubeck.xml
# skin = isswatch
# HTML_ROOT = public_html/iss
##############################################################################
# This service acts as a filter, converting the unit system coming from
# the hardware to a unit system in the database.
[StdConvert]
# The target_unit affects only the unit system in the database. Once
# chosen it cannot be changed without converting the entire database.
# Modification of target_unit after starting weewx will result in
# corrupt data - the database will contain a mix of US and METRIC data.
#
# The value of target_unit does not affect the unit system for
# reporting - reports can display US, Metric, or any combination of units.
#
# In most cases, target_unit should be left as the default: US
#
# In particular, those migrating from a standard wview installation
# should use US since that is what the wview database contains.
# DO NOT MODIFY THIS VALUE UNLESS YOU KNOW WHAT YOU ARE DOING!
target_unit = METRIC # Options are 'US', 'METRICWX', or 'METRIC'
##############################################################################
# This section can adjust data using calibration expressions.
[StdCalibrate]
[[Corrections]]
# For each type, an arbitrary calibration expression can be given.
# It should be in the units defined in the StdConvert section.
# Example:
lighting = radiation * 130
extraTemp6 = extraTemp1
extraTemp7 = extraTemp3
extraTemp8 = extraTemp2
extraTemp9 = extraTemp1
##############################################################################
# This section is for quality control checks. If units are not specified,
# values must be in the units defined in the StdConvert section.
[StdQC]
[[MinMax]]
barometer = 540, 1100, hPa
outTemp = -60, 120, degree_C
inTemp = -10, 120, degree_C
outHumidity = 0, 100
inHumidity = 0, 100
windSpeed = 0, 220, km_per_hour
pressure = 540, 1200, hPa
extraHumid1 = 0, 100
extraHumid2 = 0, 100
rain = 0, 160, mm
##############################################################################
# This section controls the origin of derived values.
[StdWXCalculate]
[[Calculations]]
# Derived quantities are calculated by this service. Possible values
are:
# hardware - use the value provided by hardware
# software - use the value calculated by weewx
# prefer_hardware - use value provide by hardware if available,
# otherwise use value calculated by weewx
pressure = prefer_hardware
barometer = prefer_hardware
altimeter = prefer_hardware
windchill = prefer_hardware
heatindex = prefer_hardware
dewpoint = prefer_hardware
inDewpoint = prefer_hardware
rainRate = prefer_hardware
ET = prefer_hardware
windrun = software
airDensity = software
windDruck = software
wetBulb = software
cbIndex = software
sunshineS = software
##############################################################################
# For hardware that supports it, this section controls how often the
# onboard clock gets updated.
[StdTimeSynch]
# How often to check the weather station clock for drift (in seconds)
clock_check = 14400
# How much it can drift before we will correct it (in seconds)
max_drift = 5
##############################################################################
# This section is for configuring the archive service.
[StdArchive]
# If the station hardware supports data logging then the archive interval
# will be downloaded from the station. Otherwise, specify it (in seconds).
archive_interval = 300
# If possible, new archive records are downloaded from the station
# hardware. If the hardware does not support this, then new archive
# records will be generated in software.
# Set the following to "software" to force software record generation.
record_generation = hardware
# Whether to include LOOP data in hi/low statistics
loop_hilo = True
# The data binding used to save archive records
data_binding = wx_binding
##############################################################################
# This section binds a data store to a database.
[DataBindings]
[[wx_binding]]
# The database must match one of the sections in [Databases].
# This is likely to be the only option you would want to change.
database = archive_mysql
# The name of the table within the database
table_name = archive
# The manager handles aggregation of data for historical summaries
manager = weewx.wxmanager.WXDaySummaryManager
# The schema defines the structure of the database.
# It is *only* used when the database is created.
schema = schemas.schemas.schema
[[wx3080_binding]]
# The database must match one of the sections in [Databases]
database = wx3080_mysql
table_name = archive
manager = weewx.wxmanager.WXDaySummaryManager
schema = schemas.wx3080.schema
[[vantage_binding]]
# The database must match one of the sections in [Databases]
database = vantage_mysql
table_name = archive
manager = weewx.wxmanager.WXDaySummaryManager
schema = schemas.vantage.schema
[[wd_binding]]
# The database must match one of the sections in [Databases]
database = wd_mysql
table_name = archive
manager = weewx.wxmanager.WXDaySummaryManager
schema = schemas.wdSchema.weewxwd_schema
[[air_binding]]
# The database must match one of the sections in [Databases]
database = air_mysql
table_name = archive
manager = weewx.wxmanager.WXDaySummaryManager
schema = schemas.air.schema
[[air2_binding]]
# The database must match one of the sections in [Databases]
database = air2_mysql
table_name = archive
manager = weewx.wxmanager.WXDaySummaryManager
schema = schemas.air2.schema
[[forecast_binding]]
database = forecast_mysql
table_name = archive
schema = user.forecast.schema
manager = weewx.manager.Manager
[[lightning_binding]]
database = blitz_mysql
table_name = archive
manager = weewx.manager.Manager
#schema = user.as3935.schema
[[cmon_binding]]
manager = weewx.manager.DaySummaryManager
schema = user.cmon.schema
table_name = archive
database = cmon_mysql
[[wdsupp_binding]]
manager = weewx.manager.Manager
schema = schemas.wdSchema.wdsupp_schema
table_name = supp
database = wdsupp_mysql
##############################################################################
# This section defines various databases.
[Databases]
# A SQLite database is simply a single file
[[archive_sqlite]]
database_type = SQLite
database_name = weewx.sdb
#############################################
# MySQL
[[archive_mysql]]
database_type = MySQL
database_name = weewxAlt
[[wx3080_mysql]]
database_type = MySQL
database_name = weewx3080
[[vantage_mysql]]
database_type = MySQL
database_name = weewx
[[wd_mysql]]
database_type = MySQL
database_name = weewxAltWD
[[air_mysql]]
database_type = MySQL
database_name = airair
[[air2_mysql]]
database_type = MySQL
database_name = airpm25
[[forecast_mysql]]
database_type = MySQL
database_name = forecasthes
[[blitz_mysql]]
database_type = MySQL
database_name = lightningair
[[cmon_mysql]]
database_type = MySQL
database_name = cmonacer
[[wdsupp_mysql]]
database_type = MySQL
database_name = wdsuppacer
##############################################################################
# This section defines defaults for the different types of databases.
[DatabaseTypes]
# Defaults for SQLite databases
[[SQLite]]
driver = weedb.sqlite
# Directory in which the database files are located
SQLITE_ROOT = /home/weewx/archive
[[MySQL]]
driver = weedb.mysql
# The host where the database is located
host = 192.168.38.35
# The user name for logging in to the host
user =
# The password for the user name
password =
##############################################################################
# This section configures the internal weewx engine.
[Engine]
[[Services]]
# This section specifies the services that should be run. They are
# grouped by type, and the order of services within each group
# determines the order in which the services will be run.
prep_services = weewx.engine.StdTimeSynch
data_services = user.snowhes.SnowDepth # user.owfs.OWFSService
process_services = weewx.engine.StdConvert, weewx.engine.StdCalibrate,
weewx.engine.StdQC, weewx.wxservices.StdWXCalculate, user.weewxwd3.WdWXCalculate
archive_services = weewx.engine.StdArchive, user.cmon.ComputerMonitor,
user.weewxwd3.WdArchive, user.weewxwd3.WdSuppArchive
#, user.weewxwd3.WdSuppArchive, user.forecast.ZambrettiForecast,
user.forecast.WUForecast, user.forecast.OWMForecast, user.forecast.AerisForecast
restful_services = ,
# weewx.restx.StdStationRegistry, weewx.restx.StdWunderground,
weewx.restx.StdPWSweather, weewx.restx.StdCWOP, weewx.restx.StdAWEKAS,
user.wetter.Wetter, user.wcloud.WeatherCloud, user.windfinder.WindFinder,
user.windguru.WindGuru
report_services = weewx.engine.StdPrint, weewx.engine.StdReport
##############################################################################
[ComputerMonitor]
data_binding = cmon_binding
max_age = 2592000 # 30 days; None to store indefinitely
################################################################################
[Forecast]
data_binding = forecast_binding
[[WU]]
api_key = 71ea
interval = 10800
max_age = 604800
#forecast_txt = hourly10day/forecast10day
[[Zambretti]]
# hemisphere can be NORTH or SOUTH
hemisphere = NORTH
# The interval determines how often the trend is calculated
interval = 600
# The lower and upper pressure define the range to which the forecaster
# should be calibrated, in units of millibar (hPa). The 'barometer'
# pressure (not station pressure) is used to calculate the forecast.
lower_pressure = 950.0
upper_pressure = 1050.0
[[XTide]]
location = Boston
[[NWS]]
lid =
foid = BOX
interval = 10800
[[OWM]]
api_key = 7
#forecast_type = 5day3hour
#interval = 10800
[[UKMO]]
api_key = XXXXXXXXXXXXXXXX # specify a UK met office api_key
location = 2337 # specify code for UK location
[[Aeris]]
client_id = # specify client identifier
client_secret = # specify client secret key
[[WWO]]
# An API key is required to access WWO forecasts.
#api_key = 2904
# The location can be specified by:
# US ZIP code 02139
# UK POST code X
# Canadian Postal code M3C4H9
# IP address x.x.x.x
# coordinate Lat 53.61 and Lon 11.34
# "latitude": "53.600",
# "longitude": "11.350",
# "population": "0",
# city name Klein Rogahn
# If no location is specified, station latitude and longitude are used
#location = 02139
# Forecasts are available in 3, 6, 12, and 24 hour increments.
forecast_type = 3
############################################################################################
[OWFS]
interface = u
#driver = user.owfs
[[sensor_type]]
#lightning = counter
extraHumid1 = humhes
extraHumid2 = heshum
#lighting = lighes
#radiation = radhes
supplyVoltage = owvolt
heatingVoltage = owvolt
referenceVoltage = owvolt
[[sensor_map]]
extraTemp1 = /uncached/28.829410050000/temperature
extraTemp4 = /uncached/28.5E1E31050000/temperature
# Carport kombi
extraTemp3 = /uncached/28.FF131B440400/temperature
extraTemp6 = /uncached/28.FF701B410400/temperature
extraTemp5 = /uncached/28.FFAC23430400/temperature
extraTemp2 = /uncached/28.FF2E20440400/temperature
extraTemp7 = /uncached/28.FEAE5E050000/temperature
# carport 1 m
soilTemp1 = /uncached/28.FFA71E430400/temperature
soilTemp2 = /uncached/28.FE4D11050000/temperature
soilTemp3 = /uncached/28.8DE010050000/temperature
soilTemp4 = /uncached/28.FF0C1F430400/temperature
soilTemp5 = /uncached/28.FFB31B410400/temperature
supplyVoltage = /26.45CD92010000
heatingVoltage = /26.0EFF91010000
referenceVoltage = /26.F8FE91010000
# Volt des one-wire busses
#outHumidity = /26.45CD92010000/humidity
#extraHumid1 = /26.45CD92010000
#extraHumid2 = /26.45CD92010000/humidity
# Sensor Carport
#radiation = /26.F8FE91010000
# Berechnung Helligkeit
#extraTemp9 = /26.0EFF91010000
extraTemp8 = /26.0EFF91010000/temperature
######################################################################################
[Weewx-WD]
data_binding = wd_binding
[[Supplementary]]
database_max_tries = 3
max_age = 691200
data_binding = wdsupp_binding
vacuum = 86400
database_retry_wait = 10
[[[WU]]]
conditions_interval = 1800
apiKey =
forecast_interval = 1800
api_lockout_period = 60
max_WU_tries = 3
location = replace_me
almanac_interval = 3600
######################################################################################
[SnowDepth]
filename = /home/weewx/snow
#!/usr/bin/env python
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# Version: 1.2.0b2 Date: 5 September 2015
#
# Revision History
# ?? September 2015 v1.2.0 - Initial implementation, based upon portions of
# weewxwd3.py
#
"""Manage the databases used by Weewx-WD"""
from __future__ import with_statement
import optparse
import os.path
import sys
import syslog
import time
from datetime import date, timedelta
# Find the install bin subdirectory:
this_file = os.path.join(os.getcwd(), __file__)
this_dir = os.path.abspath(os.path.dirname(this_file))
bin_dir = os.path.abspath(os.path.join(this_dir, os.pardir))
# Now that we've found the bin subdirectory, inject it into the path:
sys.path.insert(0, bin_dir)
# Now we can import some weewx modules
import weewx
VERSION = weewx.__version__
import user.extensions #@UnusedImport
import weedb
import weewx.manager
import weewx.units
import weecfg
import weewx
import weewx.engine
import weewx.wxformulas
import weewx.almanac
from weewx.units import convert, obs_group_dict
from weeutil.weeutil import to_bool, accumulateLeaves
from weeutil.weeutil import timestamp_to_string
# Weewx-WD imports
import user.weewxwd3
import user.wdSearchX3
#import user.wdAstroSearchX3
#import user.wdTaggedStats3
#import user.imageStackedWindRose3
from user.weewxwd3 import WdGenerateDerived
WEEWXWD_CONFIG_VERSION = '1.2.0b2'
description = """Manage the Weewx-WD database. This utility performs many of the functions
on the Weewx-WD database that the wee_database utility performs on the weewx
database. Most of these functions are handled automatically by Weewx-WD, but
they may be useful as a utility in special cases. In particular, the
'reconfigure' option can be useful if additional data types are added to or
dropped from the database schema or to change unit systems."""
usage = """weewxwd_config --help
weewxwd_config --create-archive
[CONFIG_FILE|--config=CONFIG_FILE]
[--wd-binding=BINDING_NAME]
weewxwd_config --drop-daily
[CONFIG_FILE|--config=CONFIG_FILE]
[--wd-binding=BINDING_NAME]
weewxwd_config --backfill-daily
[CONFIG_FILE|--config=CONFIG_FILE]
[--wd-binding=BINDING_NAME]
weewxwd_config --reconfigure
[CONFIG_FILE|--config=CONFIG_FILE]
[--wd-binding=BINDING_NAME]
weewxwd_config --string-check
[CONFIG_FILE|--config=CONFIG_FILE]
[--wd-binding=BINDING_NAME] [--fix]
weewxwd_config --copy-v2-data
[CONFIG_FILE|--config=CONFIG_FILE]
[--wx-binding=BINDING_NAME]
[--wd-binding=BINDING_NAME]
weewxwd_config --clear-v2-data
[CONFIG_FILE|--config=CONFIG_FILE]
[--wx-binding=BINDING_NAME]
[--wd-binding=BINDING_NAME]
weewxwd_config --version
weewxwd_config --status
"""
epilog = """If you are using a MySQL database it is assumed that you have the
appropriate permissions for the requested operation."""
def main():
# Set defaults for the system logger:
syslog.openlog('weewxwd', syslog.LOG_PID|syslog.LOG_CONS)
# Create a command line parser:
parser = optparse.OptionParser(description=description, usage=usage, epilog=epilog)
# Add the various options:
parser.add_option("--create-archive", dest="create_archive", action='store_true',
help="Create the Weewx-WD archive database.")
parser.add_option("--drop-daily", dest="drop_daily", action='store_true',
help="Drop the Weewx-WD daily summary tables.")
parser.add_option('--backfill-daily', dest='backfill_daily', action='store_true',
help='Backfill Weewx-WD daily summary tables from Weewx-WD archive.')
parser.add_option("--reconfigure", dest="reconfigure", action='store_true',
help="Create a new Weewx-WD archive database using configuration information found "
"in the configuration file. In particular, the new database will use the unit "
"system found in option [StdConvert][target_unit]. The new database will have "
"the same name as the old database, with a '_new' on the end.")
parser.add_option("--string-check", dest="string_check", action="store_true",
help="Check a sqlite version of the Weewx-WD database to "
"see whether it contains embedded strings.")
parser.add_option("--copy-v2-data", dest="copy_v2", action='store_true',
help="Copy historical Weewx-WD observation data from Weewx archive to Weewx-WD archive.")
parser.add_option("--clear-v2-data", dest="clear_v2", action='store_true',
help="Clear historical Weewx-WD data from Weewx (not Weewx-WD) archive. NOTE: This option will irreversibly clear all data stored in the 'extraTemp1' and 'extraTemp2' fields in the Weewx (not Weewx-WD) archive.")
parser.add_option('--version', dest='version', action='store_true',
help='Display Weewx-WD executable file versions.')
parser.add_option('--status', dest='status', action='store_true',
help='Display Weewx-WD archive status.')
parser.add_option('--config', dest='config_path', type=str, metavar="CONFIG_PATH",
help="Use configuration file CONFIG_PATH. Default is /etc/weewx/weewx.conf or /home/weewx/weewx.conf.")
parser.add_option("--wx-binding", dest="wxbinding", metavar="WX_BINDING_NAME",
default='wx_binding',
help="The weewx data binding. Default is 'wx_binding'.")
parser.add_option("--wd-binding", dest="wdbinding", metavar="WD_BINDING_NAME",
default='wd_binding',
help="The Weewx-WD data binding. Default is 'wd_binding'.")
parser.add_option("--fix", dest="fix", action="store_true",
help="Fix any embedded strings in a sqlite database.")
# Now we are ready to parse the command line:
(options, args) = parser.parse_args()
if options.version:
print "Weewx-WD weewxwd_config version: %s" % WEEWXWD_CONFIG_VERSION
print "Weewx-WD weewxwd version: %s" % user.weewxwd3.WEEWXWD_VERSION
print "Weewx-WD SLE version: %s" % user.wdSearchX3.WEEWXWD_SLE_VERSION
print "Weewx-WD Astronomical SLE version: %s" % user.wdAstroSearchX3.WEEWXWD_ASTRO_SLE_VERSION
print "Weewx-WD Tagged Statistics version: %s" % user.wdTaggedStats3.WEEWXWD_TAGGED_STATS_VERSION
print "Weewx-WD Stacked Windrose Generator version: %s" % user.imageStackedWindRose3.WEEWXWD_STACKED_WINDROSE_VERSION
exit(1)
config_path, config_dict = weecfg.read_config(options.config_path, args)
print "Using configuration file %s" % config_path
db_binding_wd, db_binding_wx = get_bindings(config_dict)
db_binding_wx = options.wxbinding
db_binding_wd = options.wdbinding
database_wx = config_dict['DataBindings'][db_binding_wx]['database']
database_wd = config_dict['DataBindings'][db_binding_wd]['database']
print "Using database binding '%s', which is bound to database '%s'" % (db_binding_wx, database_wx)
print "Using database binding '%s', which is bound to database '%s'" % (db_binding_wd, database_wd)
if options.status:
print_status(config_dict, db_binding_wd, db_binding_wx)
exit(1)
if options.create_archive:
createMainDatabase(config_dict, db_binding_wd)
if options.reconfigure:
reconfigMainDatabase(config_dict, db_binding_wd)
if options.drop_daily:
dropDaily(config_dict, db_binding_wd)
if options.backfill_daily:
backfillDaily(config_dict, db_binding_wd)
if options.string_check:
string_check(config_dict, db_binding_wd, options.fix)
if options.copy_v2:
copy_v2_data(config_dict, db_binding_wd, db_binding_wx)
exit(1)
if options.clear_v2:
clear_v2_data(config_dict, db_binding_wx)
exit(1)
def createMainDatabase(config_dict, db_binding):
"""Create a weewx archive database"""
# Try a simple open. If it succeeds, that means the database
# exists and is initialized. Otherwise, an exception will be thrown.
try:
with weewx.manager.open_manager_with_config(config_dict, db_binding) as dbmanager:
print "Database '%s' already exists. Nothing done." % (dbmanager.database_name,)
except weedb.OperationalError:
# Database does not exist. Try again, but allow initialization:
with weewx.manager.open_manager_with_config(config_dict, db_binding, initialize=True) as dbmanager:
print "Created database '%s'" % (dbmanager.database_name,)
def dropDaily(config_dict, db_binding):
"""Drop the daily summaries from a weewx database"""
manager_dict = weewx.manager.get_manager_dict(config_dict['DataBindings'],
config_dict['Databases'],
db_binding)
database_name = manager_dict['database_dict']['database_name']
ans = None
while ans not in ['y', 'n']:
print "Proceeding will delete all your daily summaries from database '%s'" % database_name
ans = raw_input("Are you sure you want to proceed (y/n)? ")
if ans == 'y' :
print "Dropping daily summary tables from '%s' ... " % (database_name,)
try:
with weewx.manager.open_manager_with_config(config_dict, db_binding) as dbmanager:
try:
dbmanager.drop_daily()
except weedb.OperationalError, e:
print "Got error '%s'\nPerhaps there was no daily summary?" % e
else:
print "Dropped daily summary tables from database '%s'" % (database_name,)
except weedb.OperationalError:
# No daily summaries. Nothing to be done.
print "No daily summaries found in database '%s'. Nothing done." % (database_name,)
def backfillDaily(config_dict, db_binding):
"""Backfill the daily summaries"""
manager_dict = weewx.manager.get_manager_dict(config_dict['DataBindings'],
config_dict['Databases'],
db_binding)
database_name = manager_dict['database_dict']['database_name']
print "Backfilling daily summaries in database '%s'" % database_name
t1 = time.time()
# Open up the archive. This will create the tables necessary for the daily summaries if they
# don't already exist:
with weewx.manager.open_manager_with_config(config_dict, db_binding, initialize=True) as dbmanager:
nrecs, ndays = dbmanager.backfill_day_summary()
tdiff = time.time() - t1
if nrecs:
print "Backfilled '%s' with %d records over %d days in %.2f seconds" % (database_name, nrecs, ndays, tdiff)
else:
print "Daily summaries up to date in '%s'." % database_name
def reconfigMainDatabase(config_dict, db_binding):
"""Create a new database, then populate it with the contents of an old database"""
manager_dict = weewx.manager.get_manager_dict_from_config(config_dict,
db_binding)
# Make a copy for the new database (we will be modifying it)
new_database_dict = dict(manager_dict['database_dict'])
# Now modify the database name
new_database_dict['database_name'] = manager_dict['database_dict']['database_name']+'_new'
# First check and see if the new database already exists. If it does, check
# with the user whether it's ok to delete it.
try:
weedb.create(new_database_dict)
except weedb.DatabaseExists:
ans = None
while ans not in ['y', 'n']:
ans = raw_input("New database '%s' already exists. Delete it first (y/n)? " % (new_database_dict['database_name'],))
if ans == 'y':
weedb.drop(new_database_dict)
elif ans == 'n':
print "Nothing done."
return
# Get the unit system of the old archive:
with weewx.manager.Manager.open(manager_dict['database_dict']) as old_dbmanager:
old_unit_system = old_dbmanager.std_unit_system
# Get the unit system of the new archive:
try:
target_unit_nickname = config_dict['StdConvert']['target_unit']
except KeyError:
target_unit_system = None
else:
target_unit_system = weewx.units.unit_constants[target_unit_nickname.upper()]
ans = None
while ans not in ['y', 'n']:
print "Copying Weewx-WD archive database '%s' to '%s'" % (manager_dict['database_dict']['database_name'], new_database_dict['database_name'])
if target_unit_system is None or old_unit_system==target_unit_system:
print "The new archive will use the same unit system as the old ('%s')." % (weewx.units.unit_nicknames[old_unit_system],)
else:
print "Units will be converted from the '%s' system to the '%s' system." % (weewx.units.unit_nicknames[old_unit_system],
weewx.units.unit_nicknames[target_unit_system])
ans = raw_input("Are you sure you wish to proceed (y/n)? ")
if ans == 'y':
weewx.manager.reconfig(manager_dict['database_dict'],
new_database_dict,
new_unit_system=target_unit_system,
new_schema=manager_dict['schema'])
print "Done."
elif ans == 'n':
print "Nothing done."
def print_status(config_dict, db_binding_wd, db_binding_wx):
""" Display brief status information on whether or not reconstruction of any
Weewx-WD archive data is required.
The installation of the Weewx-WD extension does not in itself
reconstruct any earlier Weewx-WD data that was previously kept in the
Weewx archive. A simple check is conducted of the earliest and
latest timestamps in the Weewx-WD archive that hold Weewx-WD data.
These times are compared against the earliest and latest timestamps
in the Weewx archive.
Parameters:
config_dict: a dictionary of the weewx.conf settings
db_binding_wd: binding for Weewx-WD database
db_binding_wx: binding for Weewx database
Returns:
Nothing.
"""
manager_dict = weewx.manager.get_manager_dict(config_dict['DataBindings'],
config_dict['Databases'],
db_binding_wd)
database_name = manager_dict['database_dict']['database_name']
with weewx.manager.open_manager_with_config(config_dict, db_binding_wd) as dbmanager_wd:
with weewx.manager.open_manager_with_config(config_dict, db_binding_wx) as dbmanager_wx:
earliest_wd_ts = None
latest_wd_ts = None
table_name = dbmanager_wd.table_name
# find earliest and latest Weewx-WD archive timestamps that hold valid data
_row = dbmanager_wd.getSql("SELECT MIN(dateTime), MAX(dateTime) FROM %s WHERE humidex IS NOT NULL AND appTemp IS NOT NULL" % table_name)
if _row:
# we have an answer
earliest_wd_ts = _row[0]
latest_wd_ts = _row[1]
# get our first and last good timestamps from Weewx archive
earliest_wx_ts = dbmanager_wx.firstGoodStamp()
latest_wx_ts = dbmanager_wx.lastGoodStamp()
if earliest_wd_ts is None or latest_wd_ts is None:
# no Weewx-WD data, reconstruct the lot if available
if earliest_wx_ts is not None and latest_wx_ts is not None:
# data available so say so
print "Reconstruction of Weewx-WD database '%s' table '%s' data from %s to %s (approx %d days) is recommended." % (database_name, table_name, timestamp_to_string(earliest_wx_ts), timestamp_to_string(latest_wx_ts), int((latest_wx_ts - earliest_wx_ts)/86400) + 1)
else:
# no data with which to reconstruct
print "Reconstruction of Weewx-WD database '%s' table '%s' is not required" % (database_name, table_name)
elif earliest_wx_ts is not None and latest_wx_ts is not None:
# some Weewx-WD data available and we also have some Weewx data
# check if we need to reconstruct
if earliest_wd_ts > earliest_wx_ts:
# we have 'before' data to reconstruct
print "Reconstruction of Weewx-WD database '%s' table '%s' data from %s to %s (approx %d days) is recommended." % (database_name, table_name, timestamp_to_string(earliest_wx_ts), timestamp_to_string(earliest_wd_ts), int((earliest_wd_ts - earliest_wx_ts)/86400) + 1)
elif latest_wd_ts < latest_wx_ts:
# we have 'after' data to reconstruct
print "Reconstruction of Weewx-WD database '%s' table '%s' data from %s to %s (approx %d days) is recommended." % (database_name, table_name, timestamp_to_string(latest_wd_ts), timestamp_to_string(latest_wx_ts), int((latest_wx_ts - latest_wd_ts)/86400) + 1)
else:
# no data with which to reconstruct so say so
print "Reconstruction of Weewx-WD database '%s' table '%s' is not required" % (database_name, table_name)
else:
# no data with which to reconstruct so say so
print "Reconstruction of Weewx-WD database '%s' table '%s' is not required" % (database_name, table_name)
def string_check(config_dict, db_binding, fix=False):
print "Checking Weewx-WD archive database for strings..."
found_problem = False
# Open up the main database archive
with weewx.manager.open_manager_with_config(config_dict, db_binding) as dbmanager:
obs_pytype_list = []
obs_list = []
# Get the schema and extract the Python type each observation type should be
for column in dbmanager.connection.genSchemaOf('archive'):
schema_type = column[2]
if schema_type == 'INTEGER':
schema_type = int
elif schema_type == 'REAL':
schema_type = float
elif schema_type == 'STR':
schema_type = str
# Save the observation type for this column (eg, 'outTemp'):
obs_list.append(column[1])
# Save the Python type for this column (eg, 'int'):
obs_pytype_list.append(schema_type)
# Cycle through each row in the database
for record in dbmanager.genBatchRows():
# Now examine each column
for icol in range(len(record)):
# Check to see if this column is an instance of the correct Python type
if record[icol] is not None and not isinstance(record[icol], obs_pytype_list[icol]):
# Oops. Found a bad one. Print it out
sys.stdout.write("Timestamp = %s; record['%s']= %r; ... " % (record[0], obs_list[icol], record[icol]))
found_problem = True
if fix:
# Cooerce to the correct type. If it can't be done, then set it to None
try:
corrected_value = obs_pytype_list[icol](record[icol])
except ValueError:
corrected_value = None
# Update the database with the new value
dbmanager.updateValue(record[0], obs_list[icol], corrected_value)
# Inform the user
sys.stdout.write("changed to %r\n" % corrected_value)
else:
sys.stdout.write("ignored.\n")
# Print out a message if nothing was found
if not found_problem:
print "Check complete. No embedded strings found."
def copy_v2_data(config_dict, db_binding_wd, db_binding_wx):
""" Copy legacy Weewx-WD derived obs from a Weewx archive.
Does a simple check of the first and last valid timestamps in
Weewx-WD and Weewx archives to identify any Weewx-WD missing data
timespans. The check is simple and only identifies missing data
before the first and after the last valid Weewx-WD timestamps.
Missing data between these timestamps will not be identified and
copied.
Parameters:
config_dict: a dictionary of the weewx.conf settings
db_binding_wd: binding for Weewx-WD database
db_binding_wx: binding for Weewx database
Returns:
Nothing.
"""
t1 = time.time()
with weewx.manager.open_manager_with_config(config_dict, db_binding_wd) as dbmanager_wd:
with weewx.manager.open_manager_with_config(config_dict, db_binding_wx) as dbmanager_wx:
# get the spans of any records we need to insert both:
# - before the start of our Weewx-WD database, and
# - after the end of our Weewx-WD database
before_span, after_span = get_backfill_spans(dbmanager_wd, dbmanager_wx)
before_start_ts, before_stop_ts, after_start_ts, after_stop_ts = before_span + after_span
# do the backfill noting numbers of records, days and periods we have
# dealt with
nrecs_b = None
ndays_b = 0
nrecs_a = None
ndays_a = 0
nperiods = 0
if before_start_ts is not None and before_stop_ts is not None:
nrecs_b, ndays_b = backfill_wd(dbmanager_wd, dbmanager_wx, before_start_ts - 1, before_stop_ts - 1)
if nrecs_b is not None:
nperiods += 1 if nrecs_b > 0 else nperiods
if after_start_ts is not None and after_stop_ts is not None:
nrecs_a, ndays_a = backfill_wd(dbmanager_wd, dbmanager_wx, after_start_ts, after_stop_ts)
if nrecs_a is not None:
nperiods += 1 if nrecs_a > 0 else nperiods
tdiff = time.time() - t1
# informational statement on what we did/did not do
nrecs = sum(filter(None, (nrecs_b, nrecs_a)))
if nperiods > 0:
print "%d record(s) over %d period(s) covering approximately %d day(s) processed in %s." % (nrecs, nperiods, ndays_b + ndays_a, str(timedelta(seconds=int(tdiff))))
else:
print "No records processed."
def clear_v2_data(config_dict, db_binding_wx):
""" Clear any legacy humidex and apparent temperature data from the
Weewx (not Weewx-WD) database.
Under Weewx v2.x Weewx-WD stored humidex and apparent temperature
data in the Weewx archive in fields extraTemp1 and extratemp2
respectively. Under Weewx v3 Weewx-WD now stores this data in a
separate database and hence this legacy data can be removed from
the Weewx database.
Parameters:
config_dict: a dictionary of the weewx.conf settings
db_binding_wx: binding for Weewx database
Returns:
Nothing.
"""
manager_dict = weewx.manager.get_manager_dict(config_dict['DataBindings'],
config_dict['Databases'],
db_binding_wx)
database_name = manager_dict['database_dict']['database_name']
with weewx.manager.open_manager_with_config(config_dict, db_binding_wx) as dbmanager_wx:
# get our first and last good timestamps
start_ts = dbmanager_wx.firstGoodStamp()
stop_ts = dbmanager_wx.lastGoodStamp()
# do we actually have any extraTemp1 and extraTemp2 fields with data in them?
#_row = dbmanager_wx.getSql("SELECT COUNT(windrun) FROM %s" % dbmanager_wx.table_name)
_row = dbmanager_wx.getSql("SELECT COUNT(extraTemp1), COUNT(extraTemp2) FROM %s" % dbmanager_wx.table_name)
print "row %s" % (_row)
if _row:
# we have an answer
if _row[0] > 0 or _row[1] >0:
# we do have some fields to clear so clear them
# set some counters
nrecs = 0
ndays = (date.fromtimestamp(stop_ts) - date.fromtimestamp(start_ts)).days
# confirm we still want to do this
print "'extraTemp1' and 'extraTemp2' data in database '%s' from %s to %s (approx %d days) is about to be cleared. Any data in these fields will be irretrievably lost." % (database_name, timestamp_to_string(start_ts), timestamp_to_string(stop_ts), ndays)
ans = None
ans = raw_input("Are you sure you wish to proceed (y/n)? ")
if ans == 'y':
# we do so go ahead and clear them
for _rec in dbmanager_wx.genBatchRecords(start_ts - 1, stop_ts):
""" test
msr = weewx.wxformulas.solar_rad_Bras(53.605963, 11.341407, 53, _rec['dateTime'], 2)
dbmanager_wx.updateValue(_rec['dateTime'], 'maxSolarRad', msr)
if _rec['outTemp'] <> 0 and _rec['outHumidity'] <> 0:
cb1 = weewx.wxformulas.cloudbase_Metric(_rec['outTemp'], _rec['outHumidity'], 53)
else:
cb1 = 0
dbmanager_wx.updateValue(_rec['dateTime'], 'cloudbase', cb1)
if _rec['windSpeed'] > 0:
be2 = _rec['windSpeed'] * 5.0 / 60.0
else:
be2 = 0.0
dbmanager_wx.updateValue(_rec['dateTime'], 'windrun', be2)
if _rec['outTemp'] <> 0 and _rec['dewpoint'] <> 0 and _rec['pressure'] <> 0 and _rec['windSpeed'] <> 0:
wi1 = weewx.wxformulas.winddruck_Metric(_rec['dewpoint'], _rec['outTemp'],
_rec['pressure'], _rec['windSpeed'])
else:
wi1 = 0
dbmanager_wx.updateValue(_rec['dateTime'], 'windDruck', wi1)
if _rec['outTemp'] <> 0 and _rec['dewpoint'] <> 0 and _rec['pressure'] <> 0:
ai1 = weewx.wxformulas.density_Metric(_rec['dewpoint'], _rec['outTemp'],
_rec['pressure'])
else:
ai1 = 0
dbmanager_wx.updateValue(_rec['dateTime'], 'airDensity', ai1)
if _rec['outTemp'] <> 0 and _rec['outHumidity'] <> 0 and _rec['pressure'] <> 0:
we1 = weewx.wxformulas.wetbulb_Metric(_rec['outTemp'], _rec['outHumidity'],
_rec['pressure'])
else:
we1 = 0
dbmanager_wx.updateValue(_rec['dateTime'], 'wetBulb', we1)
if _rec['outTemp'] <> 0 and _rec['outHumidity'] <> 0:
cbI = weewx.wxformulas.cbindex_Metric(_rec['outTemp'], _rec['outHumidity'])
else:
cbI = 0.0
dbmanager_wx.updateValue(_rec['dateTime'], 'cbIndex', cbI)
if _rec['radiation'] <> 0:
sunS = weewx.wxformulas.sunhes(_rec['radiation'], _rec['dateTime'])
else:
sunS = 0.0
dbmanager_wx.updateValue(_rec['dateTime'], 'sunshineS', sunS)
dbmanager_wx.updateValue(_rec['dateTime'], 'extraTemp2', None)
"""
dbmanager_wx.updateValue(_rec['dateTime'], 'extraTemp1', None)
dbmanager_wx.updateValue(_rec['dateTime'], 'extraTemp2', None)
nrecs += 1
# all done, say so and give some stats
print "Done. 'extraTemp1' and 'extraTemp2' cleared in %d records (approx %d days)." %(nrecs, ndays)
elif ans == 'n':
# we backed out so say so
print "Action cancelled. Nothing done."
else:
# no rows need to be cleared
print "No 'extraTemp1' or 'extraTemp2' data found in database '%s' that need to be cleared. No data changed." % (database_name)
else:
# no rows need to be cleared
print "No 'extraTemp1' or 'extraTemp2' data found in database '%s' that need to be cleared. No data changed." % (database_name)
def get_bindings(config_dict):
""" Get db_bindings for the Weewx-WD and Weewx databases.
Parameters:
config_dict: a dictionary of the weewx.conf settings
Returns:
db_binding_wd: binding for Weewx-WD database.
db_binding_wx: binding for Weewx database.
"""
# Extract our binding from the Weewx-WD section of the config file. If
# it's missing, fill with a default
if 'Weewx-WD' in config_dict:
db_binding_wd = config_dict['Weewx-WD'].get('data_binding', 'wd_binding')
else:
db_binding_wd = 'wd_binding'
# Extract the Weewx binding for use when we check the need for backfill
# from the Weewx archive
if 'StdArchive' in config_dict:
db_binding_wx = config_dict['StdArchive'].get('data_binding', 'wx_binding')
else:
db_binding_wx = 'wx_binding'
return (db_binding_wd, db_binding_wx)
def get_backfill_spans(dbmanager_wd, dbmanager_wx):
""" Calculate timespans that require backfill of data from Weewx
archive to Weewx-WD archive.
If Weewx-WD was installed some time after Weewx was first run
there will likely be one or more periods of missing data in the
Weewx-WD archive that is otherwise available from the Weewx
archive. This routine takes a simplistic approach to determining
these timespans as follows:
- first good timestamp in Weewx archive to first good timestamp in
Weewx-WD archive
- last good timestamp in Weewx-WD archive to last good timestamp in
Weewx archive
- if there is no data in the Weewx-WD archive then first good
timestamp to last good timestamp in Weewx archive
- if there is no data in the Weewx archive then a (None, None)
timespan is returned for each period
Gaps in the Weewx-WD data are not included in any timespand results.
Parameters:
dbmanager_wd: Manager object for Weewx-WD database.
dbmanager_wx: Manager object for Weewx database.
Returns:
A tuple consisting of two tuples each consisting of a start and
stop timestamp. The first tuple represents the timespan of data
that is older then the Weewx-WD data. The second tuple
represents the timespan of data that is newer than the Weewx-WD
data. (None, None) represents no timespan.
"""
# get fist and last good timestamps for each database
first_wd_ts = dbmanager_wd.firstGoodStamp()
last_wd_ts = dbmanager_wd.lastGoodStamp()
first_wx_ts = dbmanager_wx.firstGoodStamp()
last_wx_ts = dbmanager_wx.lastGoodStamp()
if first_wd_ts is None or last_wd_ts is None:
# no data in wd
if first_wx_ts is not None and last_wx_ts is not None:
# we have data in wx
return ((first_wx_ts, last_wx_ts), (None, None))
else:
# we have no data in wx
return ((None, None), (None, None))
else:
# wd data
if first_wx_ts is not None and last_wx_ts is not None:
# we have data in wx
if first_wx_ts < first_wd_ts:
#we have 'before' data to add
before = (first_wx_ts, first_wd_ts)
else:
before = (None, None)
if last_wx_ts > last_wd_ts:
#we have 'after' data to add
after = (last_wd_ts, last_wx_ts)
else:
after = (None, None)
return (before, after)
else:
# we have no data in wx
return ((None, None), (None, None))
def backfill_wd(dbmanager_wd, dbmanager_wx, start_ts, stop_ts):
""" Backfill Weewx-WD database with derived obs over a timespan.
Steps through each Weewx record in the timespan extracting
humidex/appTemp from extraTemp1/extraTemp2 values if they contain
data otherwise humidex/appTemp are calculated and saved in the
Weewx-WD database against the original timestamp. Also sets
outTempDay and outTempNight such that:
- outTempDay=outTemp if time is > 06:00 and time is <= 18:00
- outTempNight=outTemp if time is <= 06:00 and time is > 18:00
- outTempDay and outTempNight = None at all other times.
Parameters:
dbmanager_wd: manager object for Weewx-WD database
dbmanager_wx: manager object for Weewx database
start_ts: inclusive timestamp for the start of the timespan
stop_ts: inclusive timestamp for the end of the timespan
Returns:
ndays: the number of days processed
"""
# set up a reference time point
t1 = time.time()
# set some stats
nrecs = None
ndays = (date.fromtimestamp(stop_ts) - date.fromtimestamp(start_ts)).days
# how many recs do we need to update?
_row = dbmanager_wx.getSql("SELECT COUNT(dateTime) FROM %s WHERE dateTime >= %s AND dateTime <= %s" % (dbmanager_wx.table_name, start_ts, stop_ts))
if _row:
# we have an answer
nrecs = _row[0] if _row[0] > 0 else None
# confirm we still want to do this
print "%d records have been identified to backfill database '%s' from %s to %s (approx %d days). This may take some time (hours) to complete." % (nrecs, dbmanager_wd.database_name, timestamp_to_string(start_ts), timestamp_to_string(stop_ts), ndays)
ans = None
ans = raw_input("Are you sure you wish to proceed (y/n)? ")
if ans == 'y':
print "Processing %d records..." % (nrecs,)
# create a generator object that will yield records over our timespan that have had humidex/appTemp added
# need to be inclusive on the start hence the - 1
record_generator = WdGenerateDerived(dbmanager_wx.genBatchRecords(start_ts - 1, stop_ts))
# now call the addRecord method with our generator object
# should be much faster than passing addRecord individual records
dbmanager_wd.addRecord(record_generator)
else:
print "Action cancelled. Nothing done."
# we backed out so set nrecs to None
nrecs = None
return nrecs, ndays
if __name__=="__main__" :
main()
#
# Copyright (c) 2009-2015 Tom Keffer <[email protected]>
#
# See the file LICENSE.txt for your full rights.
#
"""The wview schema, which is also used by weewx."""
# =============================================================================
# This is a list containing the default schema of the archive database. It is
# identical to what is used by wview. It is only used for initialization ---
# afterwards, the schema is obtained dynamically from the database. Although a
# type may be listed here, it may not necessarily be supported by your weather
# station hardware.
#
# You may trim this list of any unused types if you wish, but it will not
# result in saving as much space as you may think --- most of the space is
# taken up by the primary key indexes (type "dateTime").
# =============================================================================
schema = [('dateTime', 'INTEGER NOT NULL UNIQUE PRIMARY KEY'),
('usUnits', 'INTEGER NOT NULL'),
('interval', 'INTEGER NOT NULL'),
('barometer', 'REAL'),
('pressure', 'REAL'),
('altimeter', 'REAL'),
('inTemp', 'REAL'),
('outTemp', 'REAL'),
('inHumidity', 'REAL'),
('outHumidity', 'REAL'),
('windSpeed', 'REAL'),
('windDir', 'REAL'),
('windGust', 'REAL'),
('windGustDir', 'REAL'),
('rainRate', 'REAL'),
('rain', 'REAL'),
('dewpoint', 'REAL'),
('windchill', 'REAL'),
('heatindex', 'REAL'),
('ET', 'REAL'),
('radiation', 'REAL'),
('UV', 'REAL'),
('extraTemp1', 'REAL'),
('extraTemp2', 'REAL'),
('extraTemp3', 'REAL'),
('soilTemp1', 'REAL'),
('soilTemp2', 'REAL'),
('soilTemp3', 'REAL'),
('soilTemp4', 'REAL'),
('leafTemp1', 'REAL'),
('leafTemp2', 'REAL'),
('extraHumid1', 'REAL'),
('extraHumid2', 'REAL'),
('soilMoist1', 'REAL'),
('soilMoist2', 'REAL'),
('soilMoist3', 'REAL'),
('soilMoist4', 'REAL'),
('leafWet1', 'REAL'),
('leafWet2', 'REAL'),
('rxCheckPercent', 'REAL'),
('txBatteryStatus', 'REAL'),
('consBatteryVoltage', 'REAL'),
('hail', 'REAL'),
('hailRate', 'REAL'),
('heatingTemp', 'REAL'),
('heatingVoltage', 'REAL'),
('supplyVoltage', 'REAL'),
('referenceVoltage', 'REAL'),
('windBatteryStatus', 'REAL'),
('rainBatteryStatus', 'REAL'),
('outTempBatteryStatus', 'REAL'),
('inTempBatteryStatus', 'REAL')]
#
# Copyright (c) 2011 Tom Keffer <[email protected]>
#
# See the file LICENSE.txt for your full rights.
#
# $Revision: 1459 $
# $Author: mwall $
# $Date: 2013-10-08 17:44:50 -0700 (Tue, 08 Oct 2013) $
#
"""Database schemas used by weewx"""
#===============================================================================
# This is a list containing the default schema of the archive database. It is
# identical to what is used by wview. It is only used for initialization ---
# afterwards, the schema is obtained dynamically from the database. Although a
# type may be listed here, it may not necessarily be supported by your weather
# station hardware.
#
# You may trim this list of any unused types if you wish, but it will not
# result in saving as much space as you may think --- most of the space is
# taken up by the primary key indexes (type "dateTime").
# =============================================================================
schema = [('dateTime', 'INTEGER NOT NULL UNIQUE PRIMARY KEY'),
('usUnits', 'INTEGER NOT NULL'),
('interval', 'INTEGER NOT NULL'),
('barometer', 'REAL'),
('pressure', 'REAL'),
('altimeter', 'REAL'),
('inTemp', 'REAL'),
('outTemp', 'REAL'),
('inHumidity', 'REAL'),
('outHumidity', 'REAL'),
('windSpeed', 'REAL'),
('windDir', 'REAL'),
('windGust', 'REAL'),
('windGustDir', 'REAL'),
('rainRate', 'REAL'),
('rain', 'REAL'),
('dewpoint', 'REAL'),
('windchill', 'REAL'),
('heatindex', 'REAL'),
('ET', 'REAL'),
('radiation', 'REAL'),
('UV', 'REAL'),
('extraTemp1', 'REAL'),
('extraTemp2', 'REAL'),
('extraTemp3', 'REAL'),
('soilTemp1', 'REAL'),
('soilTemp2', 'REAL'),
('soilTemp3', 'REAL'),
('soilTemp4', 'REAL'),
('leafTemp1', 'REAL'),
('leafTemp2', 'REAL'),
('extraHumid1', 'REAL'),
('extraHumid2', 'REAL'),
('soilMoist1', 'REAL'),
('soilMoist2', 'REAL'),
('soilMoist3', 'REAL'),
('soilMoist4', 'REAL'),
('leafWet1', 'REAL'),
('leafWet2', 'REAL'),
('rxCheckPercent', 'REAL'),
('txBatteryStatus', 'REAL'),
('consBatteryVoltage', 'REAL'),
('hail', 'REAL'),
('hailRate', 'REAL'),
('heatingTemp', 'REAL'),
('heatingVoltage', 'REAL'),
('supplyVoltage', 'REAL'),
('referenceVoltage', 'REAL'),
('windBatteryStatus', 'REAL'),
('rainBatteryStatus', 'REAL'),
('outTempBatteryStatus', 'REAL'),
('lighting', 'REAL'),
('extraTemp4', 'REAL'),
('extraTemp5', 'REAL'),
('soilTemp5', 'REAL'),
('extraTemp6', 'REAL'),
('extraTemp7', 'REAL'),
('extraTemp8', 'REAL'),
('extraTemp9', 'REAL'),
('maxSolarRad', 'REAL'),
('cloudbase', 'REAL'),
('humidex', 'REAL'),
('appTemp', 'REAL'),
('windrun', 'REAL'),
('beaufort', 'REAL'),
('inDewpoint', 'REAL'),
('inTempBatteryStatus', 'REAL'),
('sunshinehours', 'REAL'),
('sunshineS', 'REAL'),
('snow', 'REAL'),
('snowRate', 'REAL'),
('wetBulb', 'REAL'),
('cbIndex', 'REAL'),
('airDensity', 'REAL'),
('windDruck', 'REAL')]