Skip to content

Commit

Permalink
Added first cut at injecting driver stanza in config file.
Browse files Browse the repository at this point in the history
  • Loading branch information
tkeffer committed Mar 29, 2015
1 parent 7d29f59 commit 1b113a2
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 75 deletions.
51 changes: 5 additions & 46 deletions bin/config_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

import configobj

import weeutil.weeutil

minor_comment_block = [""]
major_comment_block = ["", "##############################################################################", ""]

Expand Down Expand Up @@ -104,50 +106,6 @@ def mkdir(dirpath):
except OSError:
pass

def _as_string(option):
if option is None: return None
if hasattr(option, '__iter__'):
return ', '.join(option)
return option

# def merge_config_files(template_path, old_config_path, weewx_root):
# """Merges any old config file into the new one, and sets WEEWX_ROOT.
#
# If an old configuration file exists, it will merge the contents
# into the new file. It also sets variable ['WEEWX_ROOT']
# to reflect the installation directory.
#
# template_path: Path where the new configuration file can be found.
#
# old_config_path: Path where the old configuration file can be found.
#
# weewx_root: What WEEWX_ROOT should be set to.
#
# version_number: The version number of the new configuration file.
#
# RETURNS:
#
# The (possibly) merged new configuration file.
# """
#
# # Get the template config file
# template_config = configobj.ConfigObj(template_path)
# template_config.indent_type = ' '
#
# # Check to see if there is an existing config file.
# if os.path.exists(old_config_path):
# config_dict = configobj.ConfigObj(old_config_path)
# # Do a merge of any missing stuff from the template
# merge_config(config_dict, template_config)
# else:
# # No existing config file. Substitute the template:
# config_dict = template_config
#
# # Make sure WEEWX_ROOT reflects the choice made in setup.cfg:
# config_dict['WEEWX_ROOT'] = weewx_root
#
# return config_dict

