mirror of
https://github.com/weewx/weewx.git
synced 2026-06-09 01:25:20 -04:00
V1.10.0
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
CHANGE HISTORY
|
||||
--------------------------------
|
||||
|
||||
1.10.0a6 02/26/11
|
||||
1.10.0 03/29/11
|
||||
|
||||
Added extensive almanac information if the optional package 'pyephem' has been
|
||||
installed
|
||||
|
||||
Added a weewx "favorite icon" favicon.ico that displays in your browser toolbar.
|
||||
|
||||
|
||||
2
MANIFEST
2
MANIFEST
@@ -19,7 +19,6 @@ bin/user/schemas.py
|
||||
bin/weeplot/__init__.py
|
||||
bin/weeplot/genplot.py
|
||||
bin/weeplot/utilities.py
|
||||
bin/weeutil/Almanac.py
|
||||
bin/weeutil/Moon.py
|
||||
bin/weeutil/Sun.py
|
||||
bin/weeutil/__init__.py
|
||||
@@ -29,6 +28,7 @@ bin/weeutil/weeutil.py
|
||||
bin/weewx/VantagePro.py
|
||||
bin/weewx/__init__.py
|
||||
bin/weewx/accum.py
|
||||
bin/weewx/almanac.py
|
||||
bin/weewx/archive.py
|
||||
bin/weewx/crc16.py
|
||||
bin/weewx/filegenerator.py
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
"""
|
||||
import time
|
||||
|
||||
__version__="1.10.0a6"
|
||||
__version__="1.10.0"
|
||||
|
||||
# Holds the program launch time in unix epoch seconds:
|
||||
# Useful for calculating 'uptime.'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2009 Tom Keffer <tkeffer@gmail.com>
|
||||
# Copyright (c) 2009, 2011 Tom Keffer <tkeffer@gmail.com>
|
||||
#
|
||||
# See the file LICENSE.txt for your full rights.
|
||||
#
|
||||
@@ -12,47 +12,23 @@
|
||||
This module can optionally use PyEphem, which offers high quality
|
||||
astronomical calculations. See http://rhodesmill.org/pyephem. """
|
||||
|
||||
#===============================================================================
|
||||
# Architectural notes
|
||||
#
|
||||
# Unfortunately, sunrise and sunset have to be calculated dynamically when
|
||||
# using ephem because of its unfortunate design decision to change the
|
||||
# state of the body when calling next_rising() or next_setting(). This leads
|
||||
# to some complications in the class BodyWrapper
|
||||
#===============================================================================
|
||||
|
||||
import calendar
|
||||
import time
|
||||
import sys
|
||||
|
||||
import Moon
|
||||
import weeutil.Moon
|
||||
import weewx.units
|
||||
|
||||
# If the user has installed ephem, use it. Otherwise, fall back to the weeutil algorithms:
|
||||
try:
|
||||
import ephem
|
||||
import math
|
||||
except:
|
||||
import Sun
|
||||
import weeutil.Sun
|
||||
|
||||
class Almanac(object):
|
||||
"""Almanac data.
|
||||
|
||||
time_ts: A timestamp within the date for which sunrise/sunset is desired.
|
||||
|
||||
lat, lon: Location for which sunrise/sunset is desired.
|
||||
|
||||
altitude: Elevation in **meters**. [Optional. Default is 0 (sea level)]
|
||||
|
||||
temperature: The temperature in **degrees Celsius**. [Optional. Default is 15.0]
|
||||
|
||||
pressure: The atmospheric pressure in **mBars**. [Optional. Default is 1010]
|
||||
|
||||
moon_phases: An array of 8 strings with descriptions of the moon
|
||||
phase. [optional. If not given, then weeutil.Moon.moon_phases will be used]
|
||||
|
||||
timeformat: A strftime style format to be used to format sunrise and sunset.
|
||||
[optional. If not given, then "%H:%M" will be used.
|
||||
|
||||
ATTRIBUTES.
|
||||
|
||||
As a minimum, the following attributes are available:
|
||||
@@ -62,58 +38,60 @@ class Almanac(object):
|
||||
moon_phase: A description of the moon phase(eg. "new moon", Waxing crescent", etc.)
|
||||
moon_fullness: Percent fullness of the moon (0=new moon, 100=full moon)
|
||||
|
||||
If the module 'ephem' is used, many other attributes are available.
|
||||
If the module 'ephem' is used, them many other attributes are available.
|
||||
Here are a few examples:
|
||||
|
||||
sun.transit: Time of transit (sun over meridian)
|
||||
sun.previous_sunrise: Time of last sunrise
|
||||
sun.rise: Time upper limb of sun will rise above the horizon today in unix epoch time
|
||||
sun.transit: Time of transit today (sun over meridian) in unix epoch time
|
||||
sun.previous_sunrise: Time of last sunrise in unix epoch time
|
||||
sun.az: Azimuth (in degrees) of sun
|
||||
sun.alt: Altitude (in degrees) of sun
|
||||
mars.rise: Time of mars rising
|
||||
mars.rise: Time when upper limb of mars will rise above horizon today in unix epoch time
|
||||
mars.ra: Right ascension of mars
|
||||
etc.
|
||||
|
||||
EXAMPLES:
|
||||
|
||||
>>> t = time.mktime((2009, 3, 27, 12, 0, 0, 0, 0, -1))
|
||||
>>> print weeutil.timestamp_to_string(t)
|
||||
>>> print timestamp_to_string(t)
|
||||
2009-03-27 12:00:00 PDT (1238180400)
|
||||
>>> almanac = Almanac(t, 46.0, -122.0)
|
||||
|
||||
Test backwards compatiblity with attributes 'sunrise' and 'sunset'
|
||||
>>> print "Sunrise, sunset:", almanac.sunrise, almanac.sunset
|
||||
Sunrise, sunset: 06:56 19:30
|
||||
|
||||
Test backwards compatiblity with attribute 'moon_fullness':
|
||||
Test backwards compatibility with attribute 'moon_fullness':
|
||||
>>> print "Fullness of the moon (rounded) is %.2f%% [%s]" % (almanac.moon_fullness, almanac.moon_phase)
|
||||
Fullness of the moon (rounded) is 2.00% [new (totally dark)]
|
||||
|
||||
Now get a more precise result for fullness of the moon:
|
||||
>>> print "Fullness of the moon (more precise) is %.2f" % almanac.moon.moon_phase
|
||||
Fullness of the moon (more precise) is 1.70
|
||||
>>> print "Fullness of the moon (more precise) is %.2f%%" % almanac.moon.moon_phase
|
||||
Fullness of the moon (more precise) is 1.70%
|
||||
|
||||
Test backwards compatibility with attributes 'sunrise' and 'sunset'
|
||||
>>> print "Sunrise, sunset:", almanac.sunrise, almanac.sunset
|
||||
Sunrise, sunset: 06:56 19:30
|
||||
|
||||
Get sunrise, sun transit, and sunset using the new 'ephem' syntax:
|
||||
>>> print "Sunrise, sun transit, sunset:", almanac.sun.rise, almanac.sun.transit, almanac.sun.set
|
||||
Sunrise, sun transit, sunset: 06:56 13:13 19:30
|
||||
|
||||
Do the same with the moon:
|
||||
>>> print "Moon rise, moon transit, moon set:", almanac.moon.rise, almanac.moon.transit, almanac.moon.set
|
||||
Moon rise, moon transit, moon set: 06:59 14:01 21:20
|
||||
>>> print "Moon rise, transit, set:", almanac.moon.rise, almanac.moon.transit, almanac.moon.set
|
||||
Moon rise, transit, set: 06:59 14:01 21:20
|
||||
|
||||
Exercise equinox, solstice routines
|
||||
>>> print weeutil.timestamp_to_string(almanac.next_vernal_equinox)
|
||||
2010-03-20 10:32:10 PDT (1269106330)
|
||||
>>> print weeutil.timestamp_to_string(almanac.next_autumnal_equinox)
|
||||
2009-09-22 14:18:38 PDT (1253654318)
|
||||
>>> print weeutil.timestamp_to_string(almanac.next_summer_solstice)
|
||||
2009-06-20 22:45:40 PDT (1245563140)
|
||||
>>> print weeutil.timestamp_to_string(almanac.next_winter_solstice)
|
||||
2009-12-21 09:46:38 PST (1261417598)
|
||||
>>> print almanac.next_vernal_equinox
|
||||
20-Mar-2010 10:32
|
||||
>>> print almanac.next_autumnal_equinox
|
||||
22-Sep-2009 14:18
|
||||
>>> print almanac.next_summer_solstice
|
||||
20-Jun-2009 22:45
|
||||
>>> print almanac.next_winter_solstice
|
||||
21-Dec-2009 09:46
|
||||
|
||||
Exercise moon state routines
|
||||
>>> print weeutil.timestamp_to_string(almanac.next_full_moon)
|
||||
2009-04-09 07:55:49 PDT (1239288949)
|
||||
>>> print weeutil.timestamp_to_string(almanac.next_new_moon)
|
||||
2009-04-24 20:22:33 PDT (1240629753)
|
||||
>>> print almanac.next_full_moon
|
||||
09-Apr-2009 07:55
|
||||
>>> print almanac.next_new_moon
|
||||
24-Apr-2009 20:22
|
||||
|
||||
Now location of the sun and moon
|
||||
>>> print "Solar azimuth, altitude = (%.2f, %.2f)" % (almanac.sun.az, almanac.sun.alt)
|
||||
@@ -122,21 +100,37 @@ class Almanac(object):
|
||||
Moon azimuth, altitude = (133.55, 47.89)
|
||||
"""
|
||||
|
||||
def __init__(self, time_ts, lat, lon,
|
||||
altitude=0, temperature=15.0, pressure=1010.0,
|
||||
moon_phases=Moon.moon_phases, timeformat="%H:%M"):
|
||||
self.lat = lat
|
||||
self.lon = lon
|
||||
self.altitude = altitude
|
||||
self.temperature = temperature
|
||||
self.pressure = pressure
|
||||
self.timeformat = timeformat
|
||||
self.date_tt = (0, 0, 0, 0, 0, 0)
|
||||
def __init__(self, time_ts, lat, lon,
|
||||
altitude=0.0, temperature=15.0, pressure=1010.0,
|
||||
moon_phases=weeutil.Moon.moon_phases,
|
||||
formatter=weewx.units.Formatter()):
|
||||
"""Initialize an instance of Almanac
|
||||
|
||||
self.moon_phases = moon_phases
|
||||
self.moon_phase = ''
|
||||
self.moon_fullness = None
|
||||
time_ts: A unix epoch timestamp for which the almanac will be current.
|
||||
|
||||
lat, lon: Observer's location
|
||||
|
||||
altitude: Observer's elevation in **meters**. [Optional. Default is 0 (sea level)]
|
||||
|
||||
temperature: Observer's temperature in **degrees Celsius**. [Optional. Default is 15.0]
|
||||
|
||||
pressure: Observer's atmospheric pressure in **mBars**. [Optional. Default is 1010]
|
||||
|
||||
moon_phases: An array of 8 strings with descriptions of the moon
|
||||
phase. [optional. If not given, then weeutil.Moon.moon_phases will be used]
|
||||
|
||||
formatter: An instance of weewx.units.Formatter() with the formatting information
|
||||
to be used.
|
||||
"""
|
||||
self.lat = lat
|
||||
self.lon = lon
|
||||
self.altitude = altitude
|
||||
self.temperature = temperature
|
||||
self.pressure = pressure
|
||||
self.moon_phases = moon_phases
|
||||
self.formatter = formatter
|
||||
|
||||
self.date_tt = (0, 0, 0, 0, 0, 0)
|
||||
self.hasExtras = False
|
||||
|
||||
self.setTime(time_ts)
|
||||
@@ -150,76 +144,65 @@ class Almanac(object):
|
||||
if _newdate_tt[0:6] != self.date_tt[0:6] :
|
||||
|
||||
(y,m,d) = _newdate_tt[0:3]
|
||||
(moon_index, _moon_fullness) = Moon.moon_phase(y, m, d)
|
||||
self.moon_phase = self.moon_phases[moon_index] if self.moon_phases is not None else ''
|
||||
(self.moon_index, self._moon_fullness) = weeutil.Moon.moon_phase(y, m, d)
|
||||
self.moon_phase = self.moon_phases[self.moon_index]
|
||||
|
||||
# Check to see whether the user has module 'ephem'. If so, use it.
|
||||
if sys.modules.has_key('ephem'):
|
||||
|
||||
# Set up an observer object holding the location and time:
|
||||
stn = ephem.Observer()
|
||||
stn.long = math.radians(self.lon)
|
||||
stn.lat = math.radians(self.lat)
|
||||
stn.long = math.radians(self.lon)
|
||||
stn.elev = self.altitude
|
||||
stn.temp = self.temperature
|
||||
stn.pressure = self.pressure
|
||||
stn.date = self.time_j1899 = timestamp_to_j1899(time_ts)
|
||||
stn.date = self.time_djd = timestamp_to_djd(time_ts)
|
||||
|
||||
# Sun calculations:
|
||||
self.sun = BodyWrapper(ephem.Sun, stn, self.timeformat) #@UndefinedVariable
|
||||
|
||||
# Moon calculations:
|
||||
self.moon = BodyWrapper(ephem.Moon, stn, self.timeformat)
|
||||
|
||||
# Venus calculations:
|
||||
self.venus = BodyWrapper(ephem.Venus, stn, self.timeformat) #@UndefinedVariable
|
||||
|
||||
# Mars calculations:
|
||||
self.mars = BodyWrapper(ephem.Mars, stn, self.timeformat) #@UndefinedVariable
|
||||
|
||||
# Jupiter calculations:
|
||||
self.jupiter = BodyWrapper(ephem.Jupiter, stn, self.timeformat)
|
||||
|
||||
# This attribute is here for backwards compatiblity.
|
||||
# For full precision, use attribute moon.moon_phase
|
||||
self.moon_fullness = int(self.moon.moon_phase+0.5)
|
||||
# The various celestial bodies offered by the almanac:
|
||||
self.sun = BodyWrapper(ephem.Sun, stn, self.formatter) #@UndefinedVariable
|
||||
self.moon = BodyWrapper(ephem.Moon, stn, self.formatter)
|
||||
self.venus = BodyWrapper(ephem.Venus, stn, self.formatter) #@UndefinedVariable
|
||||
self.mars = BodyWrapper(ephem.Mars, stn, self.formatter) #@UndefinedVariable
|
||||
self.jupiter = BodyWrapper(ephem.Jupiter, stn, self.formatter)
|
||||
|
||||
self.hasExtras = True
|
||||
|
||||
else:
|
||||
|
||||
# No ephem package. Use the weeutil algorithms. Less accurate, but they get the
|
||||
# job done.
|
||||
(sunrise_utc, sunset_utc) = Sun.sunRiseSet(y, m, d, self.lon, self.lat)
|
||||
# No ephem package. Use the weeutil algorithms, which supply a minimum of functionality
|
||||
(sunrise_utc, sunset_utc) = weeutil.Sun.sunRiseSet(y, m, d, self.lon, self.lat)
|
||||
# The above function returns its results in UTC hours. Convert
|
||||
# to a local time tuple
|
||||
sunrise_tt = Almanac._adjustTime(y, m, d, sunrise_utc)
|
||||
sunset_tt = Almanac._adjustTime(y, m, d, sunset_utc)
|
||||
self._sunrise = time.strftime(self.timeformat, sunrise_tt)
|
||||
self._sunset = time.strftime(self.timeformat, sunset_tt)
|
||||
self._sunrise = time.strftime("%H:%M", sunrise_tt)
|
||||
self._sunset = time.strftime("%H:%M", sunset_tt)
|
||||
|
||||
self.moon_fullness = _moon_fullness
|
||||
|
||||
self.hasExtras = False
|
||||
|
||||
self.date_tt = _newdate_tt
|
||||
|
||||
# Short cuts, used for backwards compatibility
|
||||
# Shortcuts, used for backwards compatibility
|
||||
@property
|
||||
def sunrise(self):
|
||||
return self.sun.rise if self.hasExtras else self._sunrise
|
||||
@property
|
||||
def sunset(self):
|
||||
return self.sun.set if self.hasExtras else self._sunset
|
||||
@property
|
||||
def moon_fullness(self):
|
||||
return int(self.moon.moon_phase+0.5) if self.hasExtras else self._moon_fullness
|
||||
|
||||
def __getattr__(self, attr):
|
||||
if self.hasExtras and attr in ['next_autumnal_equinox', 'next_vernal_equinox',
|
||||
if self.hasExtras and attr in ['next_equinox', 'next_solstice',
|
||||
'next_autumnal_equinox', 'next_vernal_equinox',
|
||||
'next_winter_solstice', 'next_summer_solstice',
|
||||
'next_full_moon', 'next_new_moon']:
|
||||
# This is how you call a function on an instance when all you have is its name:
|
||||
j1899 = ephem.__dict__[attr](self.time_j1899) #@UndefinedVariable
|
||||
t = j1899_to_timestamp(j1899)
|
||||
return t
|
||||
djd = ephem.__dict__[attr](self.time_djd) #@UndefinedVariable
|
||||
return weewx.units.ValueHelper((djd, "dublin_jd", "group_time"),
|
||||
context="ephem_year", formatter=self.formatter)
|
||||
else:
|
||||
raise AttributeError, "Unknown attribute "+attr
|
||||
|
||||
@@ -246,10 +229,11 @@ fn_map = {'rise' : 'next_rising',
|
||||
|
||||
class BodyWrapper(object):
|
||||
"""This class wraps a celestial body. It returns results in degrees (instead of radians)
|
||||
and percent (instead of fractions). It also deals with the unfortunately side-effect
|
||||
of changing the state of the body with certain functions."""
|
||||
and percent (instead of fractions). For times, it returns the results as a ValueHelper.
|
||||
It also deals with the unfortunate design decision in pyephem to change
|
||||
the state of the celestial body when using it as an argument in certain functions."""
|
||||
|
||||
def __init__(self, body_factory, observer, timeformat="%H:%M"):
|
||||
def __init__(self, body_factory, observer, formatter):
|
||||
"""Initialize a wrapper
|
||||
|
||||
body_factory: A function that returns an instance of the body
|
||||
@@ -257,62 +241,63 @@ class BodyWrapper(object):
|
||||
|
||||
observer: An instance of ephem.Observer, containing the observer's lat, lon, time, etc.
|
||||
|
||||
timeformat: A strftime style format to be used to format sunrise and sunset.
|
||||
[optional. If not given, then "%H:%M" will be used.
|
||||
formatter: An instance of weewx.units.Formatter(), containing the formatting
|
||||
to be used for times.
|
||||
"""
|
||||
self.body_factory = body_factory
|
||||
self.observer = observer
|
||||
self.timeformat = timeformat
|
||||
self.formatter = formatter
|
||||
self.body = body_factory(observer)
|
||||
(y,m,d) = time.localtime(j1899_to_timestamp(observer.date))[0:3]
|
||||
self.sod_j1899 = timestamp_to_j1899(time.mktime((y,m,d,0,0,0,0,0,-1)))
|
||||
|
||||
# Calculate and store the start-of-day in Dublin Julian Days:
|
||||
(y,m,d) = time.localtime(djd_to_timestamp(observer.date))[0:3]
|
||||
self.sod_djd = timestamp_to_djd(time.mktime((y,m,d,0,0,0,0,0,-1)))
|
||||
|
||||
def __getattr__(self, attr):
|
||||
if attr in ['az', 'alt', 'a_ra', 'a_dec', 'g_ra', 'ra', 'g_dec', 'dec',
|
||||
'elong', 'radius', 'hlong', 'hlat', 'sublat', 'sublong']:
|
||||
# Return the results in degrees rather than radians
|
||||
v = getattr(self.body, attr)
|
||||
return math.degrees(v)
|
||||
return math.degrees(getattr(self.body, attr))
|
||||
elif attr=='moon_phase':
|
||||
# Return the result in percent
|
||||
v = getattr(self.body, attr)
|
||||
return 100.0 * v
|
||||
return 100.0 * self.body.moon_phase
|
||||
elif attr in ['next_rising', 'next_setting', 'next_transit', 'next_antitransit',
|
||||
'previous_rising', 'previous_setting', 'previous_transit', 'previous_antitransit']:
|
||||
# These functions have the unfortunate side effect of changing the state of the body
|
||||
# being examined. So, create a temporary body and then throw it away
|
||||
temp_body = self.body_factory()
|
||||
time_j1899 = getattr(self.observer, attr)(temp_body)
|
||||
return j1899_to_string(time_j1899, self.timeformat)
|
||||
elif attr in ['rise', 'set', 'transit']:
|
||||
# These functions have the unfortunate side effect of changing the state of the body
|
||||
# being examined. So, create a temporary body and then throw it away
|
||||
time_djd = getattr(self.observer, attr)(temp_body)
|
||||
return weewx.units.ValueHelper((time_djd, "dublin_jd", "group_time"), context="ephem_day", formatter=self.formatter)
|
||||
elif attr in fn_map:
|
||||
# These attribute names have to be mapped to a different function name. Like the
|
||||
# attributes above, they also have the side effect of changing the state of the body.
|
||||
# Finally, they return the time of the event anywhere in the day (not just the next
|
||||
# event), so they take a second argument in the function call.
|
||||
temp_body = self.body_factory(self.observer)
|
||||
# Look up the function to be called for this attribute (eg, call 'next_rising' for 'rise')
|
||||
fn = fn_map[attr]
|
||||
time_j1899 = getattr(self.observer, fn)(temp_body, self.sod_j1899)
|
||||
return j1899_to_string(time_j1899, self.timeformat)
|
||||
# Call the function, with a second argument giving the start-of-day
|
||||
time_djd = getattr(self.observer, fn)(temp_body, self.sod_djd)
|
||||
return weewx.units.ValueHelper((time_djd, "dublin_jd", "group_time"), context="ephem_day", formatter=self.formatter)
|
||||
else:
|
||||
# Just return the result unchanged.
|
||||
return getattr(self.body, attr)
|
||||
|
||||
def timestamp_to_j1899(time_ts):
|
||||
"""Convert from a unix time stamp to the number of days since 12/31/1899 12:00 UTC"""
|
||||
def timestamp_to_djd(time_ts):
|
||||
"""Convert from a unix time stamp to the number of days since 12/31/1899 12:00 UTC
|
||||
(aka "Dublin Julian Days")"""
|
||||
# The number 25567.5 is the start of the Unix epoch (1/1/1970). Just add on the
|
||||
# number of days since then
|
||||
return 25567.5 + time_ts/86400.0
|
||||
|
||||
def j1899_to_timestamp(j1899):
|
||||
"""Convert from number of days since 12/31/1899 12:00 UTC to unix time stamp"""
|
||||
return (j1899-25567.5) * 86400.0
|
||||
|
||||
def j1899_to_string(j1899, timeformat="%H:%M"):
|
||||
time_tt = time.localtime(j1899_to_timestamp(j1899))
|
||||
return time.strftime(timeformat, time_tt)
|
||||
def djd_to_timestamp(djd):
|
||||
"""Convert from number of days since 12/31/1899 12:00 UTC ("Dublin Julian Days") to unix time stamp"""
|
||||
return (djd-25567.5) * 86400.0
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
import doctest
|
||||
import weeutil #@UnusedImport
|
||||
from weeutil.weeutil import timestamp_to_string #@UnusedImport
|
||||
|
||||
doctest.testmod()
|
||||
|
||||
@@ -17,8 +17,8 @@ import time
|
||||
import Cheetah.Template
|
||||
import Cheetah.Filters
|
||||
|
||||
import weeutil.Almanac
|
||||
import weeutil.weeutil
|
||||
import weewx.almanac
|
||||
import weewx.archive
|
||||
import weewx.reportengine
|
||||
import weewx.station
|
||||
@@ -304,13 +304,14 @@ class FileGenerator(weewx.reportengine.ReportGenerator):
|
||||
if temperature_C is None: temperature_C = 15.0
|
||||
if pressure_mbar is None: pressure_mbar = 1010.0
|
||||
|
||||
self.almanac = weeutil.Almanac.Almanac(celestial_ts,
|
||||
self.station.latitude_f,
|
||||
self.station.longitude_f,
|
||||
altitude_vt[0],
|
||||
temperature_C,
|
||||
pressure_mbar,
|
||||
self.moonphases)
|
||||
self.almanac = weewx.almanac.Almanac(celestial_ts,
|
||||
self.station.latitude_f,
|
||||
self.station.longitude_f,
|
||||
altitude_vt[0],
|
||||
temperature_C,
|
||||
pressure_mbar,
|
||||
self.moonphases,
|
||||
self.formatter)
|
||||
|
||||
def _prepGen(self, subskin_dict):
|
||||
|
||||
|
||||
@@ -168,7 +168,9 @@ conversionDict = {
|
||||
'mm' : lambda x : x * 10.0},
|
||||
'mm' : {'inch' : lambda x : x * .0393700787,
|
||||
'cm' : lambda x : x * 0.10},
|
||||
'meter' : {'foot' : lambda x : x * 3.2808399 } }
|
||||
'meter' : {'foot' : lambda x : x * 3.2808399 },
|
||||
'dublin_jd' : {'unix_epoch' : lambda x : (x-25567.5) * 86400.0},
|
||||
'unix_epoch' : {'dublin_jd' : lambda x : x/86400.0 + 25567.5}}
|
||||
|
||||
|
||||
# Default unit formatting to be used in the absence of a skin configuration file
|
||||
@@ -237,12 +239,14 @@ default_unit_label_dict = { "centibar" : " cb",
|
||||
|
||||
# Default strftime formatting to be used in the absence of a skin
|
||||
# configuration file:
|
||||
default_time_format_dict = {"day" : "%H:%M",
|
||||
"week" : "%H:%M on %A",
|
||||
"month" : "%d-%b-%Y %H:%M",
|
||||
"year" : "%d-%b-%Y %H:%M",
|
||||
"rainyear" : "%d-%b-%Y %H:%M",
|
||||
"current" : "%d-%b-%Y %H:%M"}
|
||||
default_time_format_dict = {"day" : "%H:%M",
|
||||
"week" : "%H:%M on %A",
|
||||
"month" : "%d-%b-%Y %H:%M",
|
||||
"year" : "%d-%b-%Y %H:%M",
|
||||
"rainyear" : "%d-%b-%Y %H:%M",
|
||||
"current" : "%d-%b-%Y %H:%M",
|
||||
"ephem_day" : "%H:%M",
|
||||
"ephem_year" : "%d-%b-%Y %H:%M"}
|
||||
|
||||
|
||||
#===============================================================================
|
||||
@@ -299,6 +303,9 @@ class Formatter(object):
|
||||
self.unit_format_dict = unit_format_dict
|
||||
self.unit_label_dict = unit_label_dict
|
||||
self.time_format_dict = time_format_dict
|
||||
# Add new keys for backwards compatibility on old skin dictionaries:
|
||||
self.time_format_dict.setdefault('ephem_day', "%H:%M")
|
||||
self.time_format_dict.setdefault('ephem_year', "%d-%b-%Y %H:%M")
|
||||
|
||||
@staticmethod
|
||||
def fromSkinDict(skin_dict):
|
||||
@@ -336,7 +343,7 @@ class Formatter(object):
|
||||
if useThisFormat:
|
||||
val_str = time.strftime(useThisFormat, time.localtime(val_t[0]))
|
||||
else:
|
||||
val_str = time.strftime(self.time_format_dict[context], time.localtime(val_t[0]))
|
||||
val_str = time.strftime(self.time_format_dict.get(context, "%d-%b-%Y %H:%M"), time.localtime(val_t[0]))
|
||||
except (KeyError, TypeError):
|
||||
# If all else fails, use this weeutil utility:
|
||||
val_str = weeutil.weeutil.timestamp_to_string(val_t[0])
|
||||
|
||||
@@ -781,6 +781,45 @@ December: Min, max temperatures: N/A N/A
|
||||
<p>See the NOAA template files <span class="code">NOAA/NOAA-YYYY.txt.tmpl</span>
|
||||
and <span class="code">NOAA/NOAA-YYYY-MM.txt.tmpl</span> for examples using
|
||||
iteration, as well as explicit formatting.</p>
|
||||
<h3>Almanac</h3>
|
||||
<p>If module <a href="http://rhodesmill.org/pyephem">pyephem</a> has been
|
||||
installed, then <span class="code">weewx</span> can generate extensive
|
||||
almanac information for the Sun, Moon, Venus, Mars, and Jupiter, including
|
||||
their rise, transit and set times, as well as their azimuth and altitude.
|
||||
Other information is also available. </p>
|
||||
<p>Here is a small sampling:</p>
|
||||
<pre><html>
|
||||
<head>
|
||||
<title>Almanac data</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>Current time is $current.dateTime<p>
|
||||
#if $almanac.hasExtras
|
||||
<p>Sunrise, transit, sunset: $almanac.sun.rise $almanac.sun.transit $almanac.sun.set</p>
|
||||
<p>Moonrise, transit, moonset: $almanac.moon.rise $almanac.moon.transit $almanac.moon.set</p>
|
||||
<p>Mars rise, transit, set: $almanac.mars.rise $almanac.mars.transit $almanac.mars.set</p>
|
||||
<p>Azimuth, altitude of mars: $almanac.mars.az $almanac.mars.alt</p>
|
||||
<p>Next new, full moon: $almanac.next_new_moon $almanac.next_full_moon</p>
|
||||
<p>Next summer, winter solstice: $almanac.next_summer_solstice $almanac.next_winter_solstice</p>
|
||||
#else
|
||||
<p>Sunrise, sunset: $almanac.sunrise $almanac.sunset</p>
|
||||
#end if
|
||||
</body>
|
||||
</html></pre>
|
||||
<p>If your installation has pyephem installed this would result in:</p>
|
||||
<pre>Current time is 29-Mar-2011 09:20
|
||||
Sunrise, transit, sunset: 06:51 13:11 19:30
|
||||
Moonrise, transit, moonset: 04:33 09:44 15:04
|
||||
Mars rise, transit, set: 06:35 12:30 18:26
|
||||
Azimuth, altitude of mars: 124.354959275 26.4808431952
|
||||
Next new, full moon: 03-Apr-2011 07:32 17-Apr-2011 19:43
|
||||
Next summer, winter solstice: 21-Jun-2011 10:16 21-Dec-2011 21:29</pre>
|
||||
<p>Otherwise, a fallback position is used, resulting in</p>
|
||||
<pre>Current time is 29-Mar-2011 09:20
|
||||
Sunrise, sunset: 06:51 19:30
|
||||
</pre>
|
||||
<p>As shown in the example, you can test whether this extended almanac information is available with
|
||||
the value <span class="code">$almanac.hasExtras</span>.</p>
|
||||
<h2>Writing a custom generator</h2>
|
||||
<p>To do more sophisticated customization it may be necessary to extend an existing
|
||||
generator, or write your own. </p>
|
||||
@@ -1039,6 +1078,13 @@ month = %d-%b-%Y %H:%M</pre>
|
||||
<p>would specify that week data should use a format such as "<span class="code">15:20
|
||||
on Sunday</span>", while month data should look like "<span class="code">06-Oct-2009
|
||||
15:20</span>"</p>
|
||||
<p>It also allows the formatting to be set for almanac times:</p>
|
||||
<pre>ephem_day = %H:%M
|
||||
ephem_year = %d-%b-%Y %H:%M</pre>
|
||||
<p>The first of these, <span class="code">ephem_day</span>, is used for
|
||||
almanac times within the day, such as sunrise or sunset. The second,
|
||||
<span class="code">ephem_year</span>, is used for almanac times within the
|
||||
year, such as the next equinox or full moon.</p>
|
||||
<h3 class="config_section">[[DegreeDays]] </h3>
|
||||
<p class="config_important">heating_base<br />
|
||||
cooling_base</p>
|
||||
|
||||
@@ -99,7 +99,7 @@ Version 1.10</h1>
|
||||
<h1><a name="Prerequisites">Prerequisites</a></h1>
|
||||
<h2>Python</h2>
|
||||
<p>Python V2.5 or V2.6 is required. The newer V3.0 distribution will not work.</p>
|
||||
<h2>Required packages</h2>
|
||||
<h2>External packages</h2>
|
||||
<p>The following external packages are required to use <span class="code">weewx</span>.</p>
|
||||
<ol>
|
||||
<li><a href="http://www.sqlite.org/">sqlite3</a> (Version 3.5 or greater)
|
||||
@@ -118,6 +118,13 @@ Version 1.10</h1>
|
||||
(Version 1.1.6 or greater) Also known as PIL, this is included in many Python
|
||||
distributions.</li>
|
||||
</ol>
|
||||
<p>In addition, there is one optional package:</p>
|
||||
<ul>
|
||||
<li><a href="http://rhodesmill.org/pyephem">pyephem</a> (Version V3.7.3
|
||||
or greater). For extended almanac information. If not installed,
|
||||
fallback information will be used. As of the time of this writing, this
|
||||
package could only be installed using <span class="code">easy_install</span>.</li>
|
||||
</ul>
|
||||
<p>There are two general strategies for installing these prerequisites:</p>
|
||||
<ol>
|
||||
<li>Use operating system tools, such as <span class="code">apt-get</span>
|
||||
@@ -127,7 +134,11 @@ Version 1.10</h1>
|
||||
<a href="http://pypi.python.org/pypi/setuptools">easy_install</a></span>.</li>
|
||||
</ol>
|
||||
<p>Option #1 is easier, but if your Linux distribution does not come with such
|
||||
tools, you may have to use <span class="code">easy_install</span>. Brief instructions
|
||||
tools, you may have to use <span class="code">easy_install</span>. If you
|
||||
choose to install <a href="http://rhodesmill.org/pyephem">pyephem</a>, then
|
||||
it can only be installed using <span class="code">easy_install</span> (<a href="#Installing_pyephem">see
|
||||
instructions below</a>).</p>
|
||||
<p>Brief instructions
|
||||
for both approaches are given below.</p>
|
||||
<h3>Installation on Debian distributions (including Ubuntu) using
|
||||
<span class="code">apt-get</span></h3>
|
||||
@@ -214,6 +225,9 @@ Version 1.10</h1>
|
||||
<p>My version of Python came with V1.1.6, which works great, but if you need
|
||||
to install</p>
|
||||
<pre>easy_install pil</pre>
|
||||
<p><a name="Installing_pyephem"></a>If you choose to install the optional
|
||||
package pyephem:</p>
|
||||
<pre>easy_install pyephem</pre>
|
||||
<h2>System requirements</h2>
|
||||
<p>I run <span class="code">weewx</span> on a 500MHz system with an AMD Geode
|
||||
processor and 512 MB of memory. Configured this way, it consumes about
|
||||
|
||||
8
setup.py
8
setup.py
@@ -175,6 +175,8 @@ class My_install_data(install_data):
|
||||
new_config = configobj.ConfigObj(f)
|
||||
new_config.indent_type = ' '
|
||||
new_version_number = VERSION.split('.')
|
||||
if len(new_version_number[1]) < 2:
|
||||
new_version_number[1] = '0'+new_version_number[1]
|
||||
|
||||
# Sometimes I forget to turn the debug flag off:
|
||||
new_config['debug'] = 0
|
||||
@@ -192,10 +194,14 @@ class My_install_data(install_data):
|
||||
# assume a very old version:
|
||||
if not old_version: old_version = '1.0.0'
|
||||
old_version_number = old_version.split('.')
|
||||
# Take care of the collation problem when comparing things like
|
||||
# version '1.9' to '1.10' by prepending a '0' to the former:
|
||||
if len(old_version_number[1]) < 2:
|
||||
old_version_number[1] = '0'+old_version_number[1]
|
||||
|
||||
# If the user has a version >= 1.7, then merge in the old
|
||||
# config file.
|
||||
if old_version_number[0:2] >= ['1','7']:
|
||||
if old_version_number[0:2] >= ['1','07']:
|
||||
# Any user changes in old_config will overwrite values in new_config
|
||||
# with this merge
|
||||
new_config.merge(old_config)
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
## $Revision$
|
||||
## $Author$
|
||||
## $Date$
|
||||
#set $short_time time.strftime("%H:%M"
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head profile="http://www.w3.org/2005/10/profile">
|
||||
@@ -321,66 +320,93 @@
|
||||
<div class="header">
|
||||
Today's Almanac
|
||||
</div>
|
||||
<table>
|
||||
<caption class="caption">Sun</caption>
|
||||
<tr>
|
||||
<td class="label">Sunrise:</td>
|
||||
<td class="data">$almanac.sunrise</td>
|
||||
</tr>
|
||||
#if $almanac.hasExtras
|
||||
<tr>
|
||||
<td class="label">Transit:</td>
|
||||
<td class="data">$almanac.sun.transit</td>
|
||||
</tr>
|
||||
#end if
|
||||
<tr>
|
||||
<td class="label">Sunset:</td>
|
||||
<td class="data">$almanac.sunset</td>
|
||||
</tr>
|
||||
#if $almanac.hasExtras
|
||||
#set $sun_az = "%.1f°" % $almanac.sun.az
|
||||
#set $sun_alt= "%.1f°" % $almanac.sun.alt
|
||||
<tr>
|
||||
<td class="label">Azimuth:</td>
|
||||
<td class="data">$sun_az</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">Altitude:</td>
|
||||
<td class="data">$sun_alt</td>
|
||||
</tr>
|
||||
#end if
|
||||
</table>
|
||||
<table>
|
||||
<caption class="caption">Moon</caption>
|
||||
<tr>
|
||||
<td class="label">Phase:</td>
|
||||
<td class="data">$almanac.moon_phase ($almanac.moon_fullness% full)</td>
|
||||
</tr>
|
||||
#if $almanac.hasExtras
|
||||
<tr>
|
||||
<td class="label">Rise:</td>
|
||||
<td class="data">$almanac.moon.rise
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">Transit:</td>
|
||||
<td class="data">$almanac.moon.transit
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">Set:</td>
|
||||
<td class="data">$almanac.moon.set
|
||||
</tr>
|
||||
#set $moon_az = "%.1f°" % $almanac.moon.az
|
||||
#set $moon_alt= "%.1f°" % $almanac.moon.alt
|
||||
<tr>
|
||||
<td class="label">Azimuth:</td>
|
||||
<td class="data">$moon_az</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">Altitude:</td>
|
||||
<td class="data">$moon_alt</td>
|
||||
</tr>
|
||||
#end if
|
||||
</table>
|
||||
<div class="celestial_group">
|
||||
<div class="celestial_body">
|
||||
<table>
|
||||
<caption class="caption">Sun</caption>
|
||||
#if $almanac.hasExtras
|
||||
<tr>
|
||||
<td class="label">Sunrise:</td>
|
||||
<td class="data">$almanac.sun.rise</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">Transit:</td>
|
||||
<td class="data">$almanac.sun.transit</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">Sunset:</td>
|
||||
<td class="data">$almanac.sun.set</td>
|
||||
</tr>
|
||||
#else
|
||||
<tr>
|
||||
<td class="label">Sunrise:</td>
|
||||
<td class="data">$almanac.sunrise</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">Sunset:</td>
|
||||
<td class="data">$almanac.sunset</td>
|
||||
</tr>
|
||||
#end if
|
||||
#if $almanac.hasExtras
|
||||
<tr>
|
||||
<td class="label">Azimuth:</td>
|
||||
<td class="data">$("%.1f°" % $almanac.sun.az)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">Altitude:</td>
|
||||
<td class="data">$("%.1f°" % $almanac.sun.alt)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">Equinox:</td>
|
||||
<td class="data">$almanac.next_equinox
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">Solstice:</td>
|
||||
<td class="data">$almanac.next_solstice
|
||||
</tr>
|
||||
#end if
|
||||
</table>
|
||||
</div> <!-- end class "celestial_body" -->
|
||||
<div class="celestial_body">
|
||||
<table>
|
||||
<caption class="caption">Moon</caption>
|
||||
#if $almanac.hasExtras
|
||||
<tr>
|
||||
<td class="label">Rise:</td>
|
||||
<td class="data">$almanac.moon.rise
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">Transit:</td>
|
||||
<td class="data">$almanac.moon.transit
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">Set:</td>
|
||||
<td class="data">$almanac.moon.set
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">Azimuth:</td>
|
||||
<td class="data">$("%.1f°" % $almanac.moon.az)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">Altitude:</td>
|
||||
<td class="data">$("%.1f°" % $almanac.moon.alt)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">Full moon:</td>
|
||||
<td class="data">$almanac.next_full_moon
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">New moon:</td>
|
||||
<td class="data">$almanac.next_new_moon
|
||||
</tr>
|
||||
#end if
|
||||
<tr>
|
||||
<td class="label">Phase:</td>
|
||||
<td class="data">$almanac.moon_phase<br/>($almanac.moon_fullness% full)</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div> <!-- end class "celestial_body" -->
|
||||
</div> <!-- end class "celestial_group" -->
|
||||
</div> <!-- end id "almanac" -->
|
||||
|
||||
<div id="plots">
|
||||
|
||||
@@ -136,12 +136,14 @@
|
||||
# This section sets the string format to be used
|
||||
# each time scale.
|
||||
#
|
||||
day = %H:%M
|
||||
week = %H:%M on %A
|
||||
month = %d-%b-%Y %H:%M
|
||||
year = %d-%b-%Y %H:%M
|
||||
rainyear = %d-%b-%Y %H:%M
|
||||
current = %d-%b-%Y %H:%M
|
||||
day = %H:%M
|
||||
week = %H:%M on %A
|
||||
month = %d-%b-%Y %H:%M
|
||||
year = %d-%b-%Y %H:%M
|
||||
rainyear = %d-%b-%Y %H:%M
|
||||
current = %d-%b-%Y %H:%M
|
||||
ephem_day = %H:%M
|
||||
ephem_year = %d-%b-%Y %H:%M
|
||||
|
||||
[[DegreeDays]]
|
||||
#
|
||||
|
||||
@@ -102,6 +102,189 @@ body {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#content .header {
|
||||
font-size: 14pt;
|
||||
font-weight: bolder;
|
||||
color: #3d6c87;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
|
||||
#content .caption {
|
||||
font-weight: bold;
|
||||
color: #3d6c87;
|
||||
}
|
||||
|
||||
#content .label {
|
||||
text-align: right;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
#content .data {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#about, #almanac {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
#almanac {
|
||||
width:80%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.celestial_group {
|
||||
}
|
||||
|
||||
.celestial_body {
|
||||
width: 48%;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
#plots {
|
||||
width: 90%;
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
#plots img {
|
||||
margin: 3px;
|
||||
border: thin solid #3d6c87;
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
#radar_img {
|
||||
width: 90%;
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
#radar_img img {
|
||||
width: 90%;
|
||||
padding: 3px;
|
||||
margin: 3px;
|
||||
}
|
||||
|
||||
/*
|
||||
* Navigation bar (week, month, etc.) at the bottom
|
||||
*/
|
||||
#navbar {
|
||||
margin: 0 1% 1% 1%;
|
||||
padding: 5px;
|
||||
text-align: center;
|
||||
clear: both;
|
||||
border-top: 1px solid #dcdcdc;
|
||||
border-right: 1px solid #a9a9a9;
|
||||
border-bottom: 1px solid #808080;
|
||||
border-left: 1px solid #a9a9a9;
|
||||
background-color: #fafaff;
|
||||
}
|
||||
|
||||
/*************** Global Styles ***************/
|
||||
|
||||
h2, h3, h4, h5, h6 {
|
||||
color: #3d6c87;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-family: Verdana, Arial, Helvetica, sans-serif;
|
||||
font-size: 10pt;
|
||||
background-color: #f2f2f7;
|
||||
background-image: url('backgrounds/band.gif');
|
||||
background-repeat: repeat;
|
||||
background-attachment: scroll;
|
||||
}
|
||||
|
||||
#container {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the big header at the top of the page
|
||||
*/
|
||||
#masthead {
|
||||
margin: 1% 1% 0 1%;
|
||||
padding: 5px;
|
||||
text-align: center;
|
||||
border-top: 1px solid #dcdcdc;
|
||||
border-right: 1px solid #a9a9a9;
|
||||
border-bottom: 1px solid #808080;
|
||||
border-left: 1px solid #a9a9a9;
|
||||
background-color: #fafaff;
|
||||
}
|
||||
|
||||
#masthead h1 {
|
||||
color: #3d6c87;
|
||||
}
|
||||
#masthead h3 {
|
||||
color: #5f8ea9;
|
||||
}
|
||||
|
||||
/*
|
||||
* This holds the statistics (daily high/low, etc.) on the left:
|
||||
*/
|
||||
#stats_group {
|
||||
width: 30%;
|
||||
min-height: 500px;
|
||||
margin: 1%;
|
||||
padding: 5px;
|
||||
float: left;
|
||||
border-top: 1px solid #dcdcdc;
|
||||
border-right: 1px solid #a9a9a9;
|
||||
border-bottom: 1px solid #808080;
|
||||
border-left: 1px solid #a9a9a9;
|
||||
background-color: #fafaff;
|
||||
}
|
||||
|
||||
.stats table {
|
||||
border: thin solid #000000;
|
||||
width: 100%;
|
||||
}
|
||||
.stats td {
|
||||
border: thin solid #000000;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.stats_header {
|
||||
background-color: #000000;
|
||||
color: #a8b8c8;
|
||||
font-size: 14pt;
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
.stats_label {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.stats_data {
|
||||
color: red;
|
||||
}
|
||||
|
||||
/*
|
||||
* This holds the "About", "Almanac", and plots on the right
|
||||
*/
|
||||
#content {
|
||||
width: 62%;
|
||||
min-height: 500px;
|
||||
margin: 1%;
|
||||
padding: 5px;
|
||||
float: right;
|
||||
border-top: 1px solid #dcdcdc;
|
||||
border-right: 1px solid #a9a9a9;
|
||||
border-bottom: 1px solid #808080;
|
||||
border-left: 1px solid #a9a9a9;
|
||||
background-color: #fafaff;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#content .header {
|
||||
text-align: center;
|
||||
font-size: 14pt;
|
||||
@@ -122,35 +305,38 @@ body {
|
||||
|
||||
#content td {
|
||||
width: 50%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#content .label {
|
||||
text-align: right;
|
||||
font-style: italic;
|
||||
padding-right: 2px;
|
||||
}
|
||||
|
||||
#content .data {
|
||||
text-align: left;
|
||||
padding-left: 2px;
|
||||
}
|
||||
|
||||
#about, #almanac {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.celestial_group {
|
||||
#almanac {
|
||||
# border: thin solid #3d6c87;
|
||||
width:60%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
.celestial_group {
|
||||
}
|
||||
|
||||
.celestial_body {
|
||||
width: 48%;
|
||||
# border: thin solid #3d6c87;
|
||||
border-top: 1px solid #3d6c87;
|
||||
border-left:1px solid #3d6c87;
|
||||
border-bottom: 2px solid #3d6c87;
|
||||
border-right: 2px solid #3d6c87;
|
||||
# border-top: 1px solid #3d6c87;
|
||||
# border-left:1px solid #3d6c87;
|
||||
# border-bottom: 2px solid #3d6c87;
|
||||
# border-right: 2px solid #3d6c87;
|
||||
display:inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
@@ -201,4 +387,3 @@ body {
|
||||
h2, h3, h4, h5, h6 {
|
||||
color: #3d6c87;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ debug = 0
|
||||
socket_timeout = 20
|
||||
|
||||
# Current version
|
||||
version = 1.10.0a6
|
||||
version = 1.10.0
|
||||
|
||||
############################################################################################
|
||||
|
||||
|
||||
Reference in New Issue
Block a user