Skip to content

Commit

Permalink
Merge branch 'bootstrap_3.2.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
brewster76 committed Dec 27, 2014
2 parents c30a839 + 668efee commit e4a6f45
Show file tree
Hide file tree
Showing 20 changed files with 1,171 additions and 1,566 deletions.
38 changes: 21 additions & 17 deletions INSTALL
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,21 @@ How to install
==============

Before we begin...
1) This has been tested on weewx versions 2.4.0 - 2.6.2, on Ubuntu linux 12.04, and on a Raspberry Pi running wheezy.
2) Only sqlite databases currently supported, not mysql.
1) This release (v2.1) has been tested on weewx version 3.0.1, on Ubuntu linux 14.04 and on a Raspberry Pi running
wheezy.
Versions of Weewx before v3 will not work. The earlier release v2.01 is on github and works with Weewx 2.4 - 2.7.
2) This has been tested on sqlite databases. Mysql may work however this has not been tested.


The easy way
============

Get hold of v2.0.tar.gz.
Get hold of the v2.1 archive from github: https://github.com/brewster76/fuzzy-archer/archive/v2.1.tar.gz

Use the WeeWx extension installer:

cd /home/weewx
setup.py --extension --install [wherever you've put v2.0.tar.gz]
setup.py --extension --install [wherever you've put v2.1.tar.gz]

Web content is stored in public_html/Bootstrap.

Expand All @@ -36,6 +38,7 @@ To get the latest stable(ish) release, point your browser here:
Move gaugeengine.py, gauges.py and historyengine,py into the bin/user directory.
Move the Bootstrap and Images directory into the skins directory.


Step 2 - Add the skins to weewx.conf
------------------------------------

Expand All @@ -55,14 +58,14 @@ So the [StdReport] section will need to look something like this:
# Dimensions are set in the Images/skin.conf file
#
skin = Images
HTML_ROOT = public_html/
HTML_ROOT = public_html/Bootstrap

[[BigImages]]
# These images are used when a small web page image is clicked on.
# So the skin.conf image_width and image_height are overridden here.
#
skin = Images
HTML_ROOT = public_html/big_images/
HTML_ROOT = public_html/Bootstrap/big_images/
[[[ImageGenerator]]]
image_width = 800
image_height = 500
Expand All @@ -71,28 +74,29 @@ So the [StdReport] section will need to look something like this:
# This generates the webpages themselves.
#
skin = Bootstrap
HTML_ROOT = public_html/
HTML_ROOT = public_html/Bootstrap

[[FTP]]
skin = Ftp

[[RSYNC]]
skin = Rsync


Step 3 - Add Bootstrap support files to your website
----------------------------------------------------

Add these files to weewx/public_html/assets
Add this file to weewx/public_html/js:
bootstrap.min.js

assets/css:
bootstrap.css bootstrap.min.css bootstrap-responsive.css bootstrap-responsive.min.css lightbox.css
and this one to weewx/public_html/css:
css/bootstrap.min.css

assets/img:
close.png glyphicons-halflings.png glyphicons-halflings-white.png loading.gif next.png prev.png
You can use the wget command to download these:
wget https://raw.githubusercontent.com/brewster76/fuzzy-archer/v2.1/public_html/Bootstrap/css/bootstrap.min.css
wget https://raw.githubusercontent.com/brewster76/fuzzy-archer/v2.1/public_html/Bootstrap/js/bootstrap.min.js

assets/js:
bootstrap-affix.js bootstrap-carousel.js bootstrap.js bootstrap-popover.js bootstrap-tooltip.js jquery-1.7.2.min.js
bootstrap-alert.js bootstrap-collapse.js bootstrap.min.js bootstrap-scrollspy.js bootstrap-transition.js jquery.js
bootstrap-button.js bootstrap-dropdown.js bootstrap-modal.js bootstrap-tab.js bootstrap-typeahead.js lightbox.js

You can download these from dajda.net/assets
Step 4 - (Optional) Translate skins to Spanish Language
-------------------------------------------------------
For skins in Spanish please use v2.01. They are in the process of being ported over to v2.1.
4 changes: 4 additions & 0 deletions TODO
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
1) Clicking on images brings up larger ones again.
2) Translate to Spanish.
3) Use a image library which draws with pens/brushes rather than pixels, e.g. aggdraw or pillow.
4) Luc's edits to historygenerator.py.
144 changes: 69 additions & 75 deletions bin/user/gaugeengine.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@
#
"""Nick's custom generator for creating visual gauge image files from weewx.
Tested on weewx release 2.5.1
Tested on Weewx release 3.0.1.
Tested with sqlite, may not work with other databases.
WILL NOT WORK WITH Weewx prior to release 3.0.
-- Use this version for 2.4 - 2.7: https://github.com/brewster76/fuzzy-archer/releases/tag/v2.0
Directions for use:
1) Put this file in the weewx/bin/user directory.
Expand All @@ -18,19 +21,13 @@
4) Guage names must match the Weewx field name, e.g. outTemp or barometer
5) Here is an example [GaugeGenerator] section:
###############################################################################
############################################################################################
#
# Settings for Nick's gauge generator
# Settings for Gauge Generator
#
[GaugeGenerator]
image_width = 180
image_height = 180
labelfontsize = 12
# This overwrites HTML_ROOT in weewx.conf if you want the images elsewhere
HTML_ROOT = public_html/gauges/
font_path = /usr/share/fonts/truetype/freefont/FreeSans.ttf
image_width = 160
image_height = 160
# Colors...
#
Expand All @@ -49,8 +46,8 @@
# Must be an integer
dial_arc = 270
digitfontsize = 15
labelfontsize = 16
digitfontsize = 13
labelfontsize = 14
[[outTemp]]
minvalue = -20
Expand Down Expand Up @@ -100,23 +97,21 @@
invert = false
history = 24
bins = 16
aggregate_type = None
"""

