    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}