Skip to content

Commit bfa30be

Browse files
committed
Add summary table below graph
1 parent 5191665 commit bfa30be

File tree

6 files changed

+277
-115
lines changed

6 files changed

+277
-115
lines changed

lib/Wihlo.pm

+17-95
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use DateTime;
2323
use DateTime::Format::Strptime;
2424
use DateTime::Format::DBI;
2525
use JSON;
26+
use Wihlo::Data;
2627

2728
our $VERSION = '0.1';
2829

@@ -37,110 +38,31 @@ any '/' => sub {
3738
};
3839
}
3940

41+
my $range = session('range') || {};
42+
43+
my $data = Wihlo::Data->new(
44+
schema => schema,
45+
from => $range->{from},
46+
to => $range->{to},
47+
group_by => 'day',
48+
);
49+
4050
template 'index' => {
41-
range => session('range'),
51+
readings => $data->readings,
52+
range => $range,
4253
};
4354
};
4455

4556
get '/data' => sub {
4657

4758
my $range = session('range') || {};
48-
my $to = $range->{to} || DateTime->now;
49-
my $from = $range->{from} || $to->clone->subtract(days => 5);
50-
51-
my $reading_rs = rset('Reading');
52-
schema->storage->debug(1);
53-
54-
# Format DateTime objects for the database query
55-
my $db_parser = DateTime::Format::DBI->new(schema->storage->dbh);
56-
my $from_db = $db_parser->format_date($from);
57-
my $to_db = $db_parser->format_date($to->add( days => 1));
58-
59-
# Calculate how many readings to extract from DB and group accordingly
60-
my $group = "";
61-
my $diff = $from->subtract_datetime( $to );
62-
if ($diff->months || $diff->years)
63-
{
64-
$group = "DATE_FORMAT(datetime, '%Y%j')";
65-
}
66-
elsif ($diff->weeks)
67-
{
68-
$group = "DATE_FORMAT(datetime, '%Y%j%H')";
69-
}
70-
else
71-
{
72-
$group = "DATE_FORMAT(datetime, '%Y%j%H%i')";
73-
}
7459

75-
my $readdisp = $reading_rs->search(
76-
{
77-
datetime => {
78-
-between => [
79-
$from_db, $to_db
80-
]
81-
}
82-
},{
83-
'+select' => [
84-
{
85-
max => 'outtemp',
86-
-as => 'maxtemp'
87-
},{
88-
min => 'outtemp',
89-
-as => 'mintemp',
90-
},{
91-
max => 'windgust',
92-
-as => 'windgust',
93-
},{
94-
sum => 'rain',
95-
-as => 'rain',
96-
},{
97-
avg => 'barometer',
98-
-as => 'baramoter',
99-
}
100-
],
101-
group_by => [
102-
\$group,
103-
]
104-
}
60+
my $data = Wihlo::Data->new(
61+
schema => schema,
62+
from => $range->{from},
63+
to => $range->{to},
10564
);
10665

107-
my $count = $readdisp->count;
108-
my $raintot = 0; my $lasthms = 0;
109-
my @data;
110-
while (my $r = $readdisp->next)
111-
{
112-
push @data, {
113-
x => $r->datetime->datetime,
114-
y => celsius($r->get_column('maxtemp')),
115-
group => 2,
116-
};
117-
push @data, {
118-
x => $r->datetime->datetime,
119-
y => celsius($r->get_column('mintemp')),
120-
group => 1,
121-
};
122-
push @data, {
123-
x => $r->datetime->datetime,
124-
y => $r->windgust || 0,
125-
group => 3,
126-
};
127-
push @data, {
128-
x => $r->datetime->datetime,
129-
y => $r->barometer || 0,
130-
group => 4,
131-
};
132-
$raintot = 0
133-
if ($r->datetime->hms('') <= $lasthms);
134-
my $rain = $r->rain ? $r->rain : 0;
135-
$raintot += $rain;
136-
push @data, {
137-
x => $r->datetime->datetime,
138-
y => $raintot,
139-
group => 0,
140-
};
141-
$lasthms = $r->datetime->hms('');
142-
}
143-
14466
my $groups = [
14567
{
14668
id => 0,
@@ -185,7 +107,7 @@ get '/data' => sub {
185107
header "Cache-Control" => "max-age=0, must-revalidate, private";
186108
content_type 'application/json';
187109
encode_json({
188-
data => \@data,
110+
data => $data->readings_graph,
189111
groups => $groups,
190112
});
191113
};

lib/Wihlo/Data.pm

+203
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
=pod
2+
Wihlo - Web-based weather logging and display software
3+
Copyright (C) 2014 A Beverley [email protected]
4+
5+
This program is free software: you can redistribute it and/or modify
6+
it under the terms of the GNU Affero General Public License as
7+
published by the Free Software Foundation, either version 3 of the
8+
License, or (at your option) any later version.
9+
10+
This program is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
GNU Affero General Public License for more details.
14+
15+
You should have received a copy of the GNU Affero General Public License
16+
along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
=cut
18+
19+
package Wihlo::Data;
20+
21+
use DateTime;
22+
use DateTime::Format::Strptime;
23+
24+
use Moo;
25+
use MooX::Types::MooseLike::Base qw(:all);
26+
use MooX::Types::MooseLike::DateTime qw/DateAndTime/;
27+
28+
has schema => (
29+
is => 'ro',
30+
required => 1,
31+
);
32+
33+
has from => (
34+
is => 'rw',
35+
isa => DateAndTime,
36+
lazy => 1,
37+
builder => sub {
38+
my $self = shift;
39+
$self->to->clone->subtract(days => 5);
40+
},
41+
);
42+
43+
has to => (
44+
is => 'rw',
45+
isa => DateAndTime,
46+
lazy => 1,
47+
builder => sub { DateTime->now },
48+
);
49+
50+
has readings => (
51+
is => 'lazy',
52+
isa => ArrayRef,
53+
);
54+
55+
has readings_graph => (
56+
is => 'lazy',
57+
isa => ArrayRef,
58+
);
59+
60+
# day, hour, minute. Defaults to sensible value
61+
# depending on range
62+
has group_by => (
63+
is => 'lazy',
64+
isa => Str,
65+
);
66+
67+
# The actual SQL grouping, based on group_by
68+
has _sql_group_by => (
69+
is => 'lazy',
70+
isa => ArrayRef,
71+
);
72+
73+
sub _build_readings
74+
{ my $self = shift;
75+
76+
my $parser = $self->schema->storage->datetime_parser;
77+
my $readdisp = $self->schema->resultset('Reading')->search(
78+
{
79+
datetime => {
80+
-between => [
81+
$parser->format_datetime($self->from),
82+
$parser->format_datetime($self->to),
83+
]
84+
}
85+
},{
86+
'+select' => [
87+
{
88+
max => 'outtemp',
89+
-as => 'maxtemp'
90+
},{
91+
min => 'outtemp',
92+
-as => 'mintemp',
93+
},{
94+
max => 'windgust',
95+
-as => 'windgust',
96+
},{
97+
sum => 'rain',
98+
-as => 'rain',
99+
},{
100+
avg => 'barometer',
101+
-as => 'baramoter',
102+
}
103+
],
104+
group_by => [
105+
$self->_sql_group_by,
106+
]
107+
}
108+
);
109+
110+
my $raintot = 0; my $lasthms = 0;
111+
my @readings;
112+
while (my $r = $readdisp->next)
113+
{
114+
$raintot = 0
115+
if ($r->datetime->hms('') <= $lasthms);
116+
my $rain = $r->rain ? $r->rain : 0;
117+
$raintot += $rain;
118+
119+
push @readings, {
120+
datetime => $r->datetime,
121+
maxtemp => celsius($r->get_column('maxtemp')),
122+
mintemp => celsius($r->get_column('mintemp')),
123+
windgust => $r->windgust || 0,
124+
barometer => $r->barometer || 0,
125+
raintot => $raintot,
126+
};
127+
$lasthms = $r->datetime->hms('');
128+
}
129+
130+
\@readings;
131+
};
132+
133+
sub _build_readings_graph
134+
{ my $self = shift;
135+
my @readings;
136+
137+
foreach my $reading (@{$self->readings})
138+
{
139+
my $datetime = $reading->{datetime}->datetime;
140+
push @readings, {
141+
x => $datetime,
142+
y => $reading->{maxtemp},
143+
group => 2,
144+
};
145+
push @readings, {
146+
x => $datetime,
147+
y => $reading->{mintemp},
148+
group => 1,
149+
};
150+
push @readings, {
151+
x => $datetime,
152+
y => $reading->{windgust},
153+
group => 3,
154+
};
155+
push @readings, {
156+
x => $datetime,
157+
y => $reading->{barometer},
158+
group => 4,
159+
};
160+
push @readings, {
161+
x => $datetime,
162+
y => $reading->{raintot},
163+
group => 0,
164+
};
165+
}
166+
\@readings;
167+
}
168+
169+
sub _build_group_by
170+
{ my $self = shift;
171+
my $diff = $self->from->subtract_datetime( $self->to );
172+
my $group = !$diff->months && !$diff->years && !$diff->weeks
173+
? 'minute'
174+
: !$diff->months && !$diff->years
175+
? 'hour'
176+
: 'day';
177+
$group;
178+
}
179+
180+
sub _build__sql_group_by
181+
{ my $self = shift;
182+
183+
my @group = (
184+
$self->schema->resultset('Reading')->dt_SQL_pluck({ -ident => '.datetime' }, 'year'),
185+
$self->schema->resultset('Reading')->dt_SQL_pluck({ -ident => '.datetime' }, 'month'),
186+
$self->schema->resultset('Reading')->dt_SQL_pluck({ -ident => '.datetime' }, 'day_of_month'),
187+
);
188+
189+
push @group, $self->schema->resultset('Reading')->dt_SQL_pluck({ -ident => '.datetime' }, 'hour')
190+
if $self->group_by eq 'hour' || $self->group_by eq 'minute';
191+
push @group, $self->schema->resultset('Reading')->dt_SQL_pluck({ -ident => '.datetime' }, 'minute')
192+
if $self->group_by eq 'minute';
193+
\@group;
194+
}
195+
196+
sub celsius($)
197+
{
198+
my $f = shift;
199+
my $c = ($f - 32) * (5/9);
200+
sprintf("%.2f", $c);
201+
}
202+
203+
1;

lib/Wihlo/Schema.pm

+4-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ use warnings;
99

1010
use base 'DBIx::Class::Schema';
1111

12-
__PACKAGE__->load_namespaces;
13-
12+
# XXX Broken the rule. Will need to fix this later.
13+
Wihlo::Schema->load_namespaces(
14+
default_resultset_class => 'ResultSet',
15+
);
1416

1517
# Created by DBIx::Class::Schema::Loader v0.07025 @ 2013-12-29 21:57:15
1618
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:4l67aG992bcXZcWCzwzoUA

lib/Wihlo/Schema/ResultSet.pm

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package Wihlo::Schema::ResultSet;
2+
3+
use strict;
4+
use warnings;
5+
6+
use parent 'DBIx::Class::ResultSet';
7+
8+
__PACKAGE__->load_components('Helper::ResultSet::DateMethods1');
9+
10+
1;

public/css/local.css

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1 @@
1-
div, span, p, td {
2-
font-family: Arial, sans-serif;
3-
}
1+
.top-buffer { margin-top:20px; }

0 commit comments

Comments
 (0)