import time
import syslog
import os.path

import Image

import weeutil.weeutil
import weewx.archive
import weewx.reportengine
import weeplot.utilities
import user.gauges

from weewx.units import ValueTupleDict, Converter

class GaugeGenerator(weewx.reportengine.CachedReportGenerator):
class GaugeGenerator(weewx.reportengine.ReportGenerator):
"""Class for managing the gauge generator."""

def run(self):
Expand All @@ -126,13 +121,20 @@ def run(self):
self.gen_gauges()

def setup(self):
self.db_manager = self.db_binder.get_manager()

self.gauge_dict = self.skin_dict['GaugeGenerator']
self.units_dict = self.skin_dict['Units']

# Lookup the last reading in the archive
self.archivedb = self._getArchive(self.skin_dict['archive_database'])
rec = self._get_record(self.archivedb, self.archivedb.lastGoodStamp())
self.record_dict_vtd = weewx.units.ValueTupleDict(rec)
self.lastGoodStamp = self.db_manager.lastGoodStamp()
last_reading = self.db_manager.getRecord(self.db_manager.lastGoodStamp())

# Create a converter to get this into the desired units
self.converter = weewx.units.Converter(self.units_dict['Groups'])

self.record_dict_vtd = self.converter.convertDict(last_reading)
self.record_dict_vtd['usUnits'] = self.db_manager.std_unit_system

def gen_gauges(self):
"""Generate the gauges."""
Expand Down Expand Up @@ -160,7 +162,7 @@ def gen_gauges(self):
t2 = time.time()

syslog.syslog(syslog.LOG_INFO, "GaugeGenerator: Generated %d images for %s in %.2f seconds" %
(ngen, self.skin_dict['REPORT_NAME'], t2 - t1))
(ngen, self.skin_dict['REPORT_NAME'], t2 - t1))