def update_config(config_dict):
"""Update a (possibly old) configuration dictionary to the latest format.
Expand Down Expand Up @@ -527,7 +485,7 @@ def get_station_info(config_dict):
stn_info = dict()
if config_dict is not None:
if 'Station' in config_dict:
stn_info['location'] = _as_string(config_dict['Station'].get('location'))
stn_info['location'] = weeutil.weeutil.list_as_string(config_dict['Station'].get('location'))
stn_info['latitude'] = config_dict['Station'].get('latitude')
stn_info['longitude'] = config_dict['Station'].get('longitude')
stn_info['altitude'] = config_dict['Station'].get('altitude')
Expand Down Expand Up @@ -599,7 +557,8 @@ def prompt_for_info(location=None, latitude='90.000', longitude='0.000',
print "Specify altitude, with units 'foot' or 'meter'. For example:"
print "35, foot"
print "12, meter"
msg = "altitude [%s]: " % _as_string(altitude) if altitude else "altitude: "
print "altitude is", altitude
msg = "altitude [%s]: " % weeutil.weeutil.list_as_string(altitude) if altitude else "altitude: "
alt = None
while alt is None:
ans = raw_input(msg).strip()
Expand Down
142 changes: 113 additions & 29 deletions bin/wee_config
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import tempfile
import configobj

import weewx
import weeutil.weeutil
import config_util

my_dir = os.path.abspath(os.path.dirname(__file__))
Expand All @@ -28,7 +29,7 @@ major_comment_block = ["", "####################################################
stn_info_defaults = {'location' : '',
'latitude' : '0',
'longitude' : '0',
'altitude' : '[0, meter]',
'altitude' : ['0', 'meter'],
'units' : 'metric',
'station_type' : 'Vantage',
'driver' : 'weewx.drivers.Vantage'}
Expand Down Expand Up @@ -102,12 +103,14 @@ def main():
help="The station latitude")
parser.add_option("--longitude", metavar="xx.x",
help="The station longitude")
parser.add_option("--altitude", metavar="zz,(foot|meter)", default='[0, meter]',
parser.add_option("--altitude", metavar="zz,(foot|meter)",
help="The station altitude in either feet or meters. E.g., '750,foot'")
parser.add_option("--location",
help="""A text description of the station. For example, "Santa's workshop, North Pole" """)
parser.add_option("--units", choices=["us", "metric"], metavar="(metric|us)",
help="Set display units to 'metric' or 'us'")
parser.add_option("--debug", action="store_true",
help="Print some intermediate data structures")

# Now we are ready to parse the command line:
(options, args) = parser.parse_args()
Expand Down Expand Up @@ -160,34 +163,9 @@ def main():
save_me = True

if options.modify:

# Get defaults out of the config file:
stn_info = config_util.get_station_info(config_dict)

# Get command line overrides, and apply them to stn_info:
for k in stn_info:
if hasattr(options, k) and getattr(options,k) is not None:
stn_info[k] = getattr(options, k)

# If any are still None, replace them with defaults:
for k in stn_info_defaults:
if stn_info[k] is None:
stn_info[k] = stn_info_defaults[k]

# Unless --no-prompt has been specified, give the user a chance to change things:
if not options.no_prompt:
stn_info.update(config_util.prompt_for_info(**stn_info))

if not options.driver:
driver = prompt_for_driver(stn_info.get('driver'))
stn_info['driver'] = driver

# Look up driver info:
driver_editor, driver_name, driver_version = config_util.load_driver_editor(stn_info.get('driver'))

print "Station info", stn_info
modify_config(config_dict, options)
exit()

if save_me:

# Save the resultant config file, backing up as necessary.
Expand Down Expand Up @@ -219,6 +197,112 @@ def main():
sys.exit("Nothing done.")
return 0

def modify_config(config_dict, options):
"""Modify the configuration dictionary according to any command
line options. Give the user a chance too."""

# Get defaults out of the config file:
stn_info = config_util.get_station_info(config_dict)

# Get command line overrides, and apply them to stn_info:
for k in stn_info:
if hasattr(options, k) and getattr(options,k) is not None:
stn_info[k] = getattr(options, k)

# If any are still None, replace them with defaults:
for k in stn_info_defaults:
if stn_info[k] is None:
stn_info[k] = stn_info_defaults[k]

# Unless --no-prompt has been specified, give the user a chance to change things:
if not options.no_prompt:
stn_info.update(config_util.prompt_for_info(**stn_info))

if not options.driver:
driver = prompt_for_driver(stn_info.get('driver'))
stn_info['driver'] = driver

# OK, we now have all the station info. Time to inject the driver stanza,
# if necessary.
driver = stn_info.get('driver')
try:
# Look up driver info:
driver_editor, driver_name, driver_version = \
config_util.load_driver_editor(driver)
except Exception, e:
exit("Driver %s failed to load: %s" (driver, e))
stn_info['station_type'] = driver_name
print 'Using %s version %s (%s)' % (stn_info['station_type'], driver_version, driver)

if options.debug:
print "Station info:\n", weeutil.weeutil.print_dict(stn_info)

stanza = None
if driver_editor is not None:
orig_stanza_text = None

# if a previous stanza exists for this driver, grab it
if driver_name in config_dict:
orig_stanza = configobj.ConfigObj(interpolation=False)
orig_stanza[driver_name] = config_dict[driver_name]
orig_stanza_text = '\n'.join(orig_stanza.write())

# let the driver process the stanza or give us a new one
stanza_text = driver_editor.get_conf(orig_stanza_text)
stanza = configobj.ConfigObj(stanza_text.splitlines())

# put the new stanza immediately after [Station]
if stanza is not None and 'Station' in config_dict:
# insert the stanza
config_dict[driver_name] = stanza[driver_name]
config_dict.comments[driver_name] = major_comment_block
# reorder the sections
idx = config_dict.sections.index(driver_name)
config_dict.sections.pop(idx)
idx = config_dict.sections.index('Station')
config_dict.sections = config_dict.sections[0:idx+1] + [driver_name] + config_dict.sections[idx+1:]
# make the stanza the station type
config_dict['Station']['station_type'] = driver_name

# apply any overrides from the stn_info
if stn_info is not None:
# update driver stanza with any overrides from stn_info
if driver_name in stn_info:
for k in stn_info[driver_name]:
config_dict[driver_name][k] = stn_info[driver_name][k]
# update station information with info overrides
for p in ['location', 'latitude', 'longitude', 'altitude']:
if stn_info.get(p) is not None:
config_dict['Station'][p] = stn_info[p]
# update units display with any info overrides
if stn_info.get('units') is not None:
if stn_info.get('units') == 'metric':
print "Using Metric units for display"
config_dict['StdReport']['StandardReport'].update({
'Units': {
'Groups': {
'group_altitude': 'meter',
'group_degree_day': 'degree_C_day',
'group_pressure': 'mbar',
'group_rain': 'mm',
'group_rainrate': 'mm_per_hour',
'group_speed': 'meter_per_second',
'group_speed2': 'meter_per_second2',
'group_temperature': 'degree_C'}}})
elif stn_info.get('units') == 'us':
print "Using US units for display"
config_dict['StdReport']['StandardReport'].update({
'Units': {
'Groups': {
'group_altitude': 'foot',
'group_degree_day': 'degree_F_day',
'group_pressure': 'inHg',
'group_rain': 'inch',
'group_rainrate': 'inch_per_hour',
'group_speed': 'mile_per_hour',
'group_speed2': 'mile_per_hour2',
'group_temperature': 'degree_F'}}})

def prompt_for_driver(dflt_driver=None):
"""Get the information about each driver, return as a dictionary."""
infos = config_util.get_driver_infos()
Expand All @@ -236,7 +320,7 @@ def prompt_for_driver(dflt_driver=None):
ans = dflt_idx
try:
idx = int(ans)
if idx < 0 or idx >= len(keys):
if not 0 <= idx < len(keys):
ans = None
except (ValueError, TypeError):
ans = None
Expand Down

0 comments on commit 1b113a2

Please sign in to comment.