Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
motoz committed Nov 26, 2015
2 parents 0ca3245 + a01d000 commit 68ce8ea
Show file tree
Hide file tree
Showing 27 changed files with 11,183 additions and 9 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ initscript/pellmonweb
pellmon_conf/
version.py
pellmoncli
pellmonconf
23 changes: 18 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ PellMon

PellMon is logging, monitoring and configuration solution for pellet burners. It consists of a backend server daemon, which
uses RRDtool as a logging database, and a frontend daemon providing a responsive mobile friendly web based user interface.
Additionally there is a command line tool for interfacing with the server. PellMon can communicate directly with a supported
pellet burner, or it can use a feeder-auger revolution counter as base for pellet consumption calculation.
Additionally there is a command line tool for interfacing with the server, and web based configuration tool.
PellMon can communicate directly with a supported pellet burner, or it can use a feeder-auger revolution counter as
base for pellet consumption calculation.

PellMon uses plugins to provide data about your burner. The most fully featured plugin is ScotteCom, which enables communication
with a NBE scotte/woody/biocomfort V4, V5 or V6 pellet burner. It gives you access to almost all configuration parameters
Expand Down Expand Up @@ -33,7 +34,7 @@ Plugin documentation is found in the configuration file pellmon.conf.

####Contains:

###pellmonsrv.py:
###pellmonsrv:
Communication daemon. Implements a DBUS interface for reading and writing setting values and reading of measurement data. Optionally handles logging of measurement data to an RRD database.
<pre>
usage: pellmonsrv.py [-h] [-P PIDFILE] [-U USER] [-G GROUP] [-C CONFIG] [-D {SESSION,SYSTEM}] [-p PLUGINDIR]
Expand All @@ -58,7 +59,7 @@ optional arguments:
Full path to plugin directory
</pre>

###pellmonweb.py:
###pellmonweb:
Webserver and webapp, plotting of measurement, calculated consumption and data and parameter reading/writing.
<pre>
usage: pellmonweb.py [-h] [-D] [-P PIDFILE] [-U USER] [-G GROUP] [-C CONFIG] [-d {SESSION,SYSTEM}]
Expand All @@ -76,11 +77,23 @@ optional arguments:
-d {SESSION,SYSTEM}, --DBUS {SESSION,SYSTEM}
which bus to use, SESSION is default
</pre>
###pellmoncli.py:
###pellmoncli:

Interactive command line client with tab completion. Reading and writing of setting values, and reading of measurement data.
usage: pellmoncli.py [-h] {get,set,list,i}

###pellmonconf:
Web based text editor for the configuration files
<pre>
pellmonconf -h
usage: pellmonconf [-h] [-P PORT] [-H HOST]

optional arguments:
-h, --help show this help message and exit
-P PORT, --port PORT Port number for webinterface, default 8083
-H HOST, --host HOST Host for webinterface, default 0.0.0.0
</pre>

###pellmon.conf
The default configuration is split up in several files in the conf.d directory using the directive `config_dir = /etc/pellmon/conf.d` in pellmon.conf.

Expand Down
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ src/Pellmonsrv/plugins/owfs/Makefile \
src/Pellmonsrv/plugins/silolevel/Makefile \
src/Pellmonsrv/plugins/pelletcalc/Makefile \
src/Pellmonsrv/plugins/consumption/Makefile \
src/Pellmonsrv/plugins/cleaning/Makefile \
src/Scotteprotocol/Makefile \
src/Pellmonweb/Makefile ])

Expand Down
6 changes: 5 additions & 1 deletion src/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
SUBDIRS = Pellmonsrv Pellmonweb Scotteprotocol conf.d

bin_SCRIPTS = pellmonsrv pellmonweb pellmoncli
bin_SCRIPTS = pellmonsrv pellmonweb pellmoncli pellmonconf
CLEANFILES = \
pellmon.conf

Expand All @@ -24,6 +24,10 @@ pellmoncli: pellmoncli.in Makefile
$(do_substitution) < $(srcdir)/$< > $(srcdir)/$@
chmod +x $@

pellmonconf: pellmonconf.in Makefile
$(do_substitution) < $(srcdir)/$< > $(srcdir)/$@
chmod +x $@

