]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.history/src/org/simantics/history/util/subscription/SamplingFormat.java
2db7ed3a6349f213fb40b1cc27c20d4eb7d5bf02
[simantics/platform.git] / bundles / org.simantics.history / src / org / simantics / history / util / subscription / SamplingFormat.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2011 Association for Decentralized Information Management in
3  * Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.history.util.subscription;
13
14 import java.util.Arrays;
15 import java.util.Comparator;
16
17 import org.simantics.databoard.Bindings;
18 import org.simantics.databoard.Datatypes;
19 import org.simantics.databoard.adapter.AdaptException;
20 import org.simantics.databoard.type.ArrayType;
21 import org.simantics.databoard.type.Component;
22 import org.simantics.databoard.type.Datatype;
23 import org.simantics.databoard.type.NumberType;
24 import org.simantics.databoard.type.RecordType;
25 import org.simantics.databoard.util.Bean;
26 import org.simantics.databoard.util.Limit;
27 import org.simantics.databoard.util.Range;
28
29 /**
30  * This is an utility class for SubscriptionItem.
31  * 
32  * The Simantics Charts samples history data in a specified way. 
33  * One data source item is recorded into multiple history item, each identified
34  * with a named SamplingFormat. This class describes a named sampling format.
35  * 
36  * @author toni.kalajainen@semantum.fi
37  */
38 public class SamplingFormat extends Bean {
39         
40         public static final SamplingFormat[] EMPTY = new SamplingFormat[0];
41         
42         public final static Comparator<Bean> INTERVAL_COMPARATOR = new Comparator<Bean>() {
43                 @Override
44                 public int compare(Bean o1, Bean o2) {
45                         double i1 = (Double) o1.getFieldUnchecked("interval");
46                         double i2 = (Double) o2.getFieldUnchecked("interval");
47                         boolean nan1 = Double.isNaN( i1 );
48                         boolean nan2 = Double.isNaN( i2 );
49                         
50                         if ( nan1 && nan2 ) return 0;
51                         if ( nan1 && !nan2) return -1;
52                         if ( !nan1 && nan2) return 1;
53                         return i1 == i2 ? 0 : ( i1 < i2 ? -1 : 1 );
54                 }
55         };
56         
57         public final static Comparator<SamplingFormat> DEADBAND_COMPARATOR = new Comparator<SamplingFormat>() {
58                 @Override
59                 public int compare(SamplingFormat o1, SamplingFormat o2) {
60                         boolean nan1 = Double.isNaN( o1.deadband );
61                         boolean nan2 = Double.isNaN( o2.deadband );
62                         
63                         if ( nan1 && nan2 ) return 0;
64                         if ( nan1 && !nan2) return -1;
65                         if ( !nan1 && nan2) return 1;
66                         return o1.deadband == o2.deadband ? 0 : ( o1.deadband < o2.deadband ? -1 : 1 );
67                 }
68         };
69
70         /** Identifier, this value is used for separating the time series files */
71         public String formatId;
72         
73         /** 
74          * Describes the format of the packed sample. The sample must be a record.
75          * The record must have any combination of the following named fields.
76          * The field types must one of: byte, integer, long, float, double.
77          * 
78          * time, endTime, value - are mandatory fields.
79          * 
80          *  time      -  Region start time, the time of the 1st included sample
81          *  endTime   -  Region end time, the time of the last included sample
82          *  
83          *  value     -  First value in the region
84          *  lastValue -  Last value in the region
85          *  avg       -  Average value of all included samples
86          *  median    -  Median value of all samples in the region
87          *  min       -  Lowest value in the region
88          *  max       -  Highest value in the region
89          *  
90          *  quality   -  0 = Good, -1 = No value
91          *  count     -  The number of included samples in the region
92          */
93         public Datatype format;
94
95         /** Interval sets the minimum time for a packed sample */
96         public double interval = Double.NaN;
97
98         /** Deadband determines the minimum value change for a packed sample when collecting data */
99         public double deadband = Double.NaN;
100         
101         public SamplingFormat()
102         {               
103         }
104         
105         public SamplingFormat(String id, RecordType sampleType, double interval, double deadband)
106         {
107                 this.formatId = id;
108                 this.format = sampleType;
109                 this.interval = interval;
110                 this.deadband = deadband;
111         }
112         
113         // Sampling format templates
114         public static SamplingFormat simple, allfields, vector;
115         
116         public RecordType record() { return (RecordType) format; }
117
118         static {
119                 simple = new SamplingFormat();
120                 simple.formatId = "Simple";
121                 RecordType format = (RecordType) (simple.format = new RecordType());            
122                 format.addComponent("time", Datatypes.DOUBLE);
123                 format.addComponent("endTime", Datatypes.DOUBLE);
124                 format.addComponent("value", Datatypes.DOUBLE);
125                 format.addComponent("quality", Datatypes.BYTE);
126                 simple.interval = Double.NaN;
127                 simple.deadband = Double.NaN;
128                 
129                 allfields = new SamplingFormat();
130                 allfields.formatId = "Allfields";
131                 allfields.format = new RecordType();
132                 format = (RecordType) (allfields.format = new RecordType());            
133                 format.addComponent("time", Datatypes.DOUBLE);
134                 format.addComponent("endTime", Datatypes.DOUBLE);
135                 
136                 format.addComponent("value", Datatypes.DOUBLE);
137                 format.addComponent("lastValue", Datatypes.DOUBLE);             
138                 format.addComponent("min", Datatypes.DOUBLE);
139                 format.addComponent("max", Datatypes.DOUBLE);
140                 format.addComponent("avg", Datatypes.DOUBLE);
141                 format.addComponent("median", Datatypes.DOUBLE);
142                 
143                 format.addComponent("quality", Datatypes.BYTE);
144                 format.addComponent("count", Datatypes.INTEGER);
145                 allfields.interval = Double.NaN;
146                 allfields.deadband = Double.NaN;                
147                 
148                 vector = new SamplingFormat();
149                 vector.formatId = "Vector";
150                 vector.format = new RecordType();
151                 format = (RecordType) (vector.format = new RecordType());               
152                 format.addComponent("time", Datatypes.FLOAT);
153                 format.addComponent("endTime", Datatypes.FLOAT);
154                 format.addComponent("value", new ArrayType( Datatypes.DOUBLE, Range.between(Limit.inclusive(3), Limit.inclusive(3)) ));
155                 format.addComponent("count", Datatypes.INTEGER);
156                 vector.interval = Double.NaN;
157                 vector.deadband = Double.NaN;
158                 
159         }
160                 
161         @Override
162         public boolean equals(Object obj) {
163                 if ( obj == null ) return false;
164                 if ( obj == this ) return true;
165                 if ( obj instanceof SamplingFormat == false ) return false;
166                 SamplingFormat other = (SamplingFormat) obj;            
167 //              if ( !doubleEquals(interval, other.interval) || !doubleEquals(deadband, other.deadband) ) return false;
168 //              return RecordTypeBinding.equals( other.sampleType, sampleType );
169                 return formatId.equals(other.formatId);
170         }
171         
172         @Override
173         public String toString() {
174                 return "id="+formatId+", "+format +", interval="+interval+", deadband="+deadband;
175         }
176         
177         @Override
178         public SamplingFormat clone() {
179                 try {
180                         SamplingFormat result = new SamplingFormat();
181                         result.formatId = formatId;
182                         result.interval = interval;
183                         result.deadband = deadband;
184                         result.format = (Datatype) Bindings.getBindingUnchecked( Datatype.class ).clone( format );
185                         return result;
186                 } catch (AdaptException e) {
187                         throw new RuntimeException( e );
188                 }
189         }
190
191         public SamplingFormat clone(double interval, double deadband) {
192                 try {
193                         SamplingFormat result = new SamplingFormat();
194                         result.formatId = formatId;
195                         result.interval = interval;
196                         result.deadband = deadband;
197                         result.format = (Datatype) Bindings.getBindingUnchecked( Datatype.class ).clone( format );
198                         return result;
199                 } catch (AdaptException e) {
200                         throw new RuntimeException( e );
201                 }
202         }
203         
204         public SamplingFormat cloneTo(String id, double interval, double deadband) {
205                 try {
206                         SamplingFormat result = new SamplingFormat();
207                         result.formatId = id;
208                         result.interval = interval;
209                         result.deadband = deadband;
210                         result.format = (Datatype) Bindings.getBindingUnchecked( Datatype.class ).clone( format );
211                         return result;
212                 } catch (AdaptException e) {
213                         throw new RuntimeException( e );
214                 }
215         }
216         
217         public SamplingFormat setUnit(String unit) {
218                 for ( int i = 0; i<format.getComponentCount(); i++ ) {
219                         Component c = ((RecordType)format).getComponent(i);
220                         if ( c.name.equals( "value" ) || 
221                                         c.name.equals( "min" ) || 
222                                         c.name.equals( "max" ) || 
223                                         c.name.equals( "avg" ) ||
224                                         c.name.equals( "median" )
225                                         ) {
226                                 if ( c.type instanceof NumberType ) {
227                                         NumberType nt = (NumberType) c.type;
228                                         nt.setUnit( unit );
229                                 }
230                         }
231                 }
232                 return this;
233         }
234         
235         public static void sortByInterval( SamplingFormat[] formats ) {
236                 Arrays.sort(formats, INTERVAL_COMPARATOR);
237         }
238         
239         public static void sortByDeadband( SamplingFormat[] formats ) {
240                 Arrays.sort(formats, DEADBAND_COMPARATOR);
241         }
242         
243 }