def gen_gauge(self, gaugename, plot_options, img_file):
image_width = int(plot_options.get('image_width', 180))
Expand All @@ -174,7 +176,7 @@ def gen_gauge(self, gaugename, plot_options, img_file):
dial_color = weeplot.utilities.tobgr(plot_options.get('dial_color', '0x707070'))
needle_outline_color = weeplot.utilities.tobgr(plot_options.get('needle_outline_color', '0xb48242'))
needle_fill_color = plot_options.get('needle_fill_color', None)
if needle_fill_color == None or needle_fill_color == 'None' or needle_fill_color == 'Opaque':
if needle_fill_color is None or needle_fill_color == 'None' or needle_fill_color == 'Opaque':
needle_fill_color = None
else:
needle_fill_color = weeplot.utilities.tobgr(needle_fill_color)
Expand All @@ -197,18 +199,20 @@ def gen_gauge(self, gaugename, plot_options, img_file):

# Create a new gauge instance using the gauges.py library
if gaugename == 'windRose':
digitformat = None
gauge = user.gauges.WindRoseGaugeDraw(image, background_color=back_color)
wind_units = self.converter.getTargetUnit('windSpeed')
else:
wind_units = None

if gaugename == 'windDir':
# Need to do some special setup for wind gauges
min_value = 0
max_value = 360
dial_arc = 360
offset_angle = 180
else:
min_value = float(plot_options.get('minvalue')) # Field is mandatory
max_value = float(plot_options.get('maxvalue')) # Field is mandatory
min_value = float(plot_options.get('minvalue')) # Field is mandatory
max_value = float(plot_options.get('maxvalue')) # Field is mandatory
dial_arc = int(plot_options.get('dial_arc', 270))
offset_angle = int(plot_options.get('offset_angle', 0))

Expand All @@ -220,92 +224,83 @@ def gen_gauge(self, gaugename, plot_options, img_file):

# Do we have a reading for it?
try:
unit_type = self.units_dict['Groups'][self.record_dict_vtd[columnname][2]]
target_unit = self.units_dict['Groups'][weewx.units.obs_group_dict[columnname]]
except:
syslog.syslog(syslog.LOG_INFO, "GaugeGenerator: Could not find reading for gauge '%s'" % gaugename)
return

# Convert it to units in skin.conf file
value_tuple = weewx.units.convert(self.record_dict_vtd[columnname], unit_type)
value_now = weewx.units.convert(weewx.units.as_value_tuple(self.record_dict_vtd, columnname), target_unit)[0]

syslog.syslog(syslog.LOG_DEBUG, "GaugeGenerator: %s reading %s = %s" % (gaugename, columnname, value_now))

syslog.syslog(syslog.LOG_DEBUG, "GaugeGenerator: %s reading %s = %s" % (gaugename, columnname, value_tuple[0]))
dial_format = None

# Do we have a proper numeric reading?
try:
needle_value = float(value_tuple[0])
needle_value = float(value_now)
except:
# Log the error, do not draw the needle and display '-'
syslog.syslog(syslog.LOG_INFO, "GaugeGenerator: %s, could not plot reading value of = %s" %
(gaugename, value_tuple[0]))
(gaugename, value_now))
label_text = ''
digit_format = None
else:
gauge.add_needle(needle_value, needle_outline_color=needle_outline_color,
needle_fill_color=needle_fill_color)

label_format = self.units_dict['StringFormats'][value_tuple[1]]
digit_format = plot_options.get("digitformat", label_format)
label_format = self.units_dict['StringFormats'][target_unit]
dial_format = plot_options.get("digitformat", label_format)

label_text = unicode(label_format % value_tuple[0], "utf8")
label_text += unicode(self.units_dict['Labels'][value_tuple[1]], "utf8")
label_text = unicode(label_format % value_now, "utf8")
label_text += unicode(self.units_dict['Labels'][target_unit], "utf8")

gauge.add_text(label_text, text_font_size=label_font_size, text_font=font_path, text_color=text_color)

aggregate_interval = int(plot_options.get('aggregate_interval', 0))
aggregate_type = plot_options.get('aggregate_type', None)
if aggregate_type == 'None': aggregate_type = None

try:
history = int(plot_options.get('history'))
except:
history = None
pass
else:
(data_time, data_value) = self.archivedb.getSqlVectors(columnname, self.archivedb.lastGoodStamp() -
history * 60 * 60, self.archivedb.lastGoodStamp(), aggregate_interval, aggregate_type)