install-data-local:
$(MKDIR_P) $(DESTDIR)$(localstatedir)/log/pellmonsrv
chown $(user_srv) $(DESTDIR)$(localstatedir)/log/pellmonsrv
Expand Down
3 changes: 2 additions & 1 deletion src/Pellmonsrv/plugins/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
SUBDIRS = scottecom raspberrygpio testplugin customalarms calculate owfs silolevel pelletcalc consumption
SUBDIRS = scottecom raspberrygpio testplugin customalarms calculate owfs silolevel pelletcalc consumption cleaning

nobase_dist_plugins_DATA = \
scottecom.pellmon-plugin \
Expand All @@ -9,6 +9,7 @@ nobase_dist_plugins_DATA = \
owfs.pellmon-plugin \
silolevel.pellmon-plugin \
pelletcalc.pellmon-plugin \
cleaning.pellmon-plugin \
consumption.pellmon-plugin

pluginsdir = $(libdir)/Pellmonsrv/plugins
9 changes: 9 additions & 0 deletions src/Pellmonsrv/plugins/cleaning.pellmon-plugin
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[Core]
Name = Cleaning
Module = cleaning

[Documentation]
Author = Anders Nylund
Version = 0.1
Website = http://github.com/motoz/PellMon
Description = Keep track of when it's time to clean the boiler
4 changes: 4 additions & 0 deletions src/Pellmonsrv/plugins/cleaning/Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
cleaningplugin_PYTHON = \
__init__.py

cleaningplugindir = $(libdir)/Pellmonsrv/plugins/cleaning
176 changes: 176 additions & 0 deletions src/Pellmonsrv/plugins/cleaning/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
#! /usr/bin/python
# -*- coding: utf-8 -*-
"""
Copyright (C) 2013 Anders Nylund
This program 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.
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
"""

from Pellmonsrv.plugin_categories import protocols
from threading import Thread, Timer
from ConfigParser import ConfigParser
from os import path
import os, grp, pwd
import time
from datetime import datetime, timedelta
from logging import getLogger
from time import mktime
import subprocess
import simplejson as json
import re
import math
import random

logger = getLogger('pellMon')

itemList=[#{'name':'clean_after', 'longname':'Clean after',
# 'type':'R/W', 'unit':'kg' , 'value':'1000', 'min':'0', 'max':'10000'},
{'name':'clean_time', 'longname':'Last cleaning time',
'type':'R/W', 'unit':'' , 'value':'01/01/14 12:00', 'min':'0', 'max':'-'},
{'name':'clean_kg', 'longname':'Cleaning counter',
'type':'R', 'unit':'kg' , 'value':'0', 'min':'0', 'max':'-'},
#{'name':'clean_days', 'longname':'Cleaning days left',
# 'type':'R', 'unit':'days' , 'value':'0', 'min':'0', 'max':'-'},
{'name':'clean', 'longname':'Clean now',
'type':'W', 'unit':'' , 'value':'0', 'min':'0', 'max':'0'},
]

itemTags = {'clean_after' : ['All', 'Basic', 'Cleaning'],
'clean_time' : ['All', 'Basic', 'Cleaning'],
'clean_kg' : ['All', 'Basic', 'Cleaning', 'Overview'],
'clean_days' : ['All', 'Basic', 'Cleaning'],
'clean' : ['All', 'Basic', 'Cleaning'],
}

itemDescriptions = {'clean_after': 'Clean the boiler after this amount burned',
'clean_time' : 'dd/mm/yy hh:mm Time when the boiler was cleaned',
'clean_kg' : 'Amount burned since last cleaning',
'clean_days' : 'Remaining days until the boiler should be cleaned',
'clean' : 'Set clean_time to now',
}

itemValues={}
Menutags = ['Cleaning']

class cleaningplugin(protocols):
def __init__(self):
protocols.__init__(self)

def activate(self, conf, glob):
protocols.activate(self, conf, glob)
self.items = {i['name']:i for i in itemList}
self.db = self.glob['conf'].db
self.valuestore = ConfigParser()
self.valuestore.add_section('values')
self.valuesfile = path.join(path.dirname(__file__), 'values.conf')
self.feeder_time = self.glob['conf'].item_to_ds_name['feeder_time']
self.feeder_capacity = self.glob['conf'].item_to_ds_name['feeder_capacity']
for item in itemList:
if item['type'] == 'R/W':
self.valuestore.set('values', item['name'], item['value'])
else:
itemValues[item['name']] = item['value']
self.valuestore.read(self.valuesfile)
f = open(self.valuesfile, 'w')
self.valuestore.write(f)
f.close()
try:
uid = pwd.getpwnam(self.glob['conf'].USER).pw_uid
gid = grp.getgrnam(self.glob['conf'].GROUP).gr_gid
os.chown(self.valuesfile, uid, gid)
except:
pass

