001package org.vishia.guiViewCfg;
002
003import java.util.List;
004import java.util.Map;
005import java.util.Queue;
006import java.util.Set;
007import java.util.concurrent.ConcurrentLinkedQueue;
008
009import org.vishia.byteData.ByteDataSymbolicAccessReadConfig;
010import org.vishia.mainCmd.Report;
011
012import org.vishia.byteData.ByteDataSymbolicAccess;
013import org.vishia.gral.base.GralCurveView;
014import org.vishia.gral.base.GralPanelActivated_ifc;
015import org.vishia.gral.base.GralValueBar;
016import org.vishia.gral.base.GralWidget;
017import org.vishia.gral.ifc.GralColor;
018import org.vishia.gral.ifc.GralMng_ifc;
019import org.vishia.gral.ifc.GralSetValue_ifc;
020import org.vishia.gral.ifc.GralUserAction;
021import org.vishia.gral.ifc.GralVisibleWidgets_ifc;
022import org.vishia.gral.ifc.GralWidget_ifc;
023
024
025public class OamShowValues
026{
027
028  
029  /**Version and history
030   * <ul>
031   * <li>2012-02-25 Hartmut new: OamShowValues: with time, grayed if old
032   * <li>2012-02-25 Hartmut new: CurveView: All data have a short timestamp. 
033   * <li>2012-02-21 Hartmut chg Now a curve view can be accessed symbolically.
034   * <li>2010-06-00 Hartmut created
035   * </ul>
036   * 
037   */
038  public static final int version = 0x20120222;
039  
040        final Report log;
041
042        /**Index (fast access) of all variable which are sent from the automation device (contained in the cfg-file). */
043        protected final ByteDataSymbolicAccessReadConfig accessOamVariable;
044
045        boolean dataValid = false;
046        
047        List<GralWidget> widgetsInTab;
048        
049        /**The access to the gui, to change data to show. */
050        protected final GralMng_ifc guiAccess;
051        
052        Set<Map.Entry<String, GralWidget>> fieldsToShow;
053        
054        /**The access to received data for the timestamp as milliseconds after a base year.
055         * It is not null if that variable is contained in the received data description
056         * See {@link #readVariableCfg()}.
057         */
058        ByteDataSymbolicAccess.Variable varTimeMilliSecFromBaseyear;
059        
060        
061  GralColor colorBackValueOk = GralColor.getColor("wh");
062  
063  GralColor colorBackValueOld = GralColor.getColor("lgr");
064  
065        long timeMilliSecFromBaseyear;
066        
067        /**Set in {@link #writeValuesOfTab()} to check newless. */
068        private long timeNow;
069        
070        /**Time for valid values. */
071        private final long milliSecondsOk = 3000; 
072        
073        //private final float[] valueUserCurves = new float[6];  
074
075        public OamShowValues(
076                Report log
077        , GralMng_ifc guiAccess
078        )
079        {
080                this.log = log;
081                this.guiAccess = guiAccess;
082                accessOamVariable = new ByteDataSymbolicAccessReadConfig(log);
083                //assign an empty array, it is necessary for local test or without data receive.
084                //elsewhere a null-pointer-exception is thrown if the tab-pane is shown.
085                //If data are received, this empty array isn't referenced any more.
086                accessOamVariable.assignData(new byte[1500], System.currentTimeMillis());
087                dataValid = true;   //it can be set because empty data are present, see above, use to test.
088        }
089        
090        public boolean readVariableCfg()
091        { int nrofVariable = accessOamVariable.readVariableCfg("GUI/oamVar.cfg");
092          if( nrofVariable>0){
093                log.writeInfoln("success read " + nrofVariable + " variables from file \"GUI/oamVar.cfg\".");
094          } else {
095                log.writeError(" variables not access-able from file \"exe/SES_oamVar.cfg\".");
096          }
097          varTimeMilliSecFromBaseyear = accessOamVariable.getVariable("time_milliseconds1970");
098          return nrofVariable >0;
099        }
100        
101        public void setFieldsToShow(Set<Map.Entry<String, GralWidget>> fields)
102        {
103                fieldsToShow = fields;
104        }
105        
106        /**This routine presents the new received values at the GUI
107         * or saves values in traces.
108         * <br><br>
109         * It is possible that this routine is called more as one time after another. 
110         * That is if more as one data set are transfered in 1 datagram. 
111         * Because that a redraw isn't send here, see {@link #showRedraw()}
112         * 
113         * @param binData
114         * @param nrofBytes
115         * @param from
116         */
117        public void show(byte[] binData, int nrofBytes, int from)
118        {
119                accessOamVariable.assignData(binData, nrofBytes, from, System.currentTimeMillis());
120                dataValid = true;
121                if(varTimeMilliSecFromBaseyear !=null){
122                  //read the time stamp from the record:
123                  timeMilliSecFromBaseyear = varTimeMilliSecFromBaseyear.bytes.getInt(varTimeMilliSecFromBaseyear, 0);
124                } else {
125                  timeMilliSecFromBaseyear = System.currentTimeMillis();
126                }
127                writeValuesOfTab();   //write the values in the current tab, most of them will be received here newly.
128                //TEST TODO:
129                //accessOamVariable.setFloat("ctrl/energyLoadCapac2Diff", checkWithoutNewdata);
130                //current panel:
131                List<GralWidget> listWidgets = guiAccess.getListCurrWidgets();
132                for(GralWidget widgetInfo : listWidgets){
133                        @SuppressWarnings("unused")
134      String sName = widgetInfo.name;
135                }
136                //read all variables which are necessary to show.
137                //writeCurveValues();   //write values for curve scoping
138
139        }
140
141
142        public void showRedraw()
143        {
144                redrawCurveValues();
145        }
146        
147        private void writeField(GralWidget widgetInfo)
148        { String sName = widgetInfo.name;
149                //String sInfo = widgetInfo.sDataPath;
150                String sValue;
151                /*int posFormat = sInfo.indexOf('%');
152                final String sPathValue = posFormat <0 ? sInfo : sInfo.substring(0, posFormat);
153                */
154                String sFormat = widgetInfo.getFormat();
155                ByteDataSymbolicAccess.Variable variable = getVariableFromContentInfo(widgetInfo);
156                //DBbyteMap.Variable variable = accessOamVariable.getVariable(sPathVariable);
157                if(variable == null){
158                        sValue = "XXXXX";
159                } else {
160                  char varType = variable.getTypeChar();
161                if(varType == 'F'){
162                float value= variable.bytes.getFloat(variable, widgetInfo.getDataIx());
163                if(sFormat ==null){
164                if(value < 1.0F && value > -1.0F){ sFormat = "%1.5f"; }
165                else if(value < 100.0F && value > -100.0F){ sFormat = "% 2.3f"; }
166                else if(value < 10000.0F && value > -10000.0F){ sFormat = "% 4.1f"; }
167                else if(value < 100000.0F && value > -100000.0F){ value = value / 1000.0F; sFormat = "% 2.3f k"; }
168                else { sFormat = "%3.3g"; }
169                } 
170                sValue = String.format(sFormat, value);
171        } else if("JISB".indexOf(varType)>=0){
172                        //integer
173                int value = variable.bytes.getInt(variable, widgetInfo.getDataIx());
174                if(sFormat ==null){
175                sFormat = "%d";
176                } 
177                sValue = String.format(sFormat, value);
178        } else {
179                //other format
180                sValue = "?type=" + varType;
181        }
182          GralWidget widg = guiAccess.getWidget(sName); 
183      widg.setText(sValue);
184          //guiAccess.setText(sName, sValue);
185      long timeLastRefresh = variable.getLastRefreshTime();
186      if( (timeNow - timeLastRefresh) < milliSecondsOk){
187        widg.setBackColor(colorBackValueOk, 0);
188      } else {
189        widg.setBackColor(colorBackValueOld, 0);
190      }
191                }
192                
193        }
194        
195        
196        
197        
198
199        /**
200         * 
201         */
202        @Deprecated void writeValuesOfTab()
203        { if(dataValid){
204            timeNow = System.currentTimeMillis();
205          ConcurrentLinkedQueue<GralVisibleWidgets_ifc> listPanels = guiAccess.getVisiblePanels();
206      //GralWidget widgdRemove = null;
207      try{
208        for(GralVisibleWidgets_ifc panel: listPanels){
209          List<GralWidget> widgetsVisible = panel.getWidgetsVisible();
210          if(widgetsVisible !=null) for(GralWidget widget: widgetsVisible){
211            if(widget instanceof GralCurveView){
212              GralCurveView curve = (GralCurveView)widget;
213              List<GralSetValue_ifc> listLines = curve.getTracks();
214              float[] values = new float[listLines.size()];
215              int ixValues = -1;
216              for(GralSetValue_ifc line: listLines){
217                ByteDataSymbolicAccess.Variable variable = getVariableFromContentInfo(line);
218                float value;
219                if(variable !=null){
220                  value= variable.bytes.getFloat(variable, line.getDataIx());
221                } else {
222                  value = 0;
223                }
224                line.setValue(value);
225                values[++ixValues] = value;
226              }
227              curve.setSample(values, (int)timeMilliSecFromBaseyear);
228            } else {
229              String sContentInfo = widget.getDataPath();
230              if(sContentInfo !=null && sContentInfo.length() >0 && widget !=null){
231                stop();
232                if(!callMethod(widget)){
233                  //show value direct
234                  writeField(widget);
235                }
236                //log.reportln(3, "TAB: " + sContentInfo);
237              }
238            }
239          }
240        }
241      } catch(Exception exc){ 
242      }
243      
244          }
245    if(widgetsInTab != null){
246                        for(GralWidget widgetInfo: widgetsInTab){
247                                String sContentInfo = widgetInfo.getDataPath();
248                                if(sContentInfo !=null && sContentInfo.length() >0 && widgetInfo !=null){
249                                        stop();
250                                        if(!callMethod(widgetInfo)){
251                                                //show value direct
252                                                writeField(widgetInfo);
253                                        }
254                                  //log.reportln(3, "TAB: " + sContentInfo);
255                                }
256                        }
257          }
258        }
259        
260        
261        ByteDataSymbolicAccess.Variable getVariableFromContentInfo(GralSetValue_ifc widgetInfo)
262        {
263                ByteDataSymbolicAccess.Variable variable;
264                Object oContentInfo = widgetInfo.getContentInfo();
265                final int[] ixArrayA = new int[1];
266                if(oContentInfo == null){
267                        //first usage:
268                        variable = getVariable(widgetInfo.getDataPath(), ixArrayA);
269                        widgetInfo.setContentInfo(variable);
270                        widgetInfo.setDataIx(ixArrayA[0]);
271                } else if(oContentInfo instanceof ByteDataSymbolicAccess.Variable){
272                        variable = (ByteDataSymbolicAccess.Variable)oContentInfo;
273                } else {
274                        variable = null;  //other info in widget, not a variable.
275                }
276          return variable; 
277        }
278        
279        
280        
281        ByteDataSymbolicAccess.Variable getVariable(String sDataPath, int[] ixArrayA)
282        {
283                final String sPathVariable = ByteDataSymbolicAccess.separateIndex(sDataPath, ixArrayA);
284                ByteDataSymbolicAccess.Variable variable = accessOamVariable.getVariable(sDataPath);
285                return variable;
286        }
287        
288        
289        boolean callMethod(GralWidget widgetInfo)
290        { String sName = widgetInfo.name;
291                String sInfo = widgetInfo.getDataPath();
292                final String sMethodName;
293                final String sVariablePath;
294                final String[] sParam;
295                final int posParanthesis = sInfo.indexOf('(');
296                if(posParanthesis >=0){
297                        sMethodName = sInfo.substring(0, posParanthesis);
298                        sParam = sInfo.substring(posParanthesis+1).split("[,)]");
299                  sVariablePath = sParam[0].trim();
300                } else {
301                        sMethodName = widgetInfo.getShowMethod();
302                        sParam = sInfo.split(",");
303                  sVariablePath = sParam[0];
304                }
305                if(sMethodName != null){
306                        if(sMethodName.equals("setValue")){
307                        setValue(widgetInfo);
308                  }
309                        if(sMethodName.equals("setBar")){
310                        setBar(widgetInfo);
311                  }
312                  else if(sMethodName.equals("uCapMaxRed")){
313                        float value= accessOamVariable.getFloat(sVariablePath);
314                if(value > 120.0F){
315                        guiAccess.setBackColor(sName, 0, 0xffe0e0);
316                } else {
317                        guiAccess.setBackColor(sName, 0, 0xffffff);
318        }
319                String sValue = "" + value;
320                guiAccess.setText(sName, sValue);
321        } 
322                  else if(sMethodName.equals("showBinManValue")){
323                        int value= accessOamVariable.getInt(sVariablePath);
324                int color;
325                if((value & 0x10)==0){
326                        color = 0xffffff;  //white: not set
327                }
328                else { //it is set
329                        int mode = value & 0x60;  //bit 6=manEnable, 5=manMode
330                        switch(mode){
331                        case 0: color=0xff0000; break;     //dark red: error, manual preset but not enabled
332                        case 0x20: color=0xff0000; break;  //dark red: error, manual preset but not enabled
333                        case 0x40: color=0xff0000; break;  //orange: set, enabled or not
334                        case 0x60: color=0xff8000; break;  //orange: set and enabled.
335                        default: color=0xff00ff;    //it isn't used.
336                        }
337                }
338                        guiAccess.setBackColor(widgetInfo, 0, color);
339                        }
340                        else if(sMethodName.equals("showBinEnable")){
341                        int value= accessOamVariable.getInt(sVariablePath);
342                int color;
343                int mode = value & 0x60;  //bit 6=manEnable, 5=manMode
344                switch(mode){
345                case 0: color=0xffffff; break;     //white: no manual
346                case 0x20: color=0xff0000; break;  //dark red: error, manual not enabled, but on
347                case 0x40: color=0x00ff00; break; //green: manual enabled
348                case 0x60: color=0xff8000; break;  //orange: manual enabled and switched.
349                default: color=0xff00ff;    //it isn't used.
350                }
351                        guiAccess.setBackColor(widgetInfo, 0, color);
352                        }
353                        else if(sMethodName.equals("xxxshowBin")){
354                        int value= accessOamVariable.getInt(sVariablePath);
355                int color;
356                        if((value & 0x06) ==0x04) color = 0x00ff00;  //green: manual enable
357                        else if((value & 0x06) ==0x06) color = 0x0000ff;  //blue: manual enable and manual control
358                        else color = 0xffffff;  
359                guiAccess.setBackColor(sName, 0, color);
360                        }
361                        else if(sMethodName.equals("showBool")){
362                                ByteDataSymbolicAccess.Variable variable = accessOamVariable.getVariable(sVariablePath);
363                int color;
364                if(variable !=null){
365                                        int value= accessOamVariable.getInt(variable, -1);
366                        
367                                if((value & 0xff) ==0x0) color = guiAccess.getColorValue(sParam[1].trim());  
368                                else color = guiAccess.getColorValue(sParam[2].trim());  
369                                //guiAccess.setBackColor(sName, 0, color);
370                } else {
371                        color = 0xb0b0b0;  //gray
372                }
373                        if(widgetInfo.whatIs == 'D'){
374                                //a LED
375                                guiAccess.setLed(widgetInfo, color, color);
376                                } else {
377                          guiAccess.setBackColor(widgetInfo, 0, color);
378                                }
379                        }
380                        else if(sMethodName.equals("setColor")){
381                        widgetSetColor(sName, sParam, widgetInfo);
382                        }
383                        else if(sMethodName.equals("showBinFromByte")){
384                                showBinFromByte(widgetInfo);
385                        }
386                  else {
387                        stop();
388                }
389                }
390                return sMethodName !=null;
391        }
392        
393        
394        static class ValueColorAssignment
395        { 
396                static class Element{
397                  int from; int to;
398                  int color;
399                }
400                
401                Element[] data;
402                
403                ValueColorAssignment(String[] sParams, GralMng_ifc guiAccess){
404                        data = new Element[sParams.length-1];
405                        int state = 0;
406                        for(int ii = 1; ii < sParams.length; ++ii){
407                                String sParam = sParams[ii];
408                                int posValue = sParam.indexOf('=')+1;
409                                final String sColor;
410                                final Element data1 = new Element();
411                                if(posValue >1){
412                                        state = Integer.parseInt(sParam.substring(posValue));
413                                        data1.from = state; data1.to = state;
414                                        sColor = sParam.substring(0, posValue-1).trim();
415                                } else {
416                                        sColor = sParam.trim();
417                                        data1.from = Integer.MIN_VALUE; data1.to = Integer.MAX_VALUE;
418                                }
419                                //String[] sColParam = sParams[ii].split("[=:+]");
420                                final int color = guiAccess.getColorValue(sColor);
421        data1.color = color;
422                                data[ii-1] = data1;
423                        }
424                }
425                
426                int getColor(int value){
427                        for(Element element: data){
428                                if(value >= element.from && value <= element.to){
429                                        return element.color;
430                                }
431                        }
432                        return 0x00880088;  //not found, return in for-loop!
433                }
434                
435        }
436        
437        
438        
439        
440        /**Information to a widget, which is colored by the value.
441         */
442        static class ColoredWidget
443        { 
444                ValueColorAssignment valueColorAssignment;
445                
446                ByteDataSymbolicAccess valueContainer;
447                
448                ByteDataSymbolicAccess.Variable variableContainsValue;
449
450                
451                
452                public ColoredWidget(ValueColorAssignment valueColorAssignment, ByteDataSymbolicAccess valueContainerBbyteMap
453                        , ByteDataSymbolicAccess.Variable variableContainsValue)
454                { this.valueColorAssignment = valueColorAssignment;
455                  this.valueContainer = valueContainer;
456                        this.variableContainsValue = variableContainsValue;
457                }
458                
459        }
460                
461        
462        
463        void widgetSetColor(String sName, String[] sParam, GralWidget widgetInfo)
464        { ColoredWidget userData;
465          Object oUserData = widgetInfo.getContentInfo();
466                if(oUserData == null){
467                        //first usage:
468                        ByteDataSymbolicAccess.Variable variable = accessOamVariable.getVariable(sParam[0]);
469                        ValueColorAssignment colorAssignment = new ValueColorAssignment(sParam, guiAccess);
470                        userData = new ColoredWidget(colorAssignment, accessOamVariable, variable);
471                  widgetInfo.setContentInfo(userData);
472                } else {
473                        userData = (ColoredWidget)oUserData;
474                }
475                int color;
476                if(userData.valueContainer !=null){
477                        int value = userData.valueContainer.getInt(userData.variableContainsValue, -1);
478                        color = userData.valueColorAssignment.getColor(value);
479                } else {
480                        color=0xaaaaaa;
481                }
482                guiAccess.setBackColor(sName, -1, color);
483                
484        }
485        
486        
487        void showBinFromByte(GralWidget widgetInfo)
488        { ByteDataSymbolicAccess.Variable variable;
489          Object oUserData = widgetInfo.getContentInfo();
490                if(oUserData == null){
491                        //first usage:
492                        variable = accessOamVariable.getVariable(widgetInfo.getDataPath());
493                        widgetInfo.setContentInfo(variable);
494                } else {
495                        variable = (ByteDataSymbolicAccess.Variable)oUserData;
496                }
497                int value = variable.bytes.getInt(variable, -1);
498                int mode = value & 0x0c;
499                int colorBorder;
500                int colorInner;
501                switch(mode){
502                case 0: colorBorder = colorInner = 0xffffff; break; 
503                case 4: colorBorder = 0xff8000; colorInner = 0xffffff; break;  //incoming value is 1, border is red, used value is 0, inner is white 
504                case 8: colorBorder = 0xffff80; colorInner = 0xff0000; break;  //incoming value is 0, border is yellow to distinguish, used value is 1, inner is red 
505                case 0x0c: colorBorder = colorInner = 0xff8000; break; 
506                default: colorBorder = colorInner = 0;  //not realistic
507                }
508                guiAccess.setLed(widgetInfo, colorBorder, colorInner);
509                
510        }
511        
512        
513        void setValue(GralWidget widgetInfo)
514        { ByteDataSymbolicAccess.Variable variable;
515          Object oUserData = widgetInfo.getContentInfo();
516                if(oUserData == null){
517                        //first usage:
518                        variable = accessOamVariable.getVariable(widgetInfo.getDataPath());
519                        widgetInfo.setContentInfo(variable);
520                } else {
521                        variable = (ByteDataSymbolicAccess.Variable)oUserData;
522                }
523                float value = variable.bytes.getFloat(variable, -1);
524                GralWidget_ifc oWidget = widgetInfo;
525                if(oWidget instanceof GralSetValue_ifc){
526                        GralSetValue_ifc widget = (GralSetValue_ifc) oWidget;
527                        widget.setValue(value);
528                }
529        }
530        
531        
532        void setBar(GralWidget widgetInfo)
533        { ByteDataSymbolicAccess.Variable variable = getVariableFromContentInfo(widgetInfo);
534          if(variable == null){
535                        debugStop();
536                } else {
537                        float value = variable.bytes.getFloat(variable, -1);
538                        
539                        GralWidget_ifc oWidget = widgetInfo;
540                        if(oWidget instanceof GralValueBar){
541                                GralValueBar widget = (GralValueBar) oWidget;
542                                String[] sParam;
543                                if( (sParam = widgetInfo.getShowParam()) != null){
544                                        widget.setBorderAndColors(sParam);
545                                        widgetInfo.clearShowParam();
546                                }
547                                widget.setValue(value);
548                        }
549                }
550        }
551        
552        
553        
554
555
556
557        /**Agent instance to offer the interface for updating the tab in the main TabPanel
558         */
559        public final GralPanelActivated_ifc tabActivatedImpl = new GralPanelActivated_ifc()
560        {
561                @Override       public void panelActivatedGui(List<GralWidget> widgets)
562                {
563                        widgetsInTab = widgets;
564                        writeValuesOfTab();
565                }
566                
567        };
568        
569
570        
571        final GralUserAction actionSetValueTestInInput = new GralUserAction("actionSetValueTestInInput")
572  { @Override
573  public boolean userActionGui(String sCmd, GralWidget widgetInfos, Object... values)
574    { 
575                final int[] ixArrayA = new int[1];
576                ByteDataSymbolicAccess.Variable variable = getVariable(widgetInfos.getDataPath(), ixArrayA);
577                int value = 0; //TODO Integer.parseInt(sParam);
578                if(variable.bytes.lengthData() == 0){
579                        variable.bytes.assignData(new byte[1500], System.currentTimeMillis());
580                }
581                variable.bytes.setFloat(variable, -1, 2.5F* value -120);
582                dataValid = true;
583                writeValuesOfTab();  //to show
584                return true;
585    }
586  };
587
588        
589        private void redrawCurveValues()
590        {
591                guiAccess.redrawWidget("userCurves");
592        }
593        
594
595        
596        
597        
598
599  void stop(){}
600
601  void debugStop(){
602        stop();
603  }
604}