num_buckets = int(plot_options.get('bins', 10))
history_list = []
windspeed_history_list = []

windspeed_history_list = None
if gaugename == 'windRose':
(speed_time, speed_value) = self.archivedb.getSqlVectors('windSpeed', self.archivedb.lastGoodStamp() -
history * 60 * 60, self.archivedb.lastGoodStamp(), aggregate_interval, aggregate_type)
windspeed_history_list = []
batch_records = self.db_manager.genBatchRecords(self.lastGoodStamp - history * 60 * 60, self.lastGoodStamp)

for rec in batch_records:
db_value_tuple = weewx.units.as_value_tuple(rec, columnname)
history_value = weewx.units.convert(db_value_tuple, target_unit)[0]

for i in range(len(data_value[0])):
value_tuple = weewx.units.convert((data_value[0][i], data_value[1], data_value[2]), unit_type)
try:
hist_value = float(value_tuple[0])
history_list.append(float(history_value))
except:
syslog.syslog(syslog.LOG_DEBUG, "GaugeGenerator: Cannot decode reading of '%s' for gauge '%s'"
% (value_tuple[0], gaugename))
% (history_value, gaugename))
else:
history_list.append(hist_value)
if gaugename == 'windRose':
speed_tuple = weewx.units.convert((speed_value[0][i], speed_value[1], speed_value[2]), 'knot')
speed_value = self.converter.convertDict(rec)['windSpeed'] # Uses up a lot of time

try:
value_knot = float(speed_tuple[0])
value_knot = float(weewx.units.convert((speed_value, wind_units[0], None), 'knot')[0])
except:
value_knot = 0.0
pass
else:
windspeed_history_list.append(value_knot);
windspeed_history_list.append(value_knot)

num_buckets = int(plot_options.get('bins', 10))

if gaugename == 'windRose':
rings = []
for ring in plot_options.get('rings', [1,3,10]):
for ring in plot_options.get('rings', [1, 3, 10]):
rings.append(int(ring))

ring_colors = []
for ring_color in plot_options.get('ring_colors', [0x4242b4,0xb482420,0xff0000]):
for ring_color in plot_options.get('ring_colors', [0x4242b4, 0xb482420, 0xff0000]):
ring_colors.append(weeplot.utilities.tobgr(ring_color))

gauge.add_history(history_list, num_buckets, windspeed_history_list, rings, ring_colors)
else:
gauge.add_history(history_list, num_buckets, history_color)

gauge.add_dial(major_ticks=major_step, minor_ticks=minor_step, dial_format=digit_format, dial_font_size=digit_font_size,
dial_font=font_path, dial_color=dial_color, dial_label_color=label_color)

if compass_labels:
# Lookup the labels for the main compass points and add them to the gauge
try:
Expand All @@ -318,25 +313,24 @@ def gen_gauge(self, gaugename, plot_options, img_file):
compass_points = [0, 180, 90, 270]
dial_labels = dict(zip(compass_points, hemispheres))

gauge.add_dial_labels(dial_labels = dial_labels, dial_label_font_size=digit_font_size,
gauge.add_dial_labels(dial_labels=dial_labels, dial_label_font_size=digit_font_size,
dial_label_color=label_color, dial_label_font=font_path)

gauge.render()
image.save(img_file)
# Do not add degree numbers to the dial
dial_format = None

@staticmethod
def _get_record(archivedb, time_ts):
"""Return a value tuple dictionary which can be used to get current
readings in skin units."""
record_dict = archivedb.getRecord(time_ts)
gauge.add_dial(major_ticks=major_step, minor_ticks=minor_step, dial_format=dial_format,
dial_font_size=digit_font_size, dial_font=font_path, dial_color=dial_color,
dial_label_color=label_color)

return ValueTupleDict(record_dict)
gauge.render()
image.save(img_file)

@staticmethod
def _int2rgb(x):
#
# Stolen from genploy.py Weewx file
#
#
# Stolen from genploy.py Weewx file
#
if x is None:
return None
else:
Expand Down
Loading

0 comments on commit e4a6f45

Please sign in to comment.