Skip to content

Commit

Permalink
Merge pull request #7 from marcelb98/charts
Browse files Browse the repository at this point in the history
Charts
  • Loading branch information
marcelb98 authored Dec 18, 2017
2 parents b2705ed + 0075d4e commit d073f1e
Show file tree
Hide file tree
Showing 15 changed files with 271 additions and 23 deletions.
4 changes: 4 additions & 0 deletions LICENSE-3RD-PARTY.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ License: MIT
Copyright © Federico Zivolo and contributors
License: MIT

* CHARTIST.JS (http://gionkunz.github.io/chartist-js/)
Copyright (c) 2013 Gion Kunz <[email protected]>
License: MIT

piTemp also relies on 3rd-party-software which isn't distributed with the source code of piTemp:
- Python (https://www.python.org/)
- PostgreSQL (https://www.postgresql.org/)
Expand Down
15 changes: 7 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
# piTemp
piTemp gives you the availability to show and track temperatures measured by DS1820-sensors.
You can access the tracked temperatures over HTTP.

## Installation
1. Install postgresql (On RPi: `sudo apt install postgresql libpq-dev`)
2. Install python3/pip (On RPi: `sudo apt-get install python3-pip`)
3. Clone this repo and switch to the cloned directory
4. Run `sudo pip3 -r requirements.txt` to install all dependencies
5. Create a database + user with access-rights to this db
6. Run `./setup.py` to configure piTemp
7. Setup cronjob for `./cron.py` to automatically save temperatures to db.
Initially piTemp was developed for Raspberry Pi, but it should run on every Linux with Python3 and PostgreSQL.

![alt text](https://screenshots.firefoxusercontent.com/images/e2d5f2fe-8d64-4c08-988f-7fceab16adb8.png "Overview")

![alt text](https://screenshots.firefoxusercontent.com/images/f1977798-9466-4337-9858-50cc00f4b770.png "Detail")
39 changes: 36 additions & 3 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import os
import sys
import datetime
from temp import piTemp

#is configured?
Expand All @@ -39,8 +40,8 @@ def index():

# DATA-Structure:
# rows = []
# temp1 = ["Temp1",13.37]
# temp2 = ["Temp2",3.14]
# temp1 = ["sensorID","Temp1",13.37]
# temp2 = ["sensorID","Temp2",3.14]
# rows.append([temp1,temp2,None])

rows = []
Expand All @@ -50,7 +51,7 @@ def index():
t = temp.getTemp(sensor)
if t == -99 or t == -100:
t = "ERR"
col.append([name,t])
col.append([sensor,name,t])
#create new row, if 3rd col
if len(col) == 3:
rows.append(col)
Expand All @@ -65,6 +66,38 @@ def index():

return render_template('index.html',rows=rows)

@app.route('/detail/<string:sensor>', defaults={'begin': None, 'end': None})
@app.route('/detail/<string:sensor>/<string:begin>/<string:end>')
def detail(sensor, begin, end):
sensor_name = temp.getSensorName(sensor)
if begin == None:
begin = datetime.datetime.now().strftime('%Y-%m-%d')+' 00:00:00'
if end == None:
end = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
t = temp.getTemp(sensor)
if t == -99 or t == -100:
t = 'ERROR'

tempHist = temp.getTempHist(sensor, begin, end)
if tempHist == False:
return render_template('error.html',error="Couldn't read temperature history...")
else:
labels = tempHist[0]
values = tempHist[1]
return render_template('detail.html', sensor=sensor, sensor_name=sensor_name, temp=t, begin=begin, end=end, labels=labels, values=values)


@app.route('/chartDetail/<string:sensor>/<string:begin>/<string:end>')
def chartDetail(sensor, begin, end):
sensor_name = temp.getSensorName(sensor)
tempHist = temp.getTempHist(sensor, begin, end)
if tempHist == False:
return render_template('error.html',error="Couldn't read temperature history...")
else:
labels = tempHist[0]
values = tempHist[1]
return render_template('chartDetail.html', sensor=sensor, sensor_name=sensor_name, begin=begin, end=end, labels=labels, values=values)

@app.route('/sensors')
def sensors():
global temp
Expand Down
1 change: 1 addition & 0 deletions static/chartist.min.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions static/chartist.min.js

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions static/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,19 @@ along with piTemp. If not, see <http://www.gnu.org/licenses/>.*/

.box {
background-color: red;
color: #fff;
border-radius: 5px;
margin: 5px;
}
.box:hover {
text-decoration: none;
color: #fff;
}
.box.name {

}
.box.value {

}

.ct-label.ct-horizontal { position: relative; transform: rotate(45deg); transform-origin: left top; }
40 changes: 39 additions & 1 deletion temp.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,17 @@ def getHardwareSensors(self):
if ( sensor != 'w1_bus_master1'):
sensors.append(sensor)
return sensors

def getSensorName(self, sensor):
# returns name of configured sensor or false
try:
self.cursor.execute('SELECT name FROM sensors WHERE sensor = %s LIMIT 1', (sensor,))
return self.cursor.fetchall()[0][0]
except Exception as e:
return False

def getTemp(self,sensor):
# get temp (as float), saves temp in db
# get temp (as float)
# returns temp on success or -100 (IOError) or -99 (temp==None)

t = None
Expand All @@ -98,6 +106,29 @@ def getTemp(self,sensor):
return -99

return t

def getTempHist(self,sensor,begin,end):
# returns saved temps from db or false
# temps are returned as dictionary of 2 dictionaries:
# [ ["2017-01-01 13:38","2017-01-01 13:38"],[13, 37]]
# contains 2 temperatures.

if not self.validateDateTime(begin) or not self.validateDateTime(end):
print('Incorrect datetime input!')
return False
times = []
values = []
try:
self.cursor.execute('SELECT time, value FROM temps WHERE sensor = %s AND time >= %s AND time <= %s', (sensor,begin,end,))
result = self.cursor.fetchall()
if result != None:
for row in result:
times.append(row[0])
values.append(row[1])
return [times, values]
except ValueError as e:
print('tempHist Error: s='+sensor+' b='+begin+' e='+end)
return False

def saveTemp(self,sensor,t):
# save temp to database
Expand Down Expand Up @@ -135,3 +166,10 @@ def deleteSensor(self, sensor):
except Exception as e:
return False

def validateDateTime(self,date):
# returns True if date is in correct format: y-m-d h-m-s
try:
datetime.datetime.strptime(date,'%Y-%m-%d %H:%M:%S')
return True
except ValueError:
return False
49 changes: 49 additions & 0 deletions templates/chartDetail.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{# Copyright 2017 Marcel Beyer

This file is part of piTemp.

piTemp is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

piTemp is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with piTemp. If not, see <http://www.gnu.org/licenses/>. #}

{% extends "chart_template.html" %}
{% block body %}

<div class="container">
<a href="/detail/{{ sensor }}/{{ begin }}/{{ end }}">back</a>
<b>{{ sensor_name }}</b> {{ begin }} - {{ end }}<br>
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="ct-chart ct-minor-seventh" style="width:100%;height:100%"></div>
</div>
</div>
</div>
</div>

<script type="text/javascript" >
var data = {
labels: [{% for label in labels %}'{{label}}',{% endfor %}],
series: [
[{% for value in values %}{{value}},{% endfor %}]
]
};
var options = {
axisX: {
offset: 50
},
}

new Chartist.Line('.ct-chart', data, options);
</script>

{% endblock %}
Loading

0 comments on commit d073f1e

Please sign in to comment.