def getItem(self, itemName):
item = self.items[itemName]
if itemName == 'clean_kg':
now = int(time.time())
if 'update_time' not in item or now - item['update_time'] > 600:
start = self.getItem('clean_time')
start = datetime.strptime(start,'%d/%m/%y %H:%M')
start = int(mktime(start.timetuple()))
try:
item['value'] = self.rrd_total(start, now)
item['update_time'] = now
return item['value']
except Exception, e:
return str(e)
else:
return item['value']
else:
if itemName in self.items:
return str(self.valuestore.get('values', itemName))
else:
return 'error'

def setItem(self, item, value):
try:
if item == 'clean':
d = datetime.fromtimestamp(time.time())
s = d.strftime('%d/%m/%y %H:%M')
self.setItem('clean_time', s)
return 'OK'
elif item == 'clean_time':
self.items['clean_kg']['update_time'] = 0
if itemValues.has_key(item):
itemValues[item] = value
return 'OK'
else:
try:
t = datetime.strptime(value,'%d/%m/%y %H:%M')
self.valuestore.set('values', item, str(value))
f = open(self.valuesfile, 'w')
self.valuestore.write(f)
f.close()
return 'OK'
except Exception,e:
return 'error'
except Exception,e:
return 'error'

def getDataBase(self):
l=[]
for item in itemList:
l.append(item['name'])
return l

def GetFullDB(self, tags):

def match(requiredtags, existingtags):
for rt in requiredtags:
if rt != '' and not rt in existingtags:
return False
return True

items = [item for item in itemList if match(tags, itemTags[item['name']]) ]
items.sort(key = lambda k:k['name'])
for item in items:
item['description'] = itemDescriptions[item['name']]
return items

def getMenutags(self):
return Menutags


def rrd_total(self, start, end):
start = str(start)
end = str(end)
command = ['rrdtool', 'graph', '--start', start, '--end', end,'-', 'DEF:a=%s:%s:AVERAGE'%(self.db,self.feeder_time),'DEF:b=%s:%s:AVERAGE'%(self.db,self.feeder_capacity), 'CDEF:c=a,b,*,360000,/', 'VDEF:s=c,TOTAL', 'PRINT:s:\"%lf\"']
cmd = subprocess.Popen(command, shell=False, stdout=subprocess.PIPE)
try:
total = str(int(float(cmd.communicate()[0].splitlines()[1].strip('"'))))
except Exception, e:
total = '0'
return total

15 changes: 15 additions & 0 deletions src/Pellmonweb/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
web_PYTHON = \
pellmonweb.py \
pellmonconf.py \
auth.py \
consumption.py \
logview.py \
Expand All @@ -16,7 +17,10 @@ nobase_dist_foohtml_DATA = \
media/js/websocket.js \
media/js/reconnectingwebsocket.js \
media/js/consumption.js \
media/js/source.js \
media/css/pellmon.css \
media/css/pellmonconf.css \
media/css/pellmonconf_print.css \
media/img/pellmon.svg \
media/img/spinner.gif \
media/img/system.svg \
Expand Down Expand Up @@ -62,6 +66,17 @@ nobase_dist_foohtml_DATA = \
media/flot/jquery.flot.time.js \
media/flot/jquery.flot.resize.js \
media/flot/jquery.flot.navigate.js \
media/codemirror/LICENSE \
media/codemirror/lib/codemirror.css \
media/codemirror/lib/codemirror.js \
media/codemirror/mode/clike/clike.js \
media/codemirror/mode/clike/index.html \
media/codemirror/mode/clike/scala.html \
media/codemirror/mode/properties/index.html \
media/codemirror/mode/properties/properties.js \
media/codemirror/mode/simple/simple.js \
html_conf/layout.html \
html_conf/source.html \
html/layout.html \
html/parameters.html \
html/consumption.html \
Expand Down
Loading

0 comments on commit 68ce8ea

Please sign in to comment.