Skip to content

Commit

Permalink
Merge pull request #123 from brewster76/4.1
Browse files Browse the repository at this point in the history
reintegrated 4.1
  • Loading branch information
mKainzbauer authored Sep 14, 2023
2 parents 34a7a58 + 34e5752 commit 8207c5b
Show file tree
Hide file tree
Showing 46 changed files with 1,053 additions and 739 deletions.
2 changes: 1 addition & 1 deletion INSTALL
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Installation
============

Before we begin...
1) This release (v4.0) has been tested on Weewx version 4.10.2 and Python 3.9.2
1) This release (v4.1) has been tested on Weewx version 4.10.2 and Python 3.9.2
Versions of Weewx before v3 will not work.
2) This has been tested on sqlite databases. Mysql and any other Weewx supported databases should work too.

Expand Down
32 changes: 26 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
Theme for Weewx weather station software.
============
Gauge graphics showing current conditions.
Gauge and Chart graphics showing current conditions.

English example | German example with combined line/bar chart and scatter chart
:-------------------------:|:-------------------------:
![image](https://github.com/brewster76/fuzzy-archer/assets/58649043/d3d948ff-763e-42cd-a653-e40f3e6fdacb) | ![image](https://github.com/brewster76/fuzzy-archer/assets/58649043/aefe0b81-742a-453a-9e1f-3859330cc414)

See it in action with live data (10s. refresh interval):

[Weather test page english](https://www.kainzbauer.net/weather/Rif/en)

[Wetter Testseite Deutsch](https://www.kainzbauer.net/weather/Rif/de)

Interactive charts showing conditions over a timespan


MQTT enabled Gauges and charts - live weather data!
(Live data needs extra extensions and configurations for publishing and subscribing MQTT messages and topics) see: https://github.com/brewster76/fuzzy-archer/wiki/MQTT-setup

Statistics: daily/weewly/monthly/yearly/alltime, highs/lows, ...
Statistics: daily/weekly/monthly/yearly/alltime, highs/lows, ...

Historic data in color coded html tables.

Expand All @@ -24,7 +35,19 @@ Available in multiple languages. Help wanted! We need help with translations for
- dutch
- thai

Read the upgrading guide, if you already have an older version installed: https://github.com/brewster76/fuzzy-archer/wiki/Upgrading-to-v4
Read the upgrading guides in the wiki, if you already have an older version installed: https://github.com/brewster76/fuzzy-archer/wiki

New in v4.1:

- Mixed charts: you can now mix "line" series with "bar" series. A mixed radiation/UV chart is already in the configs, you can enable it by adding it to live_chart_items
- New chart type "scatter". A scatter chart for lightning strikes and distance is already in the configs, you can enable it by adding it to live_chart_items
- Configurable custom pages
- Configurable news items
- More config options for charts
- Gauges, charts, stats and history items are now shown and ordered explicitly using a configuration list.
- Mulit-language linking support: you can switch languages vie dropdown in multi-language installations
- localization throughout charts and gauges (the stats and history page still depends on the systems locale, see https://github.com/weewx/weewx/issues/867)
- Bugfixes and enhancements

New in v4.0:

Expand All @@ -36,9 +59,6 @@ New in v4.0:
- Day/night background in Live Charts (needs pyephem installed)
- Bug fixes and other enhancements

See it in action with live data (~30s. refresh interval):

[Das Wetter in Rif](https://www.kainzbauer.net/weather/Rif/)
![Example_Rif](https://kainzbauer.net/example_rif.png)

See it in action (legacy v2.x): [dajda.net](http://dajda.net/)
Expand Down
25 changes: 10 additions & 15 deletions bin/user/historygenerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,25 +58,20 @@ def __init__(self, generator):
self.search_list_extension = {}

# Make some config available to templates
self.add_to_extension_list('Navigation', generator.skin_dict)
self.add_to_extension_list('StationInfo', generator.skin_dict)
self.add_to_extension_list('TranslationLinks', generator.skin_dict)
self.add_to_extension_list('HistoryReport', generator.skin_dict)
self.add_to_extension_list('ImageGenerator', generator.skin_dict)
self.add_to_extension_list('BootstrapLabels', generator.skin_dict)
self.add_to_extension_list('Labels', generator.skin_dict)
self.add_to_extension_list('Units', generator.skin_dict)
self.add_to_extension_list('LiveGauges', generator.skin_dict)
self.add_to_extension_list('Stats', generator.skin_dict)
self.add_to_extension_list('News', generator.skin_dict)
self.add_to_extension_list('LiveCharts', generator.skin_dict)
self.add_to_extension_list('locale', generator.skin_dict)

# Make ImageGenerator specific labels in config file available to templates
image_dict = {}
image_config_path = os.path.join(generator.config_dict['WEEWX_ROOT'], generator.config_dict['StdReport']['SKIN_ROOT'],
'Bootstrap', "skin.conf")
try:
image_dict = ConfigObj(image_config_path)
except:
log.info("%s: Could not import image dictionary %s" %
os.path.basename(__file__), image_config_path)
self.add_to_extension_list('ImageGenerator', image_dict)

def add_to_extension_list(self, key, source):
if key in source:
self.search_list_extension[key] = source[key]
Expand Down Expand Up @@ -105,7 +100,7 @@ def get_extension_list(self, valid_timespan, db_lookup):

t1 = time.time()
ngen = 0
self.search_list_extension["history_tables"] = []
self.search_list_extension["history_tables"] = {}

for table in self.table_dict.sections:
noaa = True if table == 'NOAA' else False
Expand Down Expand Up @@ -147,7 +142,7 @@ def get_extension_list(self, valid_timespan, db_lookup):

new_table = self._statsDict(table_options, table_stats, table, binding, NOAA=noaa)
if new_table is not None:
self.search_list_extension["history_tables"].append(new_table)
self.search_list_extension["history_tables"][table] = new_table
ngen += 1

t2 = time.time()
Expand Down Expand Up @@ -348,9 +343,9 @@ def _statsDict(self, table_options, table_stats, table, binding, NOAA=False):

def getCount(self, obs_period, aggregate_type, threshold_value, threshold_units, obs_type):
try:
return getattr(obs_period, aggregate_type)((threshold_value, threshold_units, weewx.units.obs_group_dict[obs_type])).value_t
return getattr(obs_period, aggregate_type)((threshold_value, threshold_units, weewx.units.obs_group_dict[obs_type])).value_t
except:
return [0, 'count']
return [0, 'count']

def _colorCell(self, value, format_string, cell_colors):
"""Returns a '<div style= background-color: XX; color: YY"> z.zz </div>' html table entry string.
Expand Down
29 changes: 23 additions & 6 deletions bin/user/jsonengine.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
from weewx.units import convert

from user.sunevents import SunEvents
from weeutil.config import merge_config

log = logging.getLogger(__name__)

Expand All @@ -56,7 +57,9 @@ def setup(self):
self.gauge_dict = self.skin_dict['LiveGauges']
self.chart_dict = self.skin_dict['LiveCharts']
self.units_dict = self.skin_dict['Units']
merge_config(self.units_dict, self.config_dict['StdReport']['Defaults']['Units'])
self.labels_dict = self.skin_dict['Labels']
merge_config(self.labels_dict, self.config_dict['StdReport']['Defaults']['Labels'])
self.frontend_data = {}

# Create a converter to get this into the desired units
Expand Down Expand Up @@ -114,7 +117,7 @@ def gen_data(self):

for gauge in self.gauge_dict.sections:
data_type = self.gauge_dict[gauge].get('data_type', gauge)
ret, gauge_history = self.gen_history_data(gauge, data_type, live_options, self.gauge_dict[gauge].get('data_binding', None))
ret, gauge_history = self.gen_history_data(gauge, data_type, live_options, self.gauge_dict[gauge].get('data_binding', None), None)
self.frontend_data['gauges'][gauge]['target_unit'] = self.get_target_unit(gauge)
self.frontend_data['gauges'][gauge]['obs_group'] = self.get_obs_group(gauge)

Expand All @@ -125,7 +128,8 @@ def gen_data(self):
for chart in self.chart_dict.sections:
for category in self.chart_dict[chart].sections:
data_type = self.chart_dict[chart][category].get('data_type', category)
ret, category_history = self.gen_history_data(category, data_type, live_options, self.chart_dict[chart][category].get('data_binding'))
plotType = self.chart_dict[chart][category].get('plotType', 'line')
ret, category_history = self.gen_history_data(category, data_type, live_options, self.chart_dict[chart][category].get('data_binding'), plotType)
self.frontend_data['charts'][chart][category]['target_unit'] = self.get_target_unit(category)
self.frontend_data['charts'][chart][category]['obs_group'] = self.get_obs_group(category)

Expand Down Expand Up @@ -174,7 +178,7 @@ def get_obs_group(self, column_name):
log.info("JSONGenerator: weewx.units.obs_group_dict['%s'] is not present, using the empty string." % column_name)
return ""

def gen_history_data(self, obs_name, column_name, live_options, binding_name):
def gen_history_data(self, obs_name, column_name, live_options, binding_name, plotType):
log.debug("Generating history for obs_name %s and column_name %s with binding %s" % (obs_name, column_name, binding_name))
if obs_name in self.frontend_data:
log.debug("Data for observation %s has already been collected." % obs_name)
Expand Down Expand Up @@ -206,18 +210,31 @@ def gen_history_data(self, obs_name, column_name, live_options, binding_name):
logging.exception("Could not get db_manager for default binding")

batch_records = db_manager.genBatchRecords(self.lastGoodStamp - timespan * 60 * 60, self.lastGoodStamp)

for rec in batch_records:
db_value_tuple = weewx.units.as_value_tuple(rec, column_name)
try:
db_value_tuple = weewx.units.as_value_tuple(rec, column_name)
except:
log.debug("JSONGenerator: Ignoring data for column '%s', is this column in the database table?" % (column_name))
return 0, None

if target_unit == "":
history_value = rec[column_name]
else:
history_value = weewx.units.convert(db_value_tuple, target_unit)[0]
try:
history_list.append(float(history_value))
if history_value is None:
history_list.append(history_value)
else:
history_list.append(float(history_value))
time_list.append(rec['dateTime'] * 1000)
except:
log.debug("JSONGenerator: Cannot decode reading of '%s' for column '%s'" % (history_value, column_name))





log.debug("returning history list")
return 1, list(zip(time_list, history_list))

Expand Down Expand Up @@ -256,4 +273,4 @@ def get_day_night_events(self, start, end, lon, lat, altitude_m):
if angle <= -self.transition_angle:
darkening_extent = 1
event[1] = darkening_extent
return events
return events
10 changes: 7 additions & 3 deletions install.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,23 @@ class BootstrapInstaller(setup.ExtensionInstaller):
def __init__(self):
files=[('skins/Bootstrap',
['skins/Bootstrap/about.html.tmpl',
'skins/Bootstrap/chartimages.html.inc',
'skins/Bootstrap/day.html.tmpl',
'skins/Bootstrap/foot.html.inc',
'skins/Bootstrap/graphMenu.html.inc',
'skins/Bootstrap/head.html.inc',
'skins/Bootstrap/history.html.tmpl',
'skins/Bootstrap/index.html.tmpl',
'skins/Bootstrap/livegauges.html.inc',
'skins/Bootstrap/location.html.inc',
'skins/Bootstrap/month.html.tmpl',
'skins/Bootstrap/moonphase.html.inc',
'skins/Bootstrap/nav.html.inc',
'skins/Bootstrap/news.html.tmpl',
'skins/Bootstrap/script.html.inc',
'skins/Bootstrap/chartimages.html.inc',
'skins/Bootstrap/stats.html.tmpl',
'skins/Bootstrap/sunRiseSet.html.inc',
'skins/Bootstrap/uptime.html.inc',
'skins/Bootstrap/week.html.tmpl',
'skins/Bootstrap/year.html.tmpl',
'skins/Bootstrap/skin.conf']),
Expand Down Expand Up @@ -76,9 +80,9 @@ def __init__(self):
'skins/Bootstrap/lang/th.conf'])]

super(BootstrapInstaller, self).__init__(
version="4.0",
version="4.1",
name='bootstrap',
description='A skin based around the bootstrap 5.2.0 framework',
description='A skin based around the bootstrap framework',
author="Nick Dajda, Michael Kainzbauer and other contributors",
author_email="[email protected]",
config={
Expand Down
64 changes: 59 additions & 5 deletions skins/Bootstrap/about.html.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,66 @@
and use the WeeWX installer to unpack it:</p>
<pre>wee_extension --install [wherever you've put the archive]</pre>

<p>Set the page title and footer through the corresponding file for your language in
<code>skins/Bootstrap/lang/{your_language}.conf</code>. Change the template language using
lang = {your_language} in the section for your skin in <code>weewx.conf</code>
For more information concerning localisation see the official
<a href="http://www.weewx.com/docs/customizing.htm#localization">WeeWX docs</a>.
<p>The preferred way to custumize your page is to apply any changes and additions in your weewx.conf, using the skin's section within <code>[StdConfig]</code>.
Change the language using <code>lang = {your_language}</code> in the section for your skin in <code>weewx.conf</code>.
For more information concerning localization see the official <a href="http://www.weewx.com/docs/customizing.htm#localization">WeeWX docs</a>.
</p>
<h3>Example:</h3>
<p>The following example is an excerpt of weewx.conf. It will result in a english translated page, using the en_US locale, kilometers per hour instead of miles per hour for group_speed and setting the Footer text to "My custom footer text". Also, two news items will be shown on the "News" page. Also, a custom chart "inTemp", appearing as first chart, and the preconfigured "radiation" chart, as the last chart, is configured.</p>
<pre>
[StdReport]
[[Bootstrap]]
skin = Bootstrap
HTML_ROOT = /var/www/html/weewx/Bootstrap/en
lang = en
enable = true
locale = en_US

[[[Units]]]
[[[[Groups]]]]
group_speed = km_per_hour

[[[Texts]]]
Footer Text = "My custom footer text."

[[[News]]]
[[[[February 3, 2023]]]]
header = "Big News!"
body = "We have big news!"
img_src = "path/to/big_news.jpg"
img_alt = "Big News!"
img_title = "We have big news!"
[[[[December 7, 2022]]]]
header = "News"
body = "We have news, but no pictures."

[[[LiveCharts]]]
live_chart_items = inTemp, outTemp, barometer, rain, outHumidity, wind, windDir, radiation # radiation is already preconfigured in skin.conf
[[[[inTemp]]]]
[[[[[inTemp]]]]]
payload_key = inTemp_F
showMaxMarkPoint = true
showMinMarkPoint = true
showAvgMarkLine = true
lineColor = '#b44242'
decimals = 1
</pre>

<h3>Custom pages:</h3>
<p>Let's say, you want to exchange this about page with your own. Create a template files <code>extra.html.tmpl</code>
and tell CheetahGenerator to handle it. Then exchange <code>about</code> with <code>extra</code> in the <code>navigation_items</code>.
Then configure your new page in the <code>[[[[extra]]]]</code> stanza as below.</p>
<pre>
[[[CheetahGenerator]]]
[[[[HTMLFiles]]]]
[[[[[extra]]]]]
template = extra.html.tmpl
[[[Navigation]]]
navigation_items = index, stats, history, news, extra
[[[[extra]]]]
text = About
href = extra.html
</pre>
</div>
</div>
#include "foot.html.inc"
Expand Down
5 changes: 3 additions & 2 deletions skins/Bootstrap/chartimages.html.inc
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
<p></p>
#include "graphMenu.html.inc"
<div class="row" id="modalRow">
#for $imageName, $value in $ImageGenerator[$global_type + '_images'].items()
#if isinstance($value, dict)
#for $imageName in $image_items
#set $imageItem = $ImageGenerator[$global_type + '_images'][$imageName]
#if isinstance($imageItem, dict)
<div class="chart">
<div class="modal fade" id="large-${imageName}Modal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog" style="max-width: 900px">
Expand Down
7 changes: 3 additions & 4 deletions skins/Bootstrap/css/bootstrap.min.css

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions skins/Bootstrap/css/live.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ body {
height:160px;
}
.gaugecol {
min-width: 160px;
min-height:160px;
min-width: 175px;
min-height:175px;
}
.chart {
width: 400px;
Expand Down
1 change: 1 addition & 0 deletions skins/Bootstrap/day.html.tmpl
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#errorCatcher Echo
#set global $global_type = 'day'
#set global $image_items = $to_list($ImageGenerator[$global_type + '_images'].get('image_items', ['daytempchill-Bootstrap', 'daybarometer-Bootstrap', 'dayrain-Bootstrap', 'dayhumidity-Bootstrap', 'daywind-Bootstrap', 'daywinddir-Bootstrap']))
#include "chartimages.html.inc"
Loading

0 comments on commit 8207c5b

Please sign in to comment.