pyP2Monitor  1.0.0
Monitor a P2 furnace activity reading data on serial port
 All Data Structures Namespaces Functions Variables Groups Pages
pyP2DataReader.py
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-#
3 
4 # Copyright 2013, 2014 Weber Yann, Weber Laurent
5 #
6 # This file is part of pyP2Monitor.
7 #
8 # pyP2Monitor is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
12 #
13 # pyP2Monitor is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
17 #
18 # You should have received a copy of the GNU General Public License
19 # along with pyP2Monitor. If not, see <http://www.gnu.org/licenses/>.
20 #
21 
22 ##@page dprocess Howto use the data processing programm
23 #
24 # @section Howto use the data processing programm
25 # @subsection dpdesc Description
26 #
27 # This programm is used to read datas stored by the monitoring programm. It is able to generate charts to view datas over time using GnuPlot.
28 # It's implement a simple query langage to select data.
29 #
30 # @subsection dpopt Important options
31 #
32 # - -d Specify the sqlite database to use
33 # - -o Set the name of the output file
34 # - -f Set a format for output. Allowed formats are png, jpg or svg for GnuPlot charts, cvs and data (for raw datas in hexadecimal notation)
35 # - -q Specify a query of data to put in the output file
36 #
37 # To have more informations on possible options run "pyP2_monitor -h"
38 #
39 # @subsection dpqrystx Query syntax
40 #
41 # Each '-q' option take a string in argument that represent a simple query to select datas. Queries consist of multiple couple of option and value in the form option=value separated by coma.
42 #
43 # @subsubsection dpqryexpl Queries example
44 #
45 # $ ./pyP2_dprocess -d ./p2.db -q 'begin=-26h,end=-24h,format=diff,n=5' -q 'b=-26h,e=-24h,f=diff,n=7'
46 #
47 # @subsubsection dpqryopt Query options list
48 #
49 # Each options has a shortcut ( for example begin= can be written as b= )
50 #
51 # - b or begin : begin_date (special value "now" and "first")
52 # - e or end : end_date (special value "now" and "first")
53 # - t or time : numeric time length with unit suffix (s seconds, m minutes, h hours, d days)
54 # - f or format : diff or DATEFORMAT diff mean that ou will use relatives notation like now , first (the date of first data), 10m (10 min in future) or -1h ( 1 hour in the past) DATEFORMAT is a date format like date use ( man 1 date ) to specify end and begin dates
55 # - d or data : data name
56 # - n or num : data number id (see pyP2_dprocess --list-field )
57 # - y or yaxe : Set the associated autoscale and y range (can be 1 for right y axe or 2 for the left y axe)
58 # - s or style : gnuplot graphic style (line, dots, pulse...)
59 # - sc or scale : graphic scale as a float value
60 # - a or add : integer to add at the graphics value
61 # - c or color : graphic color (with color name or in hex notation : #rrggbb )
62 # - l or label : graphic label
63 #
64 
65 import sys, os
66 import signal #Portability problem ???
67 import tempfile
68 
69 import pipes
70 
71 #import Gnuplot, Gnuplot.funcutils
72 
73 import p2dbstore
74 import p2data
75 import utils
76 
77 
78 args = utils.argParse('reader')
79 
80 #Init output (logging and verbosity)
81 utils.initLogging(args['verbosity'])
82 
83 logger = utils.getLogger()
84 
85 
86 if args['csvdump'] != None and args['database']:
87  p2data.csvDump(args['database'], args['csvdump'])
88  exit(0)
89 
90 if args['last_data'] != None:
91  p2data.csvLastDataDump(args['last_data'])
92  exit(0)
93 
94 if 'field_list' in args and args['field_list']:
95  names = p2data.colNames()
96  print "Field list :"
97  for i in range(len(names)):
98  print i,':\t'+names[i]
99  exit(0)
100 
101 if args['database']:
102  if args['query'] != None:
103  datas = p2data.P2Datas(args['database'],args['query'],args['separator'])
104 
105  datas.populate()
106 
107  if args['format'] == 'csv':
108 
109  #opening output file
110  if args['output'] == '-':
111  cvsout=sys.stdout
112  else:
113  cvsout = open(args['output'], "w+");
114 
115  #csv dumping
116  datas.getPlotData(True, cvsout,';')
117 
118  if args['output'] != '-':
119  cvsout.close()
120 
121  else:
122  #gnuplot command preparation
123  gbuff = ""
124  g = tempfile.NamedTemporaryFile('w+',-1,'pyP2gnuplotcommand')
125  rep = datas.getDateTimeFormats()
126 
127  if not (args['format'] == None or args['format'] == 'gnuplot'):
128  if args['format'] == 'png':
129  gbuff+='set terminal png'
130  elif args['format'] == 'svg':
131  gbuff+='set terminal svg'
132  elif args['format'] == 'jpg':
133  gbuff+='set terminal jpg'
134  if args['resolution'] != None:
135  gbuff+=' size '+args['resolution']
136  gbuff+='\n'
137  gbuff+='set output "'+args['output']+'"\n'
138  else:
139  gbuff+='set terminal wxt\n'
140 
141  if args['title'] != None:
142  gbuff+='set title "'+args['title']+'"\n'
143  if not rep is False:
144  (inFmt,outFmt) = rep
145  gbuff+='set xdata time\n'
146  gbuff+='set timefmt "'+inFmt+'"\n'
147  gbuff+='set format x "%H:%M:%S"\n'
148  gbuff+='set timefmt "'+inFmt+'"\n'
149  gbuff+='set ytics nomirror\n'
150  gbuff+='set y2tics nomirror\n'
151  gbuff+='set offset graph 0.001, 0.10, 0.20, 0.20\n'
152  gbuff+='set autoscale y\n'
153  gbuff+='set autoscale y2\n'
154 
155  #adding the plot command (it loads data in a file also)
156  gbuff += datas.getPlotCommand()
157  logger.debug("Writing gnuplot options : "+ gbuff)
158  g.write(gbuff)
159  g.flush()
160 
161  os.system('gnuplot --persist "'+g.name+'"')
162 
163  if args['format'] == 'gnuplot':
164  raw_input('Please press return to continue...\n')
165 
166  g.close()
167  exit(0)
168 
169  else:
170  print >> sys.stderr, 'Error, no query specified with database'
171  utils.argParse('reader','usage')
172  exit(1)
173 #elif args['input']:
174 # print 'Not implemented yet'
175 else:
176  print >> sys.stderr, 'Error, no input specified with -d or -i'
177  utils.argParse('reader','usage')
178  exit(1)
179 
180 
181 exit()