plantwatchdog 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +6 -2
- data/Manifest.txt +1 -0
- data/README.txt +12 -69
- data/Rakefile +2 -4
- data/lib/plantwatchdog/main.rb +1 -1
- data/lib/plantwatchdog/sinatra.rb +0 -3
- data/public/js/customflot.js +25 -0
- data/public/js/excanvas.min.js +1 -0
- data/public/js/select-chain.js +1 -2
- data/templates/graph.erb +19 -18
- data/templates/index.erb +4 -3
- data/templates/monthly_graph.erb +1 -1
- metadata +6 -22
data/History.txt
CHANGED
data/Manifest.txt
CHANGED
data/README.txt
CHANGED
@@ -1,36 +1,22 @@
|
|
1
1
|
= Plant Watchdog
|
2
2
|
|
3
|
+
http://wiki.github.com/mbarchfe/plantwatchdog
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
3
7
|
A watchdog for your technical plant, e.g. a photovoltaic generator. The plant
|
4
8
|
watchdog listens to data loggers, which continuously upload measurements of
|
5
9
|
plant parameters. Based on that data the watchdog creates reports about the
|
6
10
|
operational status.
|
7
11
|
|
8
|
-
|
9
|
-
== DESCRIPTION:
|
10
|
-
|
11
|
-
This software is being developed to monitor a photovoltaic generator. We found
|
12
|
-
that it would make sense to keep the domain specific knowledge out of the code
|
13
|
-
and instead provide a DSL to allow users to define their rules. Therefore this
|
14
|
-
software should be useful to monitor any kind of technical plant.
|
15
|
-
|
16
|
-
At the time being the focus of development is to
|
17
|
-
- make it reasonably stable
|
18
|
-
- run per-day aggregations
|
19
|
-
- show intraday and monthly diagrams
|
20
|
-
|
21
|
-
With more data being available the task of finding deviations from regular
|
22
|
-
operation is becoming feasible. Therefore expected values of parameters must
|
23
|
-
be calculated and compared with actual values: the users must be allowed to
|
24
|
-
define a model of the plant.
|
25
|
-
|
26
12
|
== FEATURES/PROBLEMS:
|
27
13
|
|
28
14
|
The vision of this software is to
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
15
|
+
* allow data logger devices to continuously upload time series measurements
|
16
|
+
* store and distribute measurement data
|
17
|
+
* run user defined aggregations and analyses on the data
|
18
|
+
* provide customizable HTML reports including visual diagrams
|
19
|
+
* find deviations from regular operation and send alarms if necessary
|
34
20
|
|
35
21
|
== REQUIREMENTS:
|
36
22
|
|
@@ -38,53 +24,10 @@ The vision of this software is to
|
|
38
24
|
|
39
25
|
== INSTALL:
|
40
26
|
|
41
|
-
|
42
|
-
For ubuntu
|
43
|
-
$ apt-get install ruby1.8-dev libopenssl-ruby1.8
|
27
|
+
gem install plantwatchdog
|
44
28
|
|
45
|
-
|
46
|
-
|
47
|
-
been tested with MySql 5.1.14 and SQLite 3.6.21.
|
48
|
-
|
49
|
-
In order to install sqlite3 and ruby bindings on ubuntu run
|
50
|
-
$ apt-get install sqlite3-dev
|
51
|
-
$ gem install sqlite3-ruby
|
52
|
-
|
53
|
-
3. Install Plant Watchdog and required gems
|
54
|
-
There are two options, either install the gem or download the sources from
|
55
|
-
github.
|
56
|
-
A) gem
|
57
|
-
$ gem install plantwatchdog
|
58
|
-
|
59
|
-
B) github
|
60
|
-
$ mkdir plant
|
61
|
-
$ cd plant
|
62
|
-
$ git clone git@github.com:mbarchfe/plantwatchdog.git
|
63
|
-
$ rake check_extra_deps // Get the required ruby gems
|
64
|
-
|
65
|
-
4. Install sample database and run
|
66
|
-
If your gem's bin directory is not on the PATH, add it
|
67
|
-
$ export PATH=$PATH:/var/lib/gems/1.8/bin
|
68
|
-
|
69
|
-
The default database connection uses sqlite3 and a database at
|
70
|
-
/tmp/solarsample.sqlite3. You can change the default by editing
|
71
|
-
the config file
|
72
|
-
$ vi config/app-config.yaml
|
73
|
-
|
74
|
-
Install the sample
|
75
|
-
$ plantwatch --create_sample
|
76
|
-
Upload data (needs curl and sqlite3 command line)
|
77
|
-
|
78
|
-
Start the plantwatchdog web server (an alternative way is to start via rackup)
|
79
|
-
$ plantwatchdog
|
80
|
-
|
81
|
-
On another shell upload sample measurements. The script needs curl and the
|
82
|
-
sqlite3 command line
|
83
|
-
$ apt-get install curl
|
84
|
-
$ upload_measurements
|
85
|
-
|
86
|
-
Run the daily aggregation
|
87
|
-
$ plantwatchdog -a
|
29
|
+
For more details see http://wiki.github.com/mbarchfe/plantwatchdog/installation.
|
30
|
+
In particular you will find a guide on how to set up a sample scenario.
|
88
31
|
|
89
32
|
== LICENSE:
|
90
33
|
|
data/Rakefile
CHANGED
@@ -8,11 +8,9 @@ Hoe.spec 'plantwatchdog' do |p|
|
|
8
8
|
developer('plantwatchdogteam', 'mbarchfe@rubyforge.org')
|
9
9
|
p.version=PlantWatchdog::Version::STRING
|
10
10
|
p.rubyforge_name = 'pwd'
|
11
|
-
p.author = "
|
11
|
+
p.author = "Plantwatchdog team"
|
12
12
|
p.email = "mbarchfe@rubyforge.org"
|
13
|
-
p.summary = '
|
14
|
-
p.description = p.paragraphs_of('README.txt', 1..5).join("\n\n")
|
15
|
-
p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
|
13
|
+
p.summary = 'Plantwatchdog monitors your plant.'
|
16
14
|
p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
|
17
15
|
p.extra_deps<<['sinatra','0.9.4']
|
18
16
|
p.extra_deps<<['activerecord', '2.3.5']
|
data/lib/plantwatchdog/main.rb
CHANGED
data/public/js/customflot.js
CHANGED
@@ -1,3 +1,28 @@
|
|
1
|
+
// IE
|
2
|
+
if (!Array.prototype.filter)
|
3
|
+
{
|
4
|
+
Array.prototype.filter = function(fun /*, thisp*/)
|
5
|
+
{
|
6
|
+
var len = this.length >>> 0;
|
7
|
+
if (typeof fun != "function")
|
8
|
+
throw new TypeError();
|
9
|
+
|
10
|
+
var res = [];
|
11
|
+
var thisp = arguments[1];
|
12
|
+
for (var i = 0; i < len; i++)
|
13
|
+
{
|
14
|
+
if (i in this)
|
15
|
+
{
|
16
|
+
var val = this[i]; // in case fun mutates this
|
17
|
+
if (fun.call(thisp, val, i, this))
|
18
|
+
res.push(val);
|
19
|
+
}
|
20
|
+
}
|
21
|
+
|
22
|
+
return res;
|
23
|
+
};
|
24
|
+
}
|
25
|
+
|
1
26
|
function Graph(placeholder_id) {
|
2
27
|
this.placeholder_id = placeholder_id
|
3
28
|
this.placeholder = $(placeholder_id);
|
@@ -0,0 +1 @@
|
|
1
|
+
if(!document.createElement("canvas").getContext){(function(){var z=Math;var K=z.round;var J=z.sin;var U=z.cos;var b=z.abs;var k=z.sqrt;var D=10;var F=D/2;function T(){return this.context_||(this.context_=new W(this))}var O=Array.prototype.slice;function G(i,j,m){var Z=O.call(arguments,2);return function(){return i.apply(j,Z.concat(O.call(arguments)))}}function AD(Z){return String(Z).replace(/&/g,"&").replace(/"/g,""")}function r(i){if(!i.namespaces.g_vml_){i.namespaces.add("g_vml_","urn:schemas-microsoft-com:vml","#default#VML")}if(!i.namespaces.g_o_){i.namespaces.add("g_o_","urn:schemas-microsoft-com:office:office","#default#VML")}if(!i.styleSheets.ex_canvas_){var Z=i.createStyleSheet();Z.owningElement.id="ex_canvas_";Z.cssText="canvas{display:inline-block;overflow:hidden;text-align:left;width:300px;height:150px}"}}r(document);var E={init:function(Z){if(/MSIE/.test(navigator.userAgent)&&!window.opera){var i=Z||document;i.createElement("canvas");i.attachEvent("onreadystatechange",G(this.init_,this,i))}},init_:function(m){var j=m.getElementsByTagName("canvas");for(var Z=0;Z<j.length;Z++){this.initElement(j[Z])}},initElement:function(i){if(!i.getContext){i.getContext=T;r(i.ownerDocument);i.innerHTML="";i.attachEvent("onpropertychange",S);i.attachEvent("onresize",w);var Z=i.attributes;if(Z.width&&Z.width.specified){i.style.width=Z.width.nodeValue+"px"}else{i.width=i.clientWidth}if(Z.height&&Z.height.specified){i.style.height=Z.height.nodeValue+"px"}else{i.height=i.clientHeight}}return i}};function S(i){var Z=i.srcElement;switch(i.propertyName){case"width":Z.getContext().clearRect();Z.style.width=Z.attributes.width.nodeValue+"px";Z.firstChild.style.width=Z.clientWidth+"px";break;case"height":Z.getContext().clearRect();Z.style.height=Z.attributes.height.nodeValue+"px";Z.firstChild.style.height=Z.clientHeight+"px";break}}function w(i){var Z=i.srcElement;if(Z.firstChild){Z.firstChild.style.width=Z.clientWidth+"px";Z.firstChild.style.height=Z.clientHeight+"px"}}E.init();var I=[];for(var AC=0;AC<16;AC++){for(var AB=0;AB<16;AB++){I[AC*16+AB]=AC.toString(16)+AB.toString(16)}}function V(){return[[1,0,0],[0,1,0],[0,0,1]]}function d(m,j){var i=V();for(var Z=0;Z<3;Z++){for(var AF=0;AF<3;AF++){var p=0;for(var AE=0;AE<3;AE++){p+=m[Z][AE]*j[AE][AF]}i[Z][AF]=p}}return i}function Q(i,Z){Z.fillStyle=i.fillStyle;Z.lineCap=i.lineCap;Z.lineJoin=i.lineJoin;Z.lineWidth=i.lineWidth;Z.miterLimit=i.miterLimit;Z.shadowBlur=i.shadowBlur;Z.shadowColor=i.shadowColor;Z.shadowOffsetX=i.shadowOffsetX;Z.shadowOffsetY=i.shadowOffsetY;Z.strokeStyle=i.strokeStyle;Z.globalAlpha=i.globalAlpha;Z.font=i.font;Z.textAlign=i.textAlign;Z.textBaseline=i.textBaseline;Z.arcScaleX_=i.arcScaleX_;Z.arcScaleY_=i.arcScaleY_;Z.lineScale_=i.lineScale_}var B={aliceblue:"#F0F8FF",antiquewhite:"#FAEBD7",aquamarine:"#7FFFD4",azure:"#F0FFFF",beige:"#F5F5DC",bisque:"#FFE4C4",black:"#000000",blanchedalmond:"#FFEBCD",blueviolet:"#8A2BE2",brown:"#A52A2A",burlywood:"#DEB887",cadetblue:"#5F9EA0",chartreuse:"#7FFF00",chocolate:"#D2691E",coral:"#FF7F50",cornflowerblue:"#6495ED",cornsilk:"#FFF8DC",crimson:"#DC143C",cyan:"#00FFFF",darkblue:"#00008B",darkcyan:"#008B8B",darkgoldenrod:"#B8860B",darkgray:"#A9A9A9",darkgreen:"#006400",darkgrey:"#A9A9A9",darkkhaki:"#BDB76B",darkmagenta:"#8B008B",darkolivegreen:"#556B2F",darkorange:"#FF8C00",darkorchid:"#9932CC",darkred:"#8B0000",darksalmon:"#E9967A",darkseagreen:"#8FBC8F",darkslateblue:"#483D8B",darkslategray:"#2F4F4F",darkslategrey:"#2F4F4F",darkturquoise:"#00CED1",darkviolet:"#9400D3",deeppink:"#FF1493",deepskyblue:"#00BFFF",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1E90FF",firebrick:"#B22222",floralwhite:"#FFFAF0",forestgreen:"#228B22",gainsboro:"#DCDCDC",ghostwhite:"#F8F8FF",gold:"#FFD700",goldenrod:"#DAA520",grey:"#808080",greenyellow:"#ADFF2F",honeydew:"#F0FFF0",hotpink:"#FF69B4",indianred:"#CD5C5C",indigo:"#4B0082",ivory:"#FFFFF0",khaki:"#F0E68C",lavender:"#E6E6FA",lavenderblush:"#FFF0F5",lawngreen:"#7CFC00",lemonchiffon:"#FFFACD",lightblue:"#ADD8E6",lightcoral:"#F08080",lightcyan:"#E0FFFF",lightgoldenrodyellow:"#FAFAD2",lightgreen:"#90EE90",lightgrey:"#D3D3D3",lightpink:"#FFB6C1",lightsalmon:"#FFA07A",lightseagreen:"#20B2AA",lightskyblue:"#87CEFA",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#B0C4DE",lightyellow:"#FFFFE0",limegreen:"#32CD32",linen:"#FAF0E6",magenta:"#FF00FF",mediumaquamarine:"#66CDAA",mediumblue:"#0000CD",mediumorchid:"#BA55D3",mediumpurple:"#9370DB",mediumseagreen:"#3CB371",mediumslateblue:"#7B68EE",mediumspringgreen:"#00FA9A",mediumturquoise:"#48D1CC",mediumvioletred:"#C71585",midnightblue:"#191970",mintcream:"#F5FFFA",mistyrose:"#FFE4E1",moccasin:"#FFE4B5",navajowhite:"#FFDEAD",oldlace:"#FDF5E6",olivedrab:"#6B8E23",orange:"#FFA500",orangered:"#FF4500",orchid:"#DA70D6",palegoldenrod:"#EEE8AA",palegreen:"#98FB98",paleturquoise:"#AFEEEE",palevioletred:"#DB7093",papayawhip:"#FFEFD5",peachpuff:"#FFDAB9",peru:"#CD853F",pink:"#FFC0CB",plum:"#DDA0DD",powderblue:"#B0E0E6",rosybrown:"#BC8F8F",royalblue:"#4169E1",saddlebrown:"#8B4513",salmon:"#FA8072",sandybrown:"#F4A460",seagreen:"#2E8B57",seashell:"#FFF5EE",sienna:"#A0522D",skyblue:"#87CEEB",slateblue:"#6A5ACD",slategray:"#708090",slategrey:"#708090",snow:"#FFFAFA",springgreen:"#00FF7F",steelblue:"#4682B4",tan:"#D2B48C",thistle:"#D8BFD8",tomato:"#FF6347",turquoise:"#40E0D0",violet:"#EE82EE",wheat:"#F5DEB3",whitesmoke:"#F5F5F5",yellowgreen:"#9ACD32"};function g(i){var m=i.indexOf("(",3);var Z=i.indexOf(")",m+1);var j=i.substring(m+1,Z).split(",");if(j.length==4&&i.substr(3,1)=="a"){alpha=Number(j[3])}else{j[3]=1}return j}function C(Z){return parseFloat(Z)/100}function N(i,j,Z){return Math.min(Z,Math.max(j,i))}function c(AF){var j,i,Z;h=parseFloat(AF[0])/360%360;if(h<0){h++}s=N(C(AF[1]),0,1);l=N(C(AF[2]),0,1);if(s==0){j=i=Z=l}else{var m=l<0.5?l*(1+s):l+s-l*s;var AE=2*l-m;j=A(AE,m,h+1/3);i=A(AE,m,h);Z=A(AE,m,h-1/3)}return"#"+I[Math.floor(j*255)]+I[Math.floor(i*255)]+I[Math.floor(Z*255)]}function A(i,Z,j){if(j<0){j++}if(j>1){j--}if(6*j<1){return i+(Z-i)*6*j}else{if(2*j<1){return Z}else{if(3*j<2){return i+(Z-i)*(2/3-j)*6}else{return i}}}}function Y(Z){var AE,p=1;Z=String(Z);if(Z.charAt(0)=="#"){AE=Z}else{if(/^rgb/.test(Z)){var m=g(Z);var AE="#",AF;for(var j=0;j<3;j++){if(m[j].indexOf("%")!=-1){AF=Math.floor(C(m[j])*255)}else{AF=Number(m[j])}AE+=I[N(AF,0,255)]}p=m[3]}else{if(/^hsl/.test(Z)){var m=g(Z);AE=c(m);p=m[3]}else{AE=B[Z]||Z}}}return{color:AE,alpha:p}}var L={style:"normal",variant:"normal",weight:"normal",size:10,family:"sans-serif"};var f={};function X(Z){if(f[Z]){return f[Z]}var m=document.createElement("div");var j=m.style;try{j.font=Z}catch(i){}return f[Z]={style:j.fontStyle||L.style,variant:j.fontVariant||L.variant,weight:j.fontWeight||L.weight,size:j.fontSize||L.size,family:j.fontFamily||L.family}}function P(j,i){var Z={};for(var AF in j){Z[AF]=j[AF]}var AE=parseFloat(i.currentStyle.fontSize),m=parseFloat(j.size);if(typeof j.size=="number"){Z.size=j.size}else{if(j.size.indexOf("px")!=-1){Z.size=m}else{if(j.size.indexOf("em")!=-1){Z.size=AE*m}else{if(j.size.indexOf("%")!=-1){Z.size=(AE/100)*m}else{if(j.size.indexOf("pt")!=-1){Z.size=m/0.75}else{Z.size=AE}}}}}Z.size*=0.981;return Z}function AA(Z){return Z.style+" "+Z.variant+" "+Z.weight+" "+Z.size+"px "+Z.family}function t(Z){switch(Z){case"butt":return"flat";case"round":return"round";case"square":default:return"square"}}function W(i){this.m_=V();this.mStack_=[];this.aStack_=[];this.currentPath_=[];this.strokeStyle="#000";this.fillStyle="#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=D*1;this.globalAlpha=1;this.font="10px sans-serif";this.textAlign="left";this.textBaseline="alphabetic";this.canvas=i;var Z=i.ownerDocument.createElement("div");Z.style.width=i.clientWidth+"px";Z.style.height=i.clientHeight+"px";Z.style.overflow="hidden";Z.style.position="absolute";i.appendChild(Z);this.element_=Z;this.arcScaleX_=1;this.arcScaleY_=1;this.lineScale_=1}var M=W.prototype;M.clearRect=function(){if(this.textMeasureEl_){this.textMeasureEl_.removeNode(true);this.textMeasureEl_=null}this.element_.innerHTML=""};M.beginPath=function(){this.currentPath_=[]};M.moveTo=function(i,Z){var j=this.getCoords_(i,Z);this.currentPath_.push({type:"moveTo",x:j.x,y:j.y});this.currentX_=j.x;this.currentY_=j.y};M.lineTo=function(i,Z){var j=this.getCoords_(i,Z);this.currentPath_.push({type:"lineTo",x:j.x,y:j.y});this.currentX_=j.x;this.currentY_=j.y};M.bezierCurveTo=function(j,i,AI,AH,AG,AE){var Z=this.getCoords_(AG,AE);var AF=this.getCoords_(j,i);var m=this.getCoords_(AI,AH);e(this,AF,m,Z)};function e(Z,m,j,i){Z.currentPath_.push({type:"bezierCurveTo",cp1x:m.x,cp1y:m.y,cp2x:j.x,cp2y:j.y,x:i.x,y:i.y});Z.currentX_=i.x;Z.currentY_=i.y}M.quadraticCurveTo=function(AG,j,i,Z){var AF=this.getCoords_(AG,j);var AE=this.getCoords_(i,Z);var AH={x:this.currentX_+2/3*(AF.x-this.currentX_),y:this.currentY_+2/3*(AF.y-this.currentY_)};var m={x:AH.x+(AE.x-this.currentX_)/3,y:AH.y+(AE.y-this.currentY_)/3};e(this,AH,m,AE)};M.arc=function(AJ,AH,AI,AE,i,j){AI*=D;var AN=j?"at":"wa";var AK=AJ+U(AE)*AI-F;var AM=AH+J(AE)*AI-F;var Z=AJ+U(i)*AI-F;var AL=AH+J(i)*AI-F;if(AK==Z&&!j){AK+=0.125}var m=this.getCoords_(AJ,AH);var AG=this.getCoords_(AK,AM);var AF=this.getCoords_(Z,AL);this.currentPath_.push({type:AN,x:m.x,y:m.y,radius:AI,xStart:AG.x,yStart:AG.y,xEnd:AF.x,yEnd:AF.y})};M.rect=function(j,i,Z,m){this.moveTo(j,i);this.lineTo(j+Z,i);this.lineTo(j+Z,i+m);this.lineTo(j,i+m);this.closePath()};M.strokeRect=function(j,i,Z,m){var p=this.currentPath_;this.beginPath();this.moveTo(j,i);this.lineTo(j+Z,i);this.lineTo(j+Z,i+m);this.lineTo(j,i+m);this.closePath();this.stroke();this.currentPath_=p};M.fillRect=function(j,i,Z,m){var p=this.currentPath_;this.beginPath();this.moveTo(j,i);this.lineTo(j+Z,i);this.lineTo(j+Z,i+m);this.lineTo(j,i+m);this.closePath();this.fill();this.currentPath_=p};M.createLinearGradient=function(i,m,Z,j){var p=new v("gradient");p.x0_=i;p.y0_=m;p.x1_=Z;p.y1_=j;return p};M.createRadialGradient=function(m,AE,j,i,p,Z){var AF=new v("gradientradial");AF.x0_=m;AF.y0_=AE;AF.r0_=j;AF.x1_=i;AF.y1_=p;AF.r1_=Z;return AF};M.drawImage=function(AO,j){var AH,AF,AJ,AV,AM,AK,AQ,AX;var AI=AO.runtimeStyle.width;var AN=AO.runtimeStyle.height;AO.runtimeStyle.width="auto";AO.runtimeStyle.height="auto";var AG=AO.width;var AT=AO.height;AO.runtimeStyle.width=AI;AO.runtimeStyle.height=AN;if(arguments.length==3){AH=arguments[1];AF=arguments[2];AM=AK=0;AQ=AJ=AG;AX=AV=AT}else{if(arguments.length==5){AH=arguments[1];AF=arguments[2];AJ=arguments[3];AV=arguments[4];AM=AK=0;AQ=AG;AX=AT}else{if(arguments.length==9){AM=arguments[1];AK=arguments[2];AQ=arguments[3];AX=arguments[4];AH=arguments[5];AF=arguments[6];AJ=arguments[7];AV=arguments[8]}else{throw Error("Invalid number of arguments")}}}var AW=this.getCoords_(AH,AF);var m=AQ/2;var i=AX/2;var AU=[];var Z=10;var AE=10;AU.push(" <g_vml_:group",' coordsize="',D*Z,",",D*AE,'"',' coordorigin="0,0"',' style="width:',Z,"px;height:",AE,"px;position:absolute;");if(this.m_[0][0]!=1||this.m_[0][1]||this.m_[1][1]!=1||this.m_[1][0]){var p=[];p.push("M11=",this.m_[0][0],",","M12=",this.m_[1][0],",","M21=",this.m_[0][1],",","M22=",this.m_[1][1],",","Dx=",K(AW.x/D),",","Dy=",K(AW.y/D),"");var AS=AW;var AR=this.getCoords_(AH+AJ,AF);var AP=this.getCoords_(AH,AF+AV);var AL=this.getCoords_(AH+AJ,AF+AV);AS.x=z.max(AS.x,AR.x,AP.x,AL.x);AS.y=z.max(AS.y,AR.y,AP.y,AL.y);AU.push("padding:0 ",K(AS.x/D),"px ",K(AS.y/D),"px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",p.join(""),", sizingmethod='clip');")}else{AU.push("top:",K(AW.y/D),"px;left:",K(AW.x/D),"px;")}AU.push(' ">','<g_vml_:image src="',AO.src,'"',' style="width:',D*AJ,"px;"," height:",D*AV,'px"',' cropleft="',AM/AG,'"',' croptop="',AK/AT,'"',' cropright="',(AG-AM-AQ)/AG,'"',' cropbottom="',(AT-AK-AX)/AT,'"'," />","</g_vml_:group>");this.element_.insertAdjacentHTML("BeforeEnd",AU.join(""))};M.stroke=function(AM){var m=10;var AN=10;var AE=5000;var AG={x:null,y:null};var AL={x:null,y:null};for(var AH=0;AH<this.currentPath_.length;AH+=AE){var AK=[];var AF=false;AK.push("<g_vml_:shape",' filled="',!!AM,'"',' style="position:absolute;width:',m,"px;height:",AN,'px;"',' coordorigin="0,0"',' coordsize="',D*m,",",D*AN,'"',' stroked="',!AM,'"',' path="');var AO=false;for(var AI=AH;AI<Math.min(AH+AE,this.currentPath_.length);AI++){if(AI%AE==0&&AI>0){AK.push(" m ",K(this.currentPath_[AI-1].x),",",K(this.currentPath_[AI-1].y))}var Z=this.currentPath_[AI];var AJ;switch(Z.type){case"moveTo":AJ=Z;AK.push(" m ",K(Z.x),",",K(Z.y));break;case"lineTo":AK.push(" l ",K(Z.x),",",K(Z.y));break;case"close":AK.push(" x ");Z=null;break;case"bezierCurveTo":AK.push(" c ",K(Z.cp1x),",",K(Z.cp1y),",",K(Z.cp2x),",",K(Z.cp2y),",",K(Z.x),",",K(Z.y));break;case"at":case"wa":AK.push(" ",Z.type," ",K(Z.x-this.arcScaleX_*Z.radius),",",K(Z.y-this.arcScaleY_*Z.radius)," ",K(Z.x+this.arcScaleX_*Z.radius),",",K(Z.y+this.arcScaleY_*Z.radius)," ",K(Z.xStart),",",K(Z.yStart)," ",K(Z.xEnd),",",K(Z.yEnd));break}if(Z){if(AG.x==null||Z.x<AG.x){AG.x=Z.x}if(AL.x==null||Z.x>AL.x){AL.x=Z.x}if(AG.y==null||Z.y<AG.y){AG.y=Z.y}if(AL.y==null||Z.y>AL.y){AL.y=Z.y}}}AK.push(' ">');if(!AM){R(this,AK)}else{a(this,AK,AG,AL)}AK.push("</g_vml_:shape>");this.element_.insertAdjacentHTML("beforeEnd",AK.join(""))}};function R(j,AE){var i=Y(j.strokeStyle);var m=i.color;var p=i.alpha*j.globalAlpha;var Z=j.lineScale_*j.lineWidth;if(Z<1){p*=Z}AE.push("<g_vml_:stroke",' opacity="',p,'"',' joinstyle="',j.lineJoin,'"',' miterlimit="',j.miterLimit,'"',' endcap="',t(j.lineCap),'"',' weight="',Z,'px"',' color="',m,'" />')}function a(AO,AG,Ah,AP){var AH=AO.fillStyle;var AY=AO.arcScaleX_;var AX=AO.arcScaleY_;var Z=AP.x-Ah.x;var m=AP.y-Ah.y;if(AH instanceof v){var AL=0;var Ac={x:0,y:0};var AU=0;var AK=1;if(AH.type_=="gradient"){var AJ=AH.x0_/AY;var j=AH.y0_/AX;var AI=AH.x1_/AY;var Aj=AH.y1_/AX;var Ag=AO.getCoords_(AJ,j);var Af=AO.getCoords_(AI,Aj);var AE=Af.x-Ag.x;var p=Af.y-Ag.y;AL=Math.atan2(AE,p)*180/Math.PI;if(AL<0){AL+=360}if(AL<0.000001){AL=0}}else{var Ag=AO.getCoords_(AH.x0_,AH.y0_);Ac={x:(Ag.x-Ah.x)/Z,y:(Ag.y-Ah.y)/m};Z/=AY*D;m/=AX*D;var Aa=z.max(Z,m);AU=2*AH.r0_/Aa;AK=2*AH.r1_/Aa-AU}var AS=AH.colors_;AS.sort(function(Ak,i){return Ak.offset-i.offset});var AN=AS.length;var AR=AS[0].color;var AQ=AS[AN-1].color;var AW=AS[0].alpha*AO.globalAlpha;var AV=AS[AN-1].alpha*AO.globalAlpha;var Ab=[];for(var Ae=0;Ae<AN;Ae++){var AM=AS[Ae];Ab.push(AM.offset*AK+AU+" "+AM.color)}AG.push('<g_vml_:fill type="',AH.type_,'"',' method="none" focus="100%"',' color="',AR,'"',' color2="',AQ,'"',' colors="',Ab.join(","),'"',' opacity="',AV,'"',' g_o_:opacity2="',AW,'"',' angle="',AL,'"',' focusposition="',Ac.x,",",Ac.y,'" />')}else{if(AH instanceof u){if(Z&&m){var AF=-Ah.x;var AZ=-Ah.y;AG.push("<g_vml_:fill",' position="',AF/Z*AY*AY,",",AZ/m*AX*AX,'"',' type="tile"',' src="',AH.src_,'" />')}}else{var Ai=Y(AO.fillStyle);var AT=Ai.color;var Ad=Ai.alpha*AO.globalAlpha;AG.push('<g_vml_:fill color="',AT,'" opacity="',Ad,'" />')}}}M.fill=function(){this.stroke(true)};M.closePath=function(){this.currentPath_.push({type:"close"})};M.getCoords_=function(j,i){var Z=this.m_;return{x:D*(j*Z[0][0]+i*Z[1][0]+Z[2][0])-F,y:D*(j*Z[0][1]+i*Z[1][1]+Z[2][1])-F}};M.save=function(){var Z={};Q(this,Z);this.aStack_.push(Z);this.mStack_.push(this.m_);this.m_=d(V(),this.m_)};M.restore=function(){if(this.aStack_.length){Q(this.aStack_.pop(),this);this.m_=this.mStack_.pop()}};function H(Z){return isFinite(Z[0][0])&&isFinite(Z[0][1])&&isFinite(Z[1][0])&&isFinite(Z[1][1])&&isFinite(Z[2][0])&&isFinite(Z[2][1])}function y(i,Z,j){if(!H(Z)){return }i.m_=Z;if(j){var p=Z[0][0]*Z[1][1]-Z[0][1]*Z[1][0];i.lineScale_=k(b(p))}}M.translate=function(j,i){var Z=[[1,0,0],[0,1,0],[j,i,1]];y(this,d(Z,this.m_),false)};M.rotate=function(i){var m=U(i);var j=J(i);var Z=[[m,j,0],[-j,m,0],[0,0,1]];y(this,d(Z,this.m_),false)};M.scale=function(j,i){this.arcScaleX_*=j;this.arcScaleY_*=i;var Z=[[j,0,0],[0,i,0],[0,0,1]];y(this,d(Z,this.m_),true)};M.transform=function(p,m,AF,AE,i,Z){var j=[[p,m,0],[AF,AE,0],[i,Z,1]];y(this,d(j,this.m_),true)};M.setTransform=function(AE,p,AG,AF,j,i){var Z=[[AE,p,0],[AG,AF,0],[j,i,1]];y(this,Z,true)};M.drawText_=function(AK,AI,AH,AN,AG){var AM=this.m_,AQ=1000,i=0,AP=AQ,AF={x:0,y:0},AE=[];var Z=P(X(this.font),this.element_);var j=AA(Z);var AR=this.element_.currentStyle;var p=this.textAlign.toLowerCase();switch(p){case"left":case"center":case"right":break;case"end":p=AR.direction=="ltr"?"right":"left";break;case"start":p=AR.direction=="rtl"?"right":"left";break;default:p="left"}switch(this.textBaseline){case"hanging":case"top":AF.y=Z.size/1.75;break;case"middle":break;default:case null:case"alphabetic":case"ideographic":case"bottom":AF.y=-Z.size/2.25;break}switch(p){case"right":i=AQ;AP=0.05;break;case"center":i=AP=AQ/2;break}var AO=this.getCoords_(AI+AF.x,AH+AF.y);AE.push('<g_vml_:line from="',-i,' 0" to="',AP,' 0.05" ',' coordsize="100 100" coordorigin="0 0"',' filled="',!AG,'" stroked="',!!AG,'" style="position:absolute;width:1px;height:1px;">');if(AG){R(this,AE)}else{a(this,AE,{x:-i,y:0},{x:AP,y:Z.size})}var AL=AM[0][0].toFixed(3)+","+AM[1][0].toFixed(3)+","+AM[0][1].toFixed(3)+","+AM[1][1].toFixed(3)+",0,0";var AJ=K(AO.x/D)+","+K(AO.y/D);AE.push('<g_vml_:skew on="t" matrix="',AL,'" ',' offset="',AJ,'" origin="',i,' 0" />','<g_vml_:path textpathok="true" />','<g_vml_:textpath on="true" string="',AD(AK),'" style="v-text-align:',p,";font:",AD(j),'" /></g_vml_:line>');this.element_.insertAdjacentHTML("beforeEnd",AE.join(""))};M.fillText=function(j,Z,m,i){this.drawText_(j,Z,m,i,false)};M.strokeText=function(j,Z,m,i){this.drawText_(j,Z,m,i,true)};M.measureText=function(j){if(!this.textMeasureEl_){var Z='<span style="position:absolute;top:-20000px;left:0;padding:0;margin:0;border:none;white-space:pre;"></span>';this.element_.insertAdjacentHTML("beforeEnd",Z);this.textMeasureEl_=this.element_.lastChild}var i=this.element_.ownerDocument;this.textMeasureEl_.innerHTML="";this.textMeasureEl_.style.font=this.font;this.textMeasureEl_.appendChild(i.createTextNode(j));return{width:this.textMeasureEl_.offsetWidth}};M.clip=function(){};M.arcTo=function(){};M.createPattern=function(i,Z){return new u(i,Z)};function v(Z){this.type_=Z;this.x0_=0;this.y0_=0;this.r0_=0;this.x1_=0;this.y1_=0;this.r1_=0;this.colors_=[]}v.prototype.addColorStop=function(i,Z){Z=Y(Z);this.colors_.push({offset:i,color:Z.color,alpha:Z.alpha})};function u(i,Z){q(i);switch(Z){case"repeat":case null:case"":this.repetition_="repeat";break;case"repeat-x":case"repeat-y":case"no-repeat":this.repetition_=Z;break;default:n("SYNTAX_ERR")}this.src_=i.src;this.width_=i.width;this.height_=i.height}function n(Z){throw new o(Z)}function q(Z){if(!Z||Z.nodeType!=1||Z.tagName!="IMG"){n("TYPE_MISMATCH_ERR")}if(Z.readyState!="complete"){n("INVALID_STATE_ERR")}}function o(Z){this.code=this[Z];this.message=Z+": DOM Exception "+this.code}var x=o.prototype=new Error;x.INDEX_SIZE_ERR=1;x.DOMSTRING_SIZE_ERR=2;x.HIERARCHY_REQUEST_ERR=3;x.WRONG_DOCUMENT_ERR=4;x.INVALID_CHARACTER_ERR=5;x.NO_DATA_ALLOWED_ERR=6;x.NO_MODIFICATION_ALLOWED_ERR=7;x.NOT_FOUND_ERR=8;x.NOT_SUPPORTED_ERR=9;x.INUSE_ATTRIBUTE_ERR=10;x.INVALID_STATE_ERR=11;x.SYNTAX_ERR=12;x.INVALID_MODIFICATION_ERR=13;x.NAMESPACE_ERR=14;x.INVALID_ACCESS_ERR=15;x.VALIDATION_ERR=16;x.TYPE_MISMATCH_ERR=17;G_vmlCanvasManager=E;CanvasRenderingContext2D=W;CanvasGradient=v;CanvasPattern=u;DOMException=o})()};
|
data/public/js/select-chain.js
CHANGED
data/templates/graph.erb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
1
3
|
<style>
|
2
4
|
#placeholder .button {
|
3
5
|
position: absolute;
|
@@ -14,6 +16,8 @@
|
|
14
16
|
}
|
15
17
|
</style>
|
16
18
|
<link rel="stylesheet" href="tabs.css" type="text/css" />
|
19
|
+
</head>
|
20
|
+
<body>
|
17
21
|
<ul class="tabs">
|
18
22
|
<li><a href="#"><span>Intraday</span></a></li>
|
19
23
|
<li><a href="#"><span>Monthly report</span></a></li>
|
@@ -26,7 +30,7 @@
|
|
26
30
|
<% years = years_with_data(user);
|
27
31
|
years.each_index {
|
28
32
|
|i| %>
|
29
|
-
<option <%=i == years.size() -1 ? 'selected="selected"' : ""%>><%=years[i].to_s%></option>
|
33
|
+
<option value="<%=years[i].to_s%>" <%=i == years.size() -1 ? 'selected="selected"' : ""%>><%=years[i].to_s%></option>
|
30
34
|
<% } %>
|
31
35
|
</select>
|
32
36
|
<label for="select_graph_month">Month:</label></td>
|
@@ -53,6 +57,16 @@
|
|
53
57
|
</div>
|
54
58
|
|
55
59
|
<script src="/js/jquery-1.3.2.min.js" type="text/javascript"></script>
|
60
|
+
<!-- ie hacks -->
|
61
|
+
<script src="/js/excanvas.min.js" type="text/javascript"></script>
|
62
|
+
<!-- make sure that flot is loaded before the other scripts, since some of them depend on it -->
|
63
|
+
<script src="/js/jquery.flot.js" type="text/javascript"></script>
|
64
|
+
<script src="/js/select-chain.js" type="text/javascript"></script>
|
65
|
+
<script src="/js/jquery.flot.crosshair.js" type="text/javascript"></script>
|
66
|
+
<script src="/js/jquery.flot.selection.js" type="text/javascript"></script>
|
67
|
+
<script src="/js/jquery.flot.navigate.js" type="text/javascript"></script>
|
68
|
+
<script src="/js/tools.tabs-1.0.4.js" type="text/javascript"></script>
|
69
|
+
<script src="/js/customflot.js" type="text/javascript"></script>
|
56
70
|
<script id="source" language="javascript" type="text/javascript">
|
57
71
|
prepare_graph = function () {
|
58
72
|
var year = $('#select_graph_year');
|
@@ -114,21 +128,8 @@ prepare_graph = function () {
|
|
114
128
|
}
|
115
129
|
});
|
116
130
|
};
|
131
|
+
prepare_graph();
|
132
|
+
</script>
|
133
|
+
</body>
|
134
|
+
</html>
|
117
135
|
|
118
|
-
var scripts = [ "js/select-chain.js", "js/jquery.flot.crosshair.js", "js/jquery.flot.selection.js",
|
119
|
-
"js/jquery.flot.navigate.js", "js/tools.tabs-1.0.4.js", "js/customflot.js" ]
|
120
|
-
var loaded = 0;
|
121
|
-
function load_other_scripts() {
|
122
|
-
$.each( scripts,
|
123
|
-
function(i,script) {
|
124
|
-
$.getScript(script, function() {
|
125
|
-
loaded += 1;
|
126
|
-
if (loaded == scripts.length) {
|
127
|
-
prepare_graph();
|
128
|
-
}
|
129
|
-
});
|
130
|
-
});
|
131
|
-
};
|
132
|
-
// make sure that flot is loaded before the other scripts, since some of them depend on it
|
133
|
-
$.getScript("js/jquery.flot.js", function() { load_other_scripts() });
|
134
|
-
</script>
|
data/templates/index.erb
CHANGED
@@ -17,8 +17,9 @@
|
|
17
17
|
<body>
|
18
18
|
|
19
19
|
<iframe allowtransparency="true" id="plantwatchdog" name="plantwatchdog"
|
20
|
-
scrolling="no" frameborder="
|
21
|
-
style="border:
|
22
|
-
src="graph.html?
|
20
|
+
scrolling="no" frameborder="0" border="0"
|
21
|
+
style="border:0;width:750px;height:580px;margin:0;padding:0;"
|
22
|
+
src="graph.html?width=700px&height=400px">
|
23
|
+
</iframe>
|
23
24
|
</body>
|
24
25
|
</html>
|
data/templates/monthly_graph.erb
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
<% years = years_with_data(user);
|
5
5
|
years.each_index {
|
6
6
|
|i| %>
|
7
|
-
<option <%=i == years.size() -1 ? 'selected="selected"' : ""%>><%=years[i].to_s%></option>
|
7
|
+
<option value="<%=years[i].to_s%>" <%=i == years.size() -1 ? 'selected="selected"' : ""%>><%=years[i].to_s%></option>
|
8
8
|
<% } %>
|
9
9
|
</select>
|
10
10
|
<label for="monthly_graph_month">Monat:</label></td>
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: plantwatchdog
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- Plantwatchdog team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-02-
|
12
|
+
date: 2010-02-11 00:00:00 +01:00
|
13
13
|
default_executable: plantwatchdog
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -57,23 +57,6 @@ description: |-
|
|
57
57
|
watchdog listens to data loggers, which continuously upload measurements of
|
58
58
|
plant parameters. Based on that data the watchdog creates reports about the
|
59
59
|
operational status.
|
60
|
-
|
61
|
-
== DESCRIPTION:
|
62
|
-
|
63
|
-
This software is being developed to monitor a photovoltaic generator. We found
|
64
|
-
that it would make sense to keep the domain specific knowledge out of the code
|
65
|
-
and instead provide a DSL to allow users to define their rules. Therefore this
|
66
|
-
software should be useful to monitor any kind of technical plant.
|
67
|
-
|
68
|
-
At the time being the focus of development is to
|
69
|
-
- make it reasonably stable
|
70
|
-
- run per-day aggregations
|
71
|
-
- show intraday and monthly diagrams
|
72
|
-
|
73
|
-
With more data being available the task of finding deviations from regular
|
74
|
-
operation is becoming feasible. Therefore expected values of parameters must
|
75
|
-
be calculated and compared with actual values: the users must be allowed to
|
76
|
-
define a model of the plant.
|
77
60
|
email: mbarchfe@rubyforge.org
|
78
61
|
executables:
|
79
62
|
- plantwatchdog
|
@@ -110,6 +93,7 @@ files:
|
|
110
93
|
- public/images/spinner.gif
|
111
94
|
- public/images/tabs.png
|
112
95
|
- public/js/customflot.js
|
96
|
+
- public/js/excanvas.min.js
|
113
97
|
- public/js/jquery-1.3.2.min.js
|
114
98
|
- public/js/jquery.flot.crosshair.js
|
115
99
|
- public/js/jquery.flot.js
|
@@ -129,7 +113,7 @@ files:
|
|
129
113
|
- templates/index.erb
|
130
114
|
- templates/monthly_graph.erb
|
131
115
|
has_rdoc: true
|
132
|
-
homepage:
|
116
|
+
homepage: http://wiki.github.com/mbarchfe/plantwatchdog
|
133
117
|
licenses: []
|
134
118
|
|
135
119
|
post_install_message:
|
@@ -156,7 +140,7 @@ rubyforge_project: pwd
|
|
156
140
|
rubygems_version: 1.3.5
|
157
141
|
signing_key:
|
158
142
|
specification_version: 3
|
159
|
-
summary:
|
143
|
+
summary: Plantwatchdog monitors your plant.
|
160
144
|
test_files:
|
161
145
|
- test/test_aggregation.rb
|
162
146
|
- test/test_aggregation_methods.rb
|