Nextion display plugin

Moderators: grovkillen, Stuntteam, TD-er

Post Reply
Message
Author
BertB
Normal user
Posts: 1049
Joined: 25 Apr 2015, 14:39

Re: Nextion display plugin

#281 Post by BertB » 15 Jul 2018, 13:12

I use a slightly modified version of your suggested work around, but it seems that idx and value won't modify.

Code: Select all

on E16NEXTION#idx do
  if [E16NEXTION#idx]>=1274  // Touch Events
      SendToHTTP xxx.xxx.xxx.xxx,8080,/json.htm?type=command&param=switchlight&idx=387&switchcmd=Toggle
      E16NEXTION#value = -1
  endif
  E16NEXTION#idx = -1
endon
This is the log:

Code: Select all

1865069 : EVENT: E16Nextion#idx=1274.00
1865078 : [if 1274>=1274]=true
1865080 : ACT  : SendToHTTP xxx.xxx.xxx.xxx,8080,/json.htm?type=command&param=switchlight&idx=387&switchcmd=Toggle
1865097 : Command: sendtohttp
1865122 : HTTP/1.1 200 OK

1865140 : ACT  : E16NEXTION#value = -1
1865154 : Command: e16nextion#value
1865155 : Command unknown
1865160 : ACT  : E16NEXTION#idx = -1
1865173 : Command: e16nextion#idx
1865173 : Command unknown
1865195 : EVENT: E16Nextion#idx=1274.00 Processing time:126 milliSeconds
1865196 : EVENT: E16Nextion#value=0.00
1865223 : EVENT: E16Nextion#value=0.00 Processing time:27 milliSeconds
1865225 : LoadFromFile: config.dat index: 28672 datasize: 724

User avatar
ThomasB
Normal user
Posts: 1065
Joined: 17 Jun 2018, 20:41
Location: USA

Re: Nextion display plugin

#282 Post by ThomasB » 15 Jul 2018, 19:30

@BertB: Thanks for hanging in there! This morning I recompiled with the original release (before hard serial). It has the same interval behavior as the latest V3 beta.

To test your version what method are you using to review the ESP log? The web interface's log has never worked correctly for me, so I need to come up with an alternate method that avoids edits to my home automation system.

Your rule workaround's log looks like it should work because idx has been set to -1. I say that because it matches the log I see on mine.

Code: Select all

19844 : EVENT: NEXTION#idx=20.00
19878 : ACT  : Publish /ESPEZ_Laundry/NEXTION/idx,20
19889 : Command: publish
19923 : ACT  : NEXTION#idx = -1
19934 : Command: nextion#idx
19946 : Command unknown
19981 : EVENT: NEXTION#value=0.00
20096 : Command: |s
20097 : Command unknown
After this there are no future log entries of the NEXTION since idx=-1 and the rule ignores it.

There's some interesting things going on here. In the meantime, do your best to continue with the validation so all the issues can be identified.

Lastly, if you are using the Arduino IDE, what compiler version is it? I would be good for me to know what others are using.

- Thomas

User avatar
ThomasB
Normal user
Posts: 1065
Joined: 17 Jun 2018, 20:41
Location: USA

Re: Nextion display plugin

#283 Post by ThomasB » 15 Jul 2018, 19:53

@BertB: Is the assigned name of your plugin NEXTION or is it E16NEXTION? The reason I ask is that there's a ESP bug that requires the user assigned name for this plugin to always be set to NEXTION or some things will not work correctly. So please change the Plugin name to "NEXTION" plus update the rule file to match this name.

- Thomas

BertB
Normal user
Posts: 1049
Joined: 25 Apr 2015, 14:39

Re: Nextion display plugin

#284 Post by BertB » 15 Jul 2018, 20:41

ThomasB wrote: 15 Jul 2018, 19:53 @BertB: Is the assigned name of your plugin NEXTION or is it E16NEXTION? The reason I ask is that there's a ESP bug that requires the user assigned name for this plugin to always be set to NEXTION or some things will not work correctly. So please change the Plugin name to "NEXTION" plus update the rule file to match this name.

- Thomas
Okay ... did not know that. I named it E16Nextion.

BertB
Normal user
Posts: 1049
Joined: 25 Apr 2015, 14:39

Re: Nextion display plugin

#285 Post by BertB » 15 Jul 2018, 20:48

ThomasB wrote: 15 Jul 2018, 19:30
To test your version what method are you using to review the ESP log? The web interface's log has never worked correctly for me, so I need to come up with an alternate method that avoids edits to my home automation system.
[/qoute]
I agree, the web log is not working correctly. Once the Serial.swap() has been executed, you are virtually blind for debug info.
On the other hand, the V3 version I tested, was with both softserial and hw serial.
There was no difference in 60 sec behaviour, but with softserial you have some proper debug info.

[qoute]
Your rule workaround's log looks like it should work because idx has been set to -1. I say that because it matches the log I see on mine.

Code: Select all

19844 : EVENT: NEXTION#idx=20.00
19878 : ACT  : Publish /ESPEZ_Laundry/NEXTION/idx,20
19889 : Command: publish
19923 : ACT  : NEXTION#idx = -1
19934 : Command: nextion#idx
19946 : Command unknown
19981 : EVENT: NEXTION#value=0.00
20096 : Command: |s
20097 : Command unknown
After this there are no future log entries of the NEXTION since idx=-1 and the rule ignores it.

[/qoute]
I only use the ids of Nextion objects. 60 sec thing was still hapening.
Lastly, if you are using the Arduino IDE, what compiler version is it? I would be good for me to know what others are using.

- Thomas
IDE 1.8.5 with 2.4.1

BertB
Normal user
Posts: 1049
Joined: 25 Apr 2015, 14:39

Re: Nextion display plugin

#286 Post by BertB » 15 Jul 2018, 21:14

I am running V3 again, changed E16Nextion to Nextion and no difference.
My garage light looks like a disco.

BertB
Normal user
Posts: 1049
Joined: 25 Apr 2015, 14:39

Re: Nextion display plugin

#287 Post by BertB » 15 Jul 2018, 21:27

I just used platformio to compile and upload the lot.
No change, 60sec interval still there

User avatar
ThomasB
Normal user
Posts: 1065
Joined: 17 Jun 2018, 20:41
Location: USA

Re: Nextion display plugin

#288 Post by ThomasB » 15 Jul 2018, 21:41

Thanks for all the info. At this point I don't have a solution that would retain the interval timer, but skip sending idx and value data. That's because the main purpose of the interval function is to periodically send these values. Even if we reset them to something else, they will still be sent at each interval.

Your observation that your Nextion version doesn't do it is a mystery to me. When the dust settles, maybe you can dig in deeper to determine how your code skips sending the data at each interval period.

But in the meantime, here is a workaround. Just set the interval to 0 [sec] and it will turn off the interval timer. This will allow you to continue the testing without the garage disco dance.

Code: Select all

//#######################################################################################################
//#######################################################################################################
//################################### Plugin 075: Nextion <info@sensorio.cz>  ###########################
//###################################   Created on the work of  majklovec     ###########################
//###################################    Revisions by BertB and ThomasB       ########################### 
//###################################    Last Revision: July-15-2018 (TB)     ###########################
//#######################################################################################################

#ifdef USES_P075

#include <ESPeasySoftwareSerial.h>

// *****************************************************************************************************
// Defines start here
// *****************************************************************************************************

// Plug-In defines
#define PLUGIN_075
#define PLUGIN_ID_075 75
#define PLUGIN_NAME_075 "Display - Nextion [TEST_V3.1]"
#define PLUGIN_VALUENAME1_075 "idx"
#define PLUGIN_VALUENAME2_075 "value"
#define Nlines 12        // Qty of "optional" user entered Command-Text strings, 64 chars max per line.

// Nextion defines
#define RXBUFFSZ  80     // Local Serial RxD buffer.  
#define TOUCH_BASE 500   // Base offset for 0X65 Touch Event.

// Serial defines
#define B9600    0
#define B38400   1
#define B57600   2
#define B115200  3
#define DEFAULT_BAUD B9600

// Global vars
ESPeasySoftwareSerial *SoftSerial = NULL;
int rxPin = -1;
int txPin = -1;


// *****************************************************************************************************
// PlugIn starts here
// *****************************************************************************************************

boolean Plugin_075(byte function, struct EventStruct *event, String& string) 
{
  boolean success = false;
  static boolean HwSerial = false;
  static boolean AdvHwSerial = false;  
  uint32_t AdvHwBaud = 9600UL;

  switch (function) {

    case PLUGIN_DEVICE_ADD: {
      Device[++deviceCount].Number = PLUGIN_ID_075;
      Device[deviceCount].Type = DEVICE_TYPE_DUAL;
      Device[deviceCount].VType = SENSOR_TYPE_DUAL;
      Device[deviceCount].Ports = 0;
      Device[deviceCount].PullUpOption = true;
      Device[deviceCount].InverseLogicOption = false;
      Device[deviceCount].FormulaOption = false;
      Device[deviceCount].ValueCount = 2;
      Device[deviceCount].SendDataOption = true;
      Device[deviceCount].TimerOption = true;
      Device[deviceCount].TimerOptional = true;             // Allow user to disable interval function.
      Device[deviceCount].GlobalSyncOption = true;
      break;
    }


    case PLUGIN_GET_DEVICENAME: {
      string = F(PLUGIN_NAME_075);
      break;
    }


    case PLUGIN_GET_DEVICEVALUENAMES: {
      strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0],PSTR(PLUGIN_VALUENAME1_075));
      strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1],PSTR(PLUGIN_VALUENAME2_075));
      break;
    }


    case PLUGIN_GET_DEVICEGPIONAMES: {

      AdvHwSerial = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
      rxPin = Settings.TaskDevicePin1[event->TaskIndex];
      txPin = Settings.TaskDevicePin2[event->TaskIndex];

      event->String1 = F("GPIO SS RX &larr; ");
      event->String2 = F("GPIO SS TX &rarr; ");

      if(AdvHwSerial == true) {
        if ((rxPin == 3 && txPin == 1) || (rxPin == 13 && txPin == 15)) {
            event->String1 = F("GPIO HW RX &larr; ");
            event->String2 = F("GPIO HW TX &rarr; ");
        }
      }
      break;
    }


    case PLUGIN_WEBFORM_LOAD: {
      rxPin = Settings.TaskDevicePin1[event->TaskIndex];
      txPin = Settings.TaskDevicePin2[event->TaskIndex];

      if (!((rxPin == 3 && txPin == 1) || (rxPin == 13 && txPin == 15))) { // Hardware Serial Compatible?
        Settings.TaskDevicePluginConfig[event->TaskIndex][0] = false;      // Not HW serial compatible, Reset Check Box.
      }
      
      if (rxPin == 3 && txPin == 1) {                                      // USB Port?
        if(Settings.TaskDevicePluginConfig[event->TaskIndex][0]==false &&  // Hardware serial disabled.
         Settings.TaskDeviceEnabled[event->TaskIndex] == true) {        // Plugin is enabled.
            Settings.TaskDevicePluginConfig[event->TaskIndex][0]=true;     // USB port access uses HW serial, Force set Check Box.
        }
      }

      if (Settings.TaskDevicePluginConfig[event->TaskIndex][0] == false) {  // Softserial mode. 
        Settings.TaskDevicePluginConfig[event->TaskIndex][1] = B9600;       // Reset to 9600 baud.
      }

      addFormSeparator(2);
      addFormSubHeader(F("Enhanced Serial Communication"));
      addFormCheckBox(F("Use Hardware Serial"), F("AdvHwSerial"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]);

      byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
      String options[4];
      options[0] = F("9600");
      options[1] = F("38400");
      options[2] = F("57600");
      options[3] = F("115200");
      
      addFormSelector(F("Baud Rate"), F("plugin_075_baud"), 4, options, NULL, choice);      
      addFormNote(F("Un-check box for Soft Serial communication (low performance mode, 9600 Baud)."));
      addFormNote(F("Hardware Serial is available when the GPIO pins are RX=D7 and TX=D8."));
      addFormNote(F("D8 (GPIO-15) requires a Buffer Circuit (PNP transistor) or ESP boot may fail."));
      addFormNote(F("Do <b>NOT</b> enable the Serial Log file on Tools->Advanced->Serial Port."));
      
//    ** DEVELOPER DEBUG MESSAGE AREA **
//    addFormNote(ExtraTaskSettings.TaskDeviceName); // Debug value.
//    int datax = (int)(Settings.TaskDeviceEnabled[event->TaskIndex]); // Debug value.
//    String Data = "Debug. Plugin Enable State: ";
//    Data += String(datax);
//    addFormNote(Data);


      addFormSubHeader(F("")); // Blank line, vertical space.
      addFormHeader(F("Nextion Command-Text Strings (Optional)"));
      
      char deviceTemplate[Nlines][64];
      LoadCustomTaskSettings(event->TaskIndex, (byte*)&deviceTemplate, sizeof(deviceTemplate));
      for (byte varNr = 0; varNr < Nlines; varNr++) {
        addFormTextBox(String(F("Line ")) + (varNr + 1), String(F("Plugin_075_template")) + (varNr + 1), deviceTemplate[varNr], 64);
      }
      if( Settings.TaskDeviceTimer[event->TaskIndex]==0) {
        addFormNote(F("Interval Timer OFF: Nextion Lines and Values <b>NOT</b> scheduled for updates."));
      }
      else {
        addFormNote(F("Interval Timer On: Nextion Lines and Values scheduled for updates."));
      }


      success = true;
      break;
    }


    case PLUGIN_WEBFORM_SAVE: {

        String argName;

        char deviceTemplate[Nlines][64];
        for (byte varNr = 0; varNr < Nlines; varNr++)
        {
          String arg = F("Plugin_075_template");
          arg += varNr + 1;
          String tmpString = WebServer.arg(arg);
          strncpy(deviceTemplate[varNr], tmpString.c_str(), sizeof(deviceTemplate[varNr])-1);
          deviceTemplate[varNr][63]=0;
        }
        if(ExtraTaskSettings.TaskDeviceName[0]==0) {            // User forgot to enter device name!
            strcpy(ExtraTaskSettings.TaskDeviceName,"NEXTION"); // Give standard name.
        }
        Settings.TaskDevicePluginConfig[event->TaskIndex][0] = isFormItemChecked(F("AdvHwSerial"));
        Settings.TaskDevicePluginConfig[event->TaskIndex][1] = getFormItemInt(F("plugin_075_baud"));
        SaveCustomTaskSettings(event->TaskIndex, (byte*)&deviceTemplate, sizeof(deviceTemplate));

        success = true;
        break;
    }


    case PLUGIN_INIT: {

      AdvHwSerial = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
      uint8_t BaudCode = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
      
      if(BaudCode > B115200) BaudCode = B9600;
      const uint32_t BaudArray[4] = {9600UL, 38400UL, 57600UL, 115200UL};
      AdvHwBaud = BaudArray[BaudCode];

      if (Settings.TaskDevicePin1[event->TaskIndex] != -1) {
        rxPin = Settings.TaskDevicePin1[event->TaskIndex];
      }
      if (Settings.TaskDevicePin2[event->TaskIndex] != -1) {
        txPin = Settings.TaskDevicePin2[event->TaskIndex];
      }

      if (SoftSerial != NULL) { 
        delete SoftSerial;
        SoftSerial = NULL;
      }

      String log = F("NEXTION075 : serial pin config RX:");
      log += rxPin;
      log += F(", TX:");
      log += txPin;
      if(Settings.TaskDeviceEnabled[event->TaskIndex]==true) 
       log += F(", Plugin Enabled");                    // Plugin is enabled.
      else log += F(", Plugin Disabled");
      addLog(LOG_LEVEL_INFO, log);

      if(Settings.TaskDeviceEnabled[event->TaskIndex] == true) { // Plugin is enabled.
      // Hardware serial is RX on 13 and TX on 15 (swapped hw serial)
        if (AdvHwSerial &&  rxPin == 13 && txPin == 15) {
            log = F("NEXTION075 : Using swap hardware serial");
            addLog(LOG_LEVEL_INFO, log);
            HwSerial = true;
            Settings.UseSerial = false;                 // Disable global Serial port.
            Settings.SerialLogLevel = 0;                // Disable logging on serial port.
            Settings.BaudRate = AdvHwBaud;              // Set BaudRate for Nextion.
            Serial.flush();
            Serial.begin(AdvHwBaud);
            Serial.swap();
        }
        // Hardware serial is RX on 3 and TX on 1. USB serial for Nextion IDE (User MCU Input function).
        else if(AdvHwSerial && rxPin == 3 && txPin == 1) {
            log = F("NEXTION075 : Using USB hardware serial");
            addLog(LOG_LEVEL_INFO, log);
            HwSerial = true;
            Settings.UseSerial = false;                 // Disable global Serial port.
            Settings.SerialLogLevel = 0;                // Disable logging on serial port.
            Settings.BaudRate = AdvHwBaud;              // Set BaudRate for Nextion.
            Serial.flush();
            Serial.begin(AdvHwBaud);
        }
        else {
            log = F("NEXTION075 : Using software serial");
            addLog(LOG_LEVEL_INFO, log);
            HwSerial = false;
            if (SoftSerial == NULL) {
                SoftSerial = new ESPeasySoftwareSerial(rxPin, txPin);
            } 
            SoftSerial->begin(9600);
            SoftSerial->flush();
        }
    }
    else {
    }
      success = true;
      break;
    }


    case PLUGIN_READ: {    // Get Plugin's optional command-text strings. Special RSSIBAR bargraph keyword is supported.
        char deviceTemplate[Nlines][64];
        int RssiIndex;
        String newString;
        String tmpString;
        String UcTmpString;
        
        LoadCustomTaskSettings(event->TaskIndex, (byte*)&deviceTemplate, sizeof(deviceTemplate));

        for (byte x = 0; x < Nlines; x++) {
          tmpString = deviceTemplate[x];
          if (tmpString.length()) {
            UcTmpString = deviceTemplate[x];
            UcTmpString.toUpperCase();
            RssiIndex = UcTmpString.indexOf(F("RSSIBAR"));  // RSSI bargraph Keyword found, wifi value in dBm.
            if(RssiIndex >= 0) {
              int barVal;
              newString = tmpString.substring(0, RssiIndex);
              int nbars = WiFi.RSSI();
              if (nbars < -100 || nbars >= 0)
                 barVal=0;
              else if (nbars >= -100 && nbars < -95)
                 barVal=5;
              else if (nbars >= -95 && nbars < -90)
                 barVal=10;
              else if (nbars >= -90 && nbars < -85)
                 barVal=20;
              else if (nbars >= -85 && nbars < -80)
                 barVal=30;
              else if (nbars >= -80 && nbars < -75)
                 barVal=45;
              else if (nbars >= -75 && nbars < -70)
                 barVal=60;
              else if (nbars >= -70 && nbars < -65)
                 barVal=70;
              else if (nbars >= -65 && nbars < -55)
                 barVal=80;
              else if (nbars >= -55 && nbars < -50)
                 barVal=90;
              else if (nbars >= -50)
                 barVal=100;

              newString += String(barVal,DEC);
            }
            else {
              newString = parseTemplate(tmpString, 0);
            }

            sendCommand(newString.c_str(), HwSerial);
          }
        }

        success = true;
        break;
    }


    case PLUGIN_WRITE: {
        String tmpString = string;
        int argIndex = tmpString.indexOf(',');
        if (argIndex) tmpString = tmpString.substring(0, argIndex);

//      String log = F("TaskDeviceName : ");
//      log += ExtraTaskSettings.TaskDeviceName;
//      addLog(LOG_LEVEL_INFO, log);

        if (tmpString.equalsIgnoreCase(F("NEXTION"))) {
//      if (tmpString.equalsIgnoreCase(ExtraTaskSettings.TaskDeviceName)) { // Use Plugin Name as command ID name.
            argIndex = string.indexOf(',');
            tmpString = string.substring(argIndex + 1);
            sendCommand(tmpString.c_str(), HwSerial);

            String log = F("NEXTION075 : WRITE, ");
            log += F("Command is ");
            log += (tmpString.c_str());
            addLog(LOG_LEVEL_INFO, log);

            success = true;                             // Set true only if plugin found a command to execute.
        }
        break;
    }


    case PLUGIN_EXIT: {
      if (SoftSerial) {
        delete SoftSerial;
        SoftSerial=NULL;
      }

      if(HwSerial) {
        HwSerial = false;
        Settings.UseSerial		= DEFAULT_USE_SERIAL;
        Settings.BaudRate		= DEFAULT_SERIAL_BAUD;
        Serial.flush();
        Serial.begin(DEFAULT_SERIAL_BAUD);              // Restart Serial Logging with default baud.
      }
      break;
    }


    case PLUGIN_ONCE_A_SECOND: {
        success = true;
        break;
    }

    
    case PLUGIN_TEN_PER_SECOND: {
      uint16_t i;
      uint8_t c;
      uint8_t charCount;
      String log;
      String Vidx;
      String Nvalue;
      String Svalue;
      String Nswitch;
      char __buffer[RXBUFFSZ+1];

      if(HwSerial) charCount = Serial.available();      // Prime the Hardware Serial engine.
      else charCount = SoftSerial->available();         // Prime the Soft Serial engine.

      while (charCount) {                               // This is the serial engine. It processes the serial Rx stream.
        if(HwSerial) c = Serial.read();
        else c = SoftSerial->read();

        if (c == 0x65) {
          if (charCount < 6) delay((5/(AdvHwBaud/9600))+1); // Let's wait for a few more chars to arrive.

          if (HwSerial) charCount = Serial.available();
          else charCount = SoftSerial->available();
          if (charCount >= 6) {
            __buffer[0] = c;
            for (i = 1; i < 7; i++) {
                if(HwSerial) __buffer[i] = Serial.read();
                else __buffer[i] = SoftSerial->read();
            }

            __buffer[i] = 0x00;

            if (0xFF == __buffer[4] && 0xFF == __buffer[5] && 0xFF == __buffer[6]) {
              UserVar[event->BaseVarIndex] = (__buffer[1] * 256) + __buffer[2] + TOUCH_BASE;
              UserVar[event->BaseVarIndex + 1] = __buffer[3];
              log = F("NEXTION075 : code: ");
              log += __buffer[1];
              log += ",";
              log += __buffer[2];
              log += ",";
              log += __buffer[3];
              addLog(LOG_LEVEL_INFO, log);

              sendData(event);
            }
          }
        } 
        else {
          if (c == '|') {
            __buffer[0] = c;

            if (charCount < 8) delay((9/(AdvHwBaud/9600))+1); // Let's wait for more chars to arrive.
            else delay((3/(AdvHwBaud/9600))+1);               // Short wait for tardy chars.
            if (HwSerial) charCount = Serial.available();
            else charCount = SoftSerial->available();

            if(HwSerial) {
                i = 1;            
                while (Serial.available() > 0 && i<RXBUFFSZ) {  // Copy global serial buffer to local buffer.
                  __buffer[i] = Serial.read();
                  if (__buffer[i]==0x0a || __buffer[i]==0x0d) break;
                  i++;
                }
            }
            else {
                i = 1;            
                while (SoftSerial->available() > 0 && i<RXBUFFSZ) {  // Copy global serial buffer to local buffer.
                  __buffer[i] = SoftSerial->read();
                  if (__buffer[i]==0x0a || __buffer[i]==0x0d) break;
                  i++;
                }
            }

            __buffer[i] = 0x00;
            
            String tmpString = __buffer;
            log = F("NEXTION075 : code: ");
            log += tmpString;
            addLog(LOG_LEVEL_INFO, log);

            int argIndex = tmpString.indexOf(F(",i"));
            int argEnd = tmpString.indexOf(',', argIndex + 1);
            if (argIndex) Vidx = tmpString.substring(argIndex + 2,argEnd);

            boolean GotPipeCmd = false;
            switch (__buffer[1]){
              case 'u':
                GotPipeCmd = true;
                argIndex = argEnd;
                argEnd = tmpString.indexOf(',',argIndex + 1);
                if (argIndex) Nvalue = tmpString.substring(argIndex + 2,argEnd);
                argIndex = argEnd;
                argEnd = tmpString.indexOf(0x0a);
                if (argIndex) Svalue = tmpString.substring(argIndex + 2,argEnd);
                break;
              case 's':
                GotPipeCmd = true;
                argIndex = argEnd;
                argEnd = tmpString.indexOf(0x0a);
                if (argIndex) Nvalue = tmpString.substring(argIndex + 2,argEnd);
                if (Nvalue == F("On")) Svalue='1';
                if (Nvalue == F("Off")) Svalue='0';
                break;
            }

            if (GotPipeCmd) {
                UserVar[event->BaseVarIndex] = Vidx.toFloat();
                UserVar[event->BaseVarIndex+1] = Svalue.toFloat();
                sendData(event);
                log = F("NEXTION075 : Pipe Command Sent: ");
                log += __buffer;
                log += UserVar[event->BaseVarIndex];
            }
            else {
                log = F("NEXTION075 : Unknown Pipe Command, skipped");
            }
            addLog(LOG_LEVEL_INFO, log);
          }
        }
        if(HwSerial) charCount = Serial.available();
        else charCount = SoftSerial->available();
      }

      success = true;
      break;
    }
  }
  return success;
}


void sendCommand(const char *cmd, boolean SerialHW) 
{
    if(SerialHW) {
        Serial.print(cmd);
        Serial.write(0xff);
        Serial.write(0xff);
        Serial.write(0xff);
    }
    else {
        SoftSerial->print(cmd);
        SoftSerial->write(0xff);
        SoftSerial->write(0xff);
        SoftSerial->write(0xff);
    }
}

#endif // USES_P075
- Thomas

BertB
Normal user
Posts: 1049
Joined: 25 Apr 2015, 14:39

Re: Nextion display plugin

#289 Post by BertB » 15 Jul 2018, 22:25

Thanks I will try it tomorrow.

BertB
Normal user
Posts: 1049
Joined: 25 Apr 2015, 14:39

Re: Nextion display plugin

#290 Post by BertB » 15 Jul 2018, 23:24

What I do not understand is this:
When I push a button, this causes serial data to flow to the serial port. This causes an event, where idx and value are being filled.
When this event occurs it triggers a rule.

Once every 60 seconds, idx and value are read and (in my case) send to a dummy device in Domoticz.
Why does this lead to another serial event and trigger the rule?

User avatar
ThomasB
Normal user
Posts: 1065
Joined: 17 Jun 2018, 20:41
Location: USA

Re: Nextion display plugin

#291 Post by ThomasB » 16 Jul 2018, 00:15

@BertB: At each timer interval the two "Values" data (idx and value) will be sent again. Without new data from the Nextion they default to the previous values.

This is the same as any other device that has defined Values and use a interval timer. For example, a Switch device will send the switch state at each interval. Even if the switch state has not been altered, the previous data will be sent again at the interval. That is the purpose of the interval function.

In your example the originating idx was a 1274 touch event. After the initial send, it is resent at the interval time. It is then processed by the rule file, which activates your light again. The "-1" workaround could fix this (because the rule would be ignored when idx is -1), but for some reason that trick is not working for you.

The new code will allow you turn off the interval timer and avoid the 60 second repeat. If there are alternate methods then we can incorporate them too.

- Thomas

User avatar
ThomasB
Normal user
Posts: 1065
Joined: 17 Jun 2018, 20:41
Location: USA

Re: Nextion display plugin

#292 Post by ThomasB » 16 Jul 2018, 04:16

I installed a syslog server on my NAS and can now send ESP log files to it. This allowed me to see what your code is doing. It has the same interval behavior as the original Nextion release and the latest V3 code.

Using your code here's the log output of event idx 21 and value 0. This log was captured several minutes after the Nextion sent the idx code 21 to the ESP. In this example the Nextion interval is 10 sec so the repeated data appears often. I also removed the -1 masking trick from the rule file so that the MQTT publish is seen too.

Code: Select all

18:39:33	EspEasy: EVENT: NEXTION#idx=21.00
18:39:33	EspEasy: WD   : Uptime 22 ConnectFailures 0 FreeMem 14384
18:39:33	EspEasy: LoopStats: shortestLoop: 49 longestLoop: 2083484 avgLoopDuration: 89.40 systemTimerDuration: 19.35 systemTimerCalls: 31 loopCounterMax: 612244 loopCounterLast: 328986 countFindPluginId: 0
18:39:23	EspEasy: EVENT: RSSI#signal=-75.00
18:39:23	EspEasy: SYS  : -75.00
18:39:23	EspEasy: EVENT: NEXTION#value=0.00
18:39:23	EspEasy: Command: publish
18:39:23	EspEasy: ACT  : Publish /ESPEZ_Laundry/NEXTION/idx,21
18:39:23	EspEasy: EVENT: NEXTION#idx=21.00
18:39:13	EspEasy: EVENT: NEXTION#value=0.00
18:39:13	EspEasy: Command: publish
18:39:13	EspEasy: ACT  : Publish /ESPEZ_Laundry/NEXTION/idx,21
18:39:13	EspEasy: EVENT: NEXTION#idx=21.00
18:39:03	EspEasy: EVENT: RSSI#signal=-76.00
18:39:03	EspEasy: SYS  : -76.00
18:39:03	EspEasy: EVENT: RUNTIME#days=0.01
18:39:03	EspEasy: SYS  : 21.00
18:39:03	EspEasy: EVENT: NEXTION#value=0.00
18:39:03	EspEasy: Command: publish
18:39:03	EspEasy: ACT  : Publish /ESPEZ_Laundry/NEXTION/idx,21
18:39:03	EspEasy: EVENT: NEXTION#idx=21.00
18:39:03	EspEasy: WD   : Uptime 21 ConnectFailures 0 FreeMem 14384
18:39:03	EspEasy: LoopStats: shortestLoop: 49 longestLoop: 2083484 avgLoopDuration: 88.74 systemTimerDuration: 20.94 systemTimerCalls: 31 loopCounterMax: 612244 loopCounterLast: 331381 countFindPluginId: 0
18:39:00	EspEasy: EVENT: Clock#Time=Sun,18:39
18:38:53	EspEasy: EVENT: NEXTION#value=0.00
18:38:53	EspEasy: Command: publish
18:38:53	EspEasy: ACT  : Publish /ESPEZ_Laundry/NEXTION/idx,21
18:38:53	EspEasy: EVENT: NEXTION#idx=21.00
18:38:43	EspEasy: EVENT: RSSI#signal=-77.00
18:38:43	EspEasy: SYS  : -77.00
18:38:43	EspEasy: EVENT: NEXTION#value=0.00
18:38:43	EspEasy: Command: publish
18:38:43	EspEasy: ACT  : Publish /ESPEZ_Laundry/NEXTION/idx,21
18:38:43	EspEasy: EVENT: NEXTION#idx=21.00
18:38:33	EspEasy: EVENT: NEXTION#value=0.00
18:38:33	EspEasy: Command: publish
18:38:33	EspEasy: ACT  : Publish /ESPEZ_Laundry/NEXTION/idx,21
18:38:33	EspEasy: EVENT: NEXTION#idx=21.00
18:38:33	EspEasy: WD   : Uptime 21 ConnectFailures 0 FreeMem 14384
18:38:33	EspEasy: LoopStats: shortestLoop: 49 longestLoop: 2083484 avgLoopDuration: 89.47 systemTimerDuration: 19.65 systemTimerCalls: 31 loopCounterMax: 612244 loopCounterLast: 328733 countFindPluginId: 0
18:38:23	EspEasy: EVENT: RSSI#signal=-77.00
18:38:23	EspEasy: SYS  : -77.00
18:38:23	EspEasy: EVENT: NEXTION#value=0.00
18:38:23	EspEasy: Command: publish
18:38:23	EspEasy: ACT  : Publish /ESPEZ_Laundry/NEXTION/idx,21
18:38:23	EspEasy: EVENT: NEXTION#idx=21.00
I don't use Nextion Touch events because I prefer a different numerical code for On and Off commands. This, along with my home automation's On Change rule, eliminates any worries of repeated data.

There may be a way to suppress the idx and val from the interval timer (and retain the Lines function), but that will require some research.

- Thomas

BertB
Normal user
Posts: 1049
Joined: 25 Apr 2015, 14:39

Re: Nextion display plugin

#293 Post by BertB » 16 Jul 2018, 06:59

ThomasB wrote: 16 Jul 2018, 00:15

In your example the originating idx was a 1274 touch event. After the initial send, it is resent at the interval time. It is then processed by the rule file, which activates your light again.
That is exactly my point. Why would a timer interval invoke a rule that should be event driven by the switch. In my case, the timer sends the values to a domoticz waste bin.

BertB
Normal user
Posts: 1049
Joined: 25 Apr 2015, 14:39

Re: Nextion display plugin

#294 Post by BertB » 16 Jul 2018, 07:03

ThomasB wrote: 16 Jul 2018, 04:16 I installed a syslog server on my NAS and can now send ESP log files to it. This allowed me to see what your code is doing. It has the same interval behavior as the original Nextion release and the latest V3 code.

So weird as on my wemos my latest code does not show the 60 sec on off behaviour. Tonite i will start from scrap..

User avatar
ThomasB
Normal user
Posts: 1065
Joined: 17 Jun 2018, 20:41
Location: USA

Re: Nextion display plugin

#295 Post by ThomasB » 16 Jul 2018, 07:51

That is exactly my point. Why would a timer interval invoke a rule that should be event driven by the switch. In my case, the timer sends the values to a domoticz waste bin.
I'm just the messenger, so don't shoot me. It's the behavior of the interval timer. It can be turned off now, so you should be good to go.
- Thomas

BertB
Normal user
Posts: 1049
Joined: 25 Apr 2015, 14:39

Re: Nextion display plugin

#296 Post by BertB » 16 Jul 2018, 14:10

ThomasB wrote: 16 Jul 2018, 07:51 I'm just the messenger, so don't shoot me.

- Thomas
Most certainly not. :-)

BertB
Normal user
Posts: 1049
Joined: 25 Apr 2015, 14:39

Re: Nextion display plugin

#297 Post by BertB » 16 Jul 2018, 23:48

So far, the plugin is running just fine.

User avatar
ThomasB
Normal user
Posts: 1065
Joined: 17 Jun 2018, 20:41
Location: USA

Re: Nextion display plugin

#298 Post by ThomasB » 17 Jul 2018, 02:19

@BertB: Thanks for checking it. Let me know if any other issues come up.

@Everyone: Would be great if there were others that could try it out. More feedback would be helpful.

I found a CustomTaskSettings byte storage mistake in the Nextion Plugin. But fixing it did not solve the crash/brick when the plugin is deleted and system rebooted. I see an Exception (28) in the logs right after the rule file tries to process a Nextion statement.

The workaround is to delete Nextion rules before deleting the plugin. If I don't do that then the recovery is to reflash with full memory reset. The problem comes and goes, depending on its mood.

The original Nextion plugin (without hardware serial) experiences the problem too. My gut feeling is that it has nothing to do with the Nextion Plugin.

- Thomas

User avatar
ManS-H
Normal user
Posts: 281
Joined: 27 Dec 2015, 11:26
Location: the Netherlands

Re: Nextion display plugin

#299 Post by ManS-H » 17 Jul 2018, 10:43

Hello,
I have a question about the Nextion display, maybe not the right place to ask but what version of the Nextion is most common for this plugin.
On the Itead site i see two versions, the Basic Model and the Enhanced Model.

BertB
Normal user
Posts: 1049
Joined: 25 Apr 2015, 14:39

Re: Nextion display plugin

#300 Post by BertB » 17 Jul 2018, 11:57

I only have tested and developed with the Basic model.

waspie
Normal user
Posts: 127
Joined: 09 Feb 2017, 19:35

Re: Nextion display plugin

#301 Post by waspie » 17 Jul 2018, 16:13

ThomasB wrote: 17 Jul 2018, 02:19 @BertB: Thanks for checking it. Let me know if any other issues come up.

@Everyone: Would be great if there were others that could try it out. More feedback would be helpful.

I found a CustomTaskSettings byte storage mistake in the Nextion Plugin. But fixing it did not solve the crash/brick when the plugin is deleted and system rebooted. I see an Exception (28) in the logs right after the rule file tries to process a Nextion statement.

The workaround is to delete Nextion rules before deleting the plugin. If I don't do that then the recovery is to reflash with full memory reset. The problem comes and goes, depending on its mood.

The original Nextion plugin (without hardware serial) experiences the problem too. My gut feeling is that it has nothing to do with the Nextion Plugin.

- Thomas
I deployed most of my nextions so far working within the constraints of the plugin prior to H/W serial. I think H/W serial with a reliable serial message will allow me to cut down my rules (one nextion I have all 4 rules almost completely full!).

If I understand correctly I could have if/else/whatever statements on the nextion and the state of internal variables would determine what exactly gets sent to the ESP (on/off/whatever) vs button pressed and then I have to determine the state based on stored dummy values which eats up valuable rule characters.
Last edited by waspie on 17 Jul 2018, 16:17, edited 1 time in total.

waspie
Normal user
Posts: 127
Joined: 09 Feb 2017, 19:35

Re: Nextion display plugin

#302 Post by waspie » 17 Jul 2018, 16:17

ManS-H wrote: 17 Jul 2018, 10:43 Hello,
I have a question about the Nextion display, maybe not the right place to ask but what version of the Nextion is most common for this plugin.
On the Itead site i see two versions, the Basic Model and the Enhanced Model.
Enhanced has more memory and faster CPU. Most likely not necessary for what most of us do here. The faster CPU means pages or images refresh faster ( I assume). The basic model refreshes the page plenty fast enough. It's noticeable, but no problem whatsoever. I only mean you can see it happen but it is not a problem.

More memory could be useful depending on how many images you use. I think with my 3.5" I have 5 pages ( and 2 images/page) and I was using 3MB so I got kind of close to filling one. I could reduce the quality probably and it wouldn't make any difference visually.

I see no real reason to get the enhanced version

User avatar
ThomasB
Normal user
Posts: 1065
Joined: 17 Jun 2018, 20:41
Location: USA

Re: Nextion display plugin

#303 Post by ThomasB » 17 Jul 2018, 19:03

I have a question about the Nextion display, maybe not the right place to ask but what version of the Nextion is most common for this plugin.
I use the basic model.
If I understand correctly I could have if/else/whatever statements on the nextion and the state of internal variables would determine what exactly gets sent to the ESP (on/off/whatever) vs button pressed and {snip}.
That's how I do it. I don't use the Touch Event Send Component ID at all. Instead, in the button's Touch Event code space I use if/else and Nextion vars to assign a different idx value for button On and Off while emulating a push on-off toggling switch. Each touch button gets a pair of unique codes to do this. Some buttons have more codes to represent different variations of the button so that one button can do additional things.

Below is example Nextion code to a simple touch button that is a push-on / push off switch. The Send Component ID checkbox remains unchecked. Instead, the customized Touch Press Event assigns two different idx values (20 & 21). Not shown are many other if/else actions, such as change picture graphics, text, and colors for the on/off states:

Code: Select all

if(page0.va_SwState.val==0)   // Switch is currently off
{
    page0.va_SwState.val=1    // Toggle state (turn it on)
    print "|s,i21,sOff"       // Send idx to ESP MQTT rule
    printh 0a
}else
{
    page0.va_SwState.val=0   // Toggle state (turn it off)
    print "|s,i20,sOff"      // Send idx to ESP for MQTT rule
    printh 0a
}
This method simplifies ESP and home automation rules by pushing some low level work onto the Nextion.

- Thomas

waspie
Normal user
Posts: 127
Joined: 09 Feb 2017, 19:35

Re: Nextion display plugin

#304 Post by waspie » 18 Jul 2018, 02:52

ThomasB wrote: 17 Jul 2018, 19:03
I have a question about the Nextion display, maybe not the right place to ask but what version of the Nextion is most common for this plugin.
I use the basic model.
If I understand correctly I could have if/else/whatever statements on the nextion and the state of internal variables would determine what exactly gets sent to the ESP (on/off/whatever) vs button pressed and {snip}.
That's how I do it. I don't use the Touch Event Send Component ID at all. Instead, in the button's Touch Event code space I use if/else and Nextion vars to assign a different idx value for button On and Off while emulating a push on-off toggling switch. Each touch button gets a pair of unique codes to do this. Some buttons have more codes to represent different variations of the button so that one button can do additional things.

Below is example Nextion code to a simple touch button that is a push-on / push off switch. The Send Component ID checkbox remains unchecked. Instead, the customized Touch Press Event assigns two different idx values (20 & 21). Not shown are many other if/else actions, such as change picture graphics, text, and colors for the on/off states:

Code: Select all

if(page0.va_SwState.val==0)   // Switch is currently off
{
    page0.va_SwState.val=1    // Toggle state (turn it on)
    print "|s,i21,sOff"       // Send idx to ESP MQTT rule
    printh 0a
}else
{
    page0.va_SwState.val=0   // Toggle state (turn it off)
    print "|s,i20,sOff"      // Send idx to ESP for MQTT rule
    printh 0a
}
This method simplifies ESP and home automation rules by pushing some low level work onto the Nextion.

- Thomas
damn, too bad i had a bunch of boards made using some guy's design off of home assistant (HASP). the tx/rx are wired to d4/d7 (i think, i dont remember)
https://github.com/aderusha/HASwitchPla ... master/PCB

BertB
Normal user
Posts: 1049
Joined: 25 Apr 2015, 14:39

Re: Nextion display plugin

#305 Post by BertB » 18 Jul 2018, 08:51

I designed this communication to put more of the thinking in the Nextion, but it also more or less causes more often changes in the Nextion.
This is not very user friendly while there is no easy way to update Nextion.

Therefore I mostly use the id's and let Rules and Domoticz do the thinking.
The drawback here is the shortage of rules space, but the gain is simplicity, agility and beter feedback.

User avatar
ManS-H
Normal user
Posts: 281
Joined: 27 Dec 2015, 11:26
Location: the Netherlands

Re: Nextion display plugin

#306 Post by ManS-H » 18 Jul 2018, 12:17

Thank for the info about the Nextion display.

User avatar
ThomasB
Normal user
Posts: 1065
Joined: 17 Jun 2018, 20:41
Location: USA

Re: Nextion display plugin

#307 Post by ThomasB » 19 Jul 2018, 01:52

@BertB: I have been working on the interval issue. There is a chance that this new beta release is what you want:

Code: Select all

//#######################################################################################################
//#######################################################################################################
//################################### Plugin 075: Nextion <info@sensorio.cz>  ###########################
//###################################   Created on the work of  majklovec     ###########################
//###################################    Revisions by BertB and ThomasB       ########################### 
//###################################    Last Revision: July-18-2018 (TB)     ###########################
//#######################################################################################################

#ifdef USES_P075

#include <ESPeasySoftwareSerial.h>

// *****************************************************************************************************
// Defines start here
// *****************************************************************************************************

// Plug-In defines
#define PLUGIN_075
#define PLUGIN_ID_075 75
#define PLUGIN_NAME_075 "Display - Nextion [TEST_V3.2]"
#define PLUGIN_VALUENAME1_075 "idx"
#define PLUGIN_VALUENAME2_075 "value"

// Configuration Settings. Custom Configuration Memory must be less than 512 Bytes!
//#define Nlines 12       // Qty of "optional" user entered Command-Text strings. 
//#define Lenlines 64     // Length of "optional" user entered Command-Text strings.
#define Nlines 8          // Qty of "optional" user entered Command-Text strings. 
#define Lenlines 48       // Length of "optional" user entered Command-Text strings.
char deviceTemplate[Nlines][Lenlines]; 

// Nextion defines
#define RXBUFFSZ  80     // Local Serial RxD buffer.  
#define TOUCH_BASE 500   // Base offset for 0X65 Touch Event Component ID.

// Serial defines
#define B9600    0  
#define B38400   1
#define B57600   2
#define B115200  3
#define DEFAULT_BAUD B9600

// Global vars
ESPeasySoftwareSerial *SoftSerial = NULL;
int rxPin = -1;
int txPin = -1;


// *****************************************************************************************************
// PlugIn starts here
// *****************************************************************************************************

boolean Plugin_075(byte function, struct EventStruct *event, String& string) 
{
  boolean success = false;
  static boolean HwSerial = false;
  static boolean AdvHwSerial = false;  
  uint32_t AdvHwBaud = 9600UL;

  switch (function) {

    case PLUGIN_DEVICE_ADD: {
      Device[++deviceCount].Number = PLUGIN_ID_075;
      Device[deviceCount].Type = DEVICE_TYPE_DUAL;
      Device[deviceCount].VType = SENSOR_TYPE_DUAL;
      Device[deviceCount].Ports = 0;
      Device[deviceCount].PullUpOption = true;
      Device[deviceCount].InverseLogicOption = false;
      Device[deviceCount].FormulaOption = false;
      Device[deviceCount].ValueCount = 2;
      Device[deviceCount].SendDataOption = true;
      Device[deviceCount].TimerOption = true;
      Device[deviceCount].TimerOptional = true;             // Allow user to disable interval function.
      Device[deviceCount].GlobalSyncOption = true;
      break;
    }


    case PLUGIN_GET_DEVICENAME: {
      string = F(PLUGIN_NAME_075);
      break;
    }


    case PLUGIN_GET_DEVICEVALUENAMES: {
      strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0],PSTR(PLUGIN_VALUENAME1_075));
      strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1],PSTR(PLUGIN_VALUENAME2_075));
      break;
    }


    case PLUGIN_GET_DEVICEGPIONAMES: {

      AdvHwSerial = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
      rxPin = Settings.TaskDevicePin1[event->TaskIndex];
      txPin = Settings.TaskDevicePin2[event->TaskIndex];

      event->String1 = F("GPIO SS RX &larr; ");
      event->String2 = F("GPIO SS TX &rarr; ");

      if(AdvHwSerial == true) {
        if ((rxPin == 3 && txPin == 1) || (rxPin == 13 && txPin == 15)) {
            event->String1 = F("GPIO HW RX &larr; ");
            event->String2 = F("GPIO HW TX &rarr; ");
        }
      }
      break;
    }


    case PLUGIN_WEBFORM_LOAD: {
      rxPin = Settings.TaskDevicePin1[event->TaskIndex];
      txPin = Settings.TaskDevicePin2[event->TaskIndex];

      if (!((rxPin == 3 && txPin == 1) || (rxPin == 13 && txPin == 15))) { // Hardware Serial Compatible?
        Settings.TaskDevicePluginConfig[event->TaskIndex][0] = false;      // Not HW serial compatible, Reset Check Box.
      }
      
      if (rxPin == 3 && txPin == 1) {                                      // USB Port?
        if(Settings.TaskDevicePluginConfig[event->TaskIndex][0]==false &&  // Hardware serial disabled.
         Settings.TaskDeviceEnabled[event->TaskIndex] == true) {           // Plugin is enabled.
            Settings.TaskDevicePluginConfig[event->TaskIndex][0]=true;     // USB port access uses HW serial, Force set Check Box.
        }
      }

      if (Settings.TaskDevicePluginConfig[event->TaskIndex][0] == false) { // Softserial mode. 
        Settings.TaskDevicePluginConfig[event->TaskIndex][1] = B9600;      // Reset to 9600 baud.
      }

      addFormSeparator(2);
      addFormSubHeader(F("Enhanced Serial Communication"));
      addFormCheckBox(F("Use Hardware Serial"), F("AdvHwSerial"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]);

      byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
      String options[4];
      options[0] = F("9600");
      options[1] = F("38400");
      options[2] = F("57600");
      options[3] = F("115200");
      
      addFormSelector(F("Baud Rate"), F("plugin_075_baud"), 4, options, NULL, choice);      
      addFormNote(F("Un-check box for Soft Serial communication (low performance mode, 9600 Baud)."));
      addFormNote(F("Hardware Serial is available when the GPIO pins are RX=D7 and TX=D8."));
      addFormNote(F("D8 (GPIO-15) requires a Buffer Circuit (PNP transistor) or ESP boot may fail."));
      addFormNote(F("Do <b>NOT</b> enable the Serial Log file on Tools->Advanced->Serial Port."));
      
//    ** DEVELOPER DEBUG MESSAGE AREA **
//    addFormNote(ExtraTaskSettings.TaskDeviceName);    // Debug value.
//    int datax = (int)(Settings.TaskDeviceEnabled[event->TaskIndex]); // Debug value.
//    String Data = "Debug. Plugin Enable State: ";
//    Data += String(datax);
//    addFormNote(Data);


      addFormSubHeader(F("")); // Blank line, vertical space.
      addFormHeader(F("Nextion Command-Text Strings (Optional)"));
      
      char deviceTemplate[Nlines][Lenlines];
      LoadCustomTaskSettings(event->TaskIndex, (byte*)&deviceTemplate, sizeof(deviceTemplate));
      for (byte varNr = 0; varNr < Nlines; varNr++) {
        addFormTextBox(String(F("Line ")) + (varNr + 1), String(F("Plugin_075_template")) + (varNr + 1), deviceTemplate[varNr], Lenlines-1);
  
      }
      if( Settings.TaskDeviceTimer[event->TaskIndex]==0) {
        addFormNote(F("Interval Timer OFF: Nextion Lines (above) <b>NOT</b> scheduled for updates."));
      }
      else {
        addFormNote(F("Interval Timer On: Nextion Lines (above) scheduled for updates."));
      }


      success = true;
      break;
    }


    case PLUGIN_WEBFORM_SAVE: {

        String argName;

        char deviceTemplate[Nlines][Lenlines];
        for (byte varNr = 0; varNr < Nlines; varNr++)
        {
          String arg = F("Plugin_075_template");
          arg += varNr + 1;
          String tmpString = WebServer.arg(arg);
          strncpy(deviceTemplate[varNr], tmpString.c_str(), sizeof(deviceTemplate[varNr])-1);
            deviceTemplate[varNr][Lenlines-1]=0;
        }
        if(ExtraTaskSettings.TaskDeviceName[0]==0) {            // User forgot to enter device name!
            strcpy(ExtraTaskSettings.TaskDeviceName,"NEXTION"); // Give standard name.
        }
        Settings.TaskDevicePluginConfig[event->TaskIndex][0] = isFormItemChecked(F("AdvHwSerial"));
        Settings.TaskDevicePluginConfig[event->TaskIndex][1] = getFormItemInt(F("plugin_075_baud"));
        SaveCustomTaskSettings(event->TaskIndex, (byte*)&deviceTemplate, sizeof(deviceTemplate));

        success = true;
        break;
    }


    case PLUGIN_INIT: {

      AdvHwSerial = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
      uint8_t BaudCode = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
      Settings.TaskDevicePluginConfig[event->TaskIndex][2] = -999;       // Reset Last known idx.
      Settings.TaskDevicePluginConfig[event->TaskIndex][3] = -999;       // Reset Last known value.

      if(BaudCode > B115200) BaudCode = B9600;
      const uint32_t BaudArray[4] = {9600UL, 38400UL, 57600UL, 115200UL};
      AdvHwBaud = BaudArray[BaudCode];

      if (Settings.TaskDevicePin1[event->TaskIndex] != -1) {
        rxPin = Settings.TaskDevicePin1[event->TaskIndex];
      }
      if (Settings.TaskDevicePin2[event->TaskIndex] != -1) {
        txPin = Settings.TaskDevicePin2[event->TaskIndex];
      }

      if (SoftSerial != NULL) { 
        delete SoftSerial;
        SoftSerial = NULL;
      }

      String log = F("NEXTION075 : serial pin config RX:");
      log += rxPin;
      log += F(", TX:");
      log += txPin;
      if(Settings.TaskDeviceEnabled[event->TaskIndex]==true) 
       log += F(", Plugin Enabled");                    // Plugin is enabled.
      else log += F(", Plugin Disabled");
      addLog(LOG_LEVEL_INFO, log);

      if(Settings.TaskDeviceEnabled[event->TaskIndex] == true) { // Plugin is enabled.
      // Hardware serial is RX on 13 and TX on 15 (swapped hw serial)
        if (AdvHwSerial &&  rxPin == 13 && txPin == 15) {
            log = F("NEXTION075 : Using swap hardware serial");
            addLog(LOG_LEVEL_INFO, log);
            HwSerial = true;
            Settings.UseSerial = false;                 // Disable global Serial port.
            Settings.SerialLogLevel = 0;                // Disable logging on serial port.
            Settings.BaudRate = AdvHwBaud;              // Set BaudRate for Nextion.
            Serial.flush();
            Serial.begin(AdvHwBaud);
            Serial.swap();
        }
        // Hardware serial is RX on 3 and TX on 1. USB serial for Nextion IDE (User MCU Input function).
        else if(AdvHwSerial && rxPin == 3 && txPin == 1) {
            log = F("NEXTION075 : Using USB hardware serial");
            addLog(LOG_LEVEL_INFO, log);
            HwSerial = true;
            Settings.UseSerial = false;                 // Disable global Serial port.
            Settings.SerialLogLevel = 0;                // Disable logging on serial port.
            Settings.BaudRate = AdvHwBaud;              // Set BaudRate for Nextion.
            Serial.flush();
            Serial.begin(AdvHwBaud);
        }
        else {
            log = F("NEXTION075 : Using software serial");
            addLog(LOG_LEVEL_INFO, log);
            HwSerial = false;
            if (SoftSerial == NULL) {
                SoftSerial = new ESPeasySoftwareSerial(rxPin, txPin);
            } 
            SoftSerial->begin(9600);
            SoftSerial->flush();
        }
    }
    else {
    }
      success = true;
      break;
    }


    case PLUGIN_READ: {    // Get Plugin's optional command-text strings. Special RSSIBAR bargraph keyword is supported.
        char deviceTemplate[Nlines][Lenlines];
        int RssiIndex;
        String newString;
        String tmpString;
        String UcTmpString;
        
        LoadCustomTaskSettings(event->TaskIndex, (byte*)&deviceTemplate, sizeof(deviceTemplate));

        for (byte x = 0; x < Nlines; x++) {
          tmpString = deviceTemplate[x];
          if (tmpString.length()) {
            UcTmpString = deviceTemplate[x];
            UcTmpString.toUpperCase();
            RssiIndex = UcTmpString.indexOf(F("RSSIBAR"));  // RSSI bargraph Keyword found, wifi value in dBm.
            if(RssiIndex >= 0) {
              int barVal;
              newString = tmpString.substring(0, RssiIndex);
              int nbars = WiFi.RSSI();
              if (nbars < -100 || nbars >= 0)
                 barVal=0;
              else if (nbars >= -100 && nbars < -95)
                 barVal=5;
              else if (nbars >= -95 && nbars < -90)
                 barVal=10;
              else if (nbars >= -90 && nbars < -85)
                 barVal=20;
              else if (nbars >= -85 && nbars < -80)
                 barVal=30;
              else if (nbars >= -80 && nbars < -75)
                 barVal=45;
              else if (nbars >= -75 && nbars < -70)
                 barVal=60;
              else if (nbars >= -70 && nbars < -65)
                 barVal=70;
              else if (nbars >= -65 && nbars < -55)
                 barVal=80;
              else if (nbars >= -55 && nbars < -50)
                 barVal=90;
              else if (nbars >= -50)
                 barVal=100;

              newString += String(barVal,DEC);
            }
            else {
              newString = parseTemplate(tmpString, 0);
            }

            sendCommand(newString.c_str(), HwSerial);
            success = true;
          }
        }

        // At Interval timer, send idx & value data only if either changed. This eliminates repeating the data.
        if ((Settings.TaskDevicePluginConfig[event->TaskIndex][2] != UserVar[event->BaseVarIndex]) ||
          (Settings.TaskDevicePluginConfig[event->TaskIndex][3] != UserVar[event->BaseVarIndex+1])) {
            Settings.TaskDevicePluginConfig[event->TaskIndex][2] = UserVar[event->BaseVarIndex];  // Save new idx.
            Settings.TaskDevicePluginConfig[event->TaskIndex][3] = UserVar[event->BaseVarIndex+1]; // Save new value.
            success = true;
        } 
        else {
            success = false;
        }


        break;
    }


    case PLUGIN_WRITE: {
        String tmpString = string;
        int argIndex = tmpString.indexOf(',');
        if (argIndex) tmpString = tmpString.substring(0, argIndex);

//      String log = F("TaskDeviceName : ");
//      log += ExtraTaskSettings.TaskDeviceName;
//      addLog(LOG_LEVEL_INFO, log);

        if (tmpString.equalsIgnoreCase(F("NEXTION"))) {
//      if (tmpString.equalsIgnoreCase(ExtraTaskSettings.TaskDeviceName)) { // Use Plugin Name as command ID name.
            argIndex = string.indexOf(',');
            tmpString = string.substring(argIndex + 1);
            sendCommand(tmpString.c_str(), HwSerial);

            String log = F("NEXTION075 : WRITE, ");
            log += F("Command is ");
            log += (tmpString.c_str());
            addLog(LOG_LEVEL_INFO, log);

            success = true;                             // Set true only if plugin found a command to execute.
        }
        break;
    }


    case PLUGIN_EXIT: {
      if (SoftSerial) {
        delete SoftSerial;
        SoftSerial=NULL;
      }

      if(HwSerial) {
        HwSerial = false;
        Settings.UseSerial		= DEFAULT_USE_SERIAL;
        Settings.BaudRate		= DEFAULT_SERIAL_BAUD;
        Serial.flush();
        Serial.begin(DEFAULT_SERIAL_BAUD);              // Restart Serial Logging with default baud.
      }
      break;
    }


    case PLUGIN_ONCE_A_SECOND: {
        success = true;
        break;
    }

    
    case PLUGIN_TEN_PER_SECOND: {
      uint16_t i;
      uint8_t c;
      uint8_t charCount;
      String log;
      String Vidx;
      String Nvalue;
      String Svalue;
      String Nswitch;
      char __buffer[RXBUFFSZ+1];

      if(HwSerial) charCount = Serial.available();      // Prime the Hardware Serial engine.
      else charCount = SoftSerial->available();         // Prime the Soft Serial engine.

      while (charCount) {                               // This is the serial engine. It processes the serial Rx stream.
        if(HwSerial) c = Serial.read();
        else c = SoftSerial->read();

        if (c == 0x65) {
          if (charCount < 6) delay((5/(AdvHwBaud/9600))+1); // Let's wait for a few more chars to arrive.

          if (HwSerial) charCount = Serial.available();
          else charCount = SoftSerial->available();
          if (charCount >= 6) {
            __buffer[0] = c;
            for (i = 1; i < 7; i++) {
                if(HwSerial) __buffer[i] = Serial.read();
                else __buffer[i] = SoftSerial->read();
            }

            __buffer[i] = 0x00;

            if (0xFF == __buffer[4] && 0xFF == __buffer[5] && 0xFF == __buffer[6]) {
              UserVar[event->BaseVarIndex] = (__buffer[1] * 256) + __buffer[2] + TOUCH_BASE;
              UserVar[event->BaseVarIndex + 1] = __buffer[3];
              log = F("NEXTION075 : code: ");
              log += __buffer[1];
              log += ",";
              log += __buffer[2];
              log += ",";
              log += __buffer[3];
              addLog(LOG_LEVEL_INFO, log);

              sendData(event);
            }
          }
        } 
        else {
          if (c == '|') {
            __buffer[0] = c;

            if (charCount < 8) delay((9/(AdvHwBaud/9600))+1); // Let's wait for more chars to arrive.
            else delay((3/(AdvHwBaud/9600))+1);               // Short wait for tardy chars.
            if (HwSerial) charCount = Serial.available();
            else charCount = SoftSerial->available();

            if(HwSerial) {
                i = 1;            
                while (Serial.available() > 0 && i<RXBUFFSZ) {  // Copy global serial buffer to local buffer.
                  __buffer[i] = Serial.read();
                  if (__buffer[i]==0x0a || __buffer[i]==0x0d) break;
                  i++;
                }
            }
            else {
                i = 1;            
                while (SoftSerial->available() > 0 && i<RXBUFFSZ) {  // Copy global serial buffer to local buffer.
                  __buffer[i] = SoftSerial->read();
                  if (__buffer[i]==0x0a || __buffer[i]==0x0d) break;
                  i++;
                }
            }

            __buffer[i] = 0x00;
            
            String tmpString = __buffer;
            log = F("NEXTION075 : code: ");
            log += tmpString;
            addLog(LOG_LEVEL_INFO, log);

            int argIndex = tmpString.indexOf(F(",i"));
            int argEnd = tmpString.indexOf(',', argIndex + 1);
            if (argIndex) Vidx = tmpString.substring(argIndex + 2,argEnd);

            boolean GotPipeCmd = false;
            switch (__buffer[1]){
              case 'u':
                GotPipeCmd = true;
                argIndex = argEnd;
                argEnd = tmpString.indexOf(',',argIndex + 1);
                if (argIndex) Nvalue = tmpString.substring(argIndex + 2,argEnd);
                argIndex = argEnd;
                argEnd = tmpString.indexOf(0x0a);
                if (argIndex) Svalue = tmpString.substring(argIndex + 2,argEnd);
                break;
              case 's':
                GotPipeCmd = true;
                argIndex = argEnd;
                argEnd = tmpString.indexOf(0x0a);
                if (argIndex) Nvalue = tmpString.substring(argIndex + 2,argEnd);
                if (Nvalue == F("On")) Svalue='1';
                if (Nvalue == F("Off")) Svalue='0';
                break;
            }

            if (GotPipeCmd) {
                UserVar[event->BaseVarIndex] = Vidx.toFloat();
                UserVar[event->BaseVarIndex+1] = Svalue.toFloat();
                sendData(event);
                log = F("NEXTION075 : Pipe Command Sent: ");
                log += __buffer;
                log += UserVar[event->BaseVarIndex];
            }
            else {
                log = F("NEXTION075 : Unknown Pipe Command, skipped");
            }
            addLog(LOG_LEVEL_INFO, log);
          }
        }
        if(HwSerial) charCount = Serial.available();
        else charCount = SoftSerial->available();
      }

      success = true;
      break;
    }
  }
  return success;
}


void sendCommand(const char *cmd, boolean SerialHW) 
{
    if(SerialHW) {
        Serial.print(cmd);
        Serial.write(0xff);
        Serial.write(0xff);
        Serial.write(0xff);
    }
    else {
        SoftSerial->print(cmd);
        SoftSerial->write(0xff);
        SoftSerial->write(0xff);
        SoftSerial->write(0xff);
    }
}

#endif // USES_P075
Please check it. Be sure to turn the Interval timer back on and recreate your previous conditions. If the magic code is working your garage light shouldn't do the disco dance anymore.

- Thomas
Last edited by ThomasB on 19 Jul 2018, 16:31, edited 1 time in total.

waspie
Normal user
Posts: 127
Joined: 09 Feb 2017, 19:35

Re: Nextion display plugin

#308 Post by waspie » 19 Jul 2018, 14:47

BertB wrote: 18 Jul 2018, 08:51 I designed this communication to put more of the thinking in the Nextion, but it also more or less causes more often changes in the Nextion.
This is not very user friendly while there is no easy way to update Nextion.

Therefore I mostly use the id's and let Rules and Domoticz do the thinking.
The drawback here is the shortage of rules space, but the gain is simplicity, agility and beter feedback.
same here which is why i asked early on if the Nextion could be updated remotely. As this isn't possible I wanted to rely more on the ESP. It turns out not to be a huge problem..make the panel design once, and something you can live with and the rest you manipulate with espeasy and openhab(domo/whatever) but I do run out of rules, almost! something like 2000/2048 on all 4 pages! glad i didn't need more buttons

BertB
Normal user
Posts: 1049
Joined: 25 Apr 2015, 14:39

Re: Nextion display plugin

#309 Post by BertB » 19 Jul 2018, 23:11

@ThomasB
I will test it this weekend.

BertB
Normal user
Posts: 1049
Joined: 25 Apr 2015, 14:39

Re: Nextion display plugin

#310 Post by BertB » 22 Jul 2018, 15:51

@Thomas,
You have limited the number of lines and the max number of characters. I guess it is to limit the memory usage, but iyt gave me a lot of trouble as I had to delete the plugin and activated it all over again. No big deal, but it was a bit confusing.

Then, because of the lack of info on the WEB LOG tool, I used the Softserial option with the normal serial port for debug info.

It gave me this, but for some reason, nothing happens in the domoticz anymore. (I am going to test that later with an older version of ESPEasy).

This is the output:

Code: Select all

1480325 : NEXTION075 : code: ,,
1480328 : EVENT: Nextion#idx=2039.00
1480346 : ACT  : SendToHTTP xxx.xxx.xxx.xxx,8080,/json.htm?type=command&param=switchlight&idx=293&switchcmd=Toggle
1480363 : Command: sendtohttp
1480369 : GET  HTTP/1.1
Host: xxx.xxx.xxx.xxx
Connection: close


1481385 : Timeout while reading input data!
1481418 : EVENT: Nextion#idx=2039.00 Processing time:1090 milliSeconds
1481419 : EVENT: Nextion#value=0.00
1481461 : EVENT: Nextion#value=0.00 Processing time:42 milliSeconds
1481474 : HTTP : connecting to xxx.xxx.xxx.xxx:8080
1481483 :  Domoticz: Sensortype: 5 idx: 310 values: 2039;0
1481511 : HTTP : Success
1481516 : HTTP : closing connection


Ok
1494318 : NEXTION075 : code: ,,
1494320 : EVENT: Nextion#idx=2039.00
1494338 : ACT  : SendToHTTP xxx.xxx.xxx.xxx,8080,/json.htm?type=command&param=switchlight&idx=293&switchcmd=Toggle
1494357 : Command: sendtohttp
1494394 : GET  HTTP/1.1
Host: xxx.xxx.xxx.xxx
Connection: close


1495409 : Timeout while reading input data!
1495441 : EVENT: Nextion#idx=2039.00 Processing time:1121 milliSeconds
1495442 : EVENT: Nextion#value=0.00
1495485 : EVENT: Nextion#value=0.00 Processing time:42 milliSeconds
1495499 : HTTP : connecting to xxx.xxx.xxx.xxx:8080
1495510 :  Domoticz: Sensortype: 5 idx: 310 values: 2039;0
1495530 : HTTP : Success
1495535 : HTTP : closing connection
>settings
1499880 : Command: settings


Edit
When I enter this in a internet page, I get to expected result:

Code: Select all

http://xxx.xxx.xxx.xxx:8080/json.htm?type=command&param=switchlight&idx=293&switchcmd=Toggle

BertB
Normal user
Posts: 1049
Joined: 25 Apr 2015, 14:39

Re: Nextion display plugin

#311 Post by BertB » 22 Jul 2018, 16:30

Something seems to be not ok with the latest release Release mega-20180722, as it does not do the switching in Domoticz.
Release Release mega-20180719 seems to work.

User avatar
grovkillen
Core team member
Posts: 3621
Joined: 19 Jan 2017, 12:56
Location: Hudiksvall, Sweden
Contact:

Re: Nextion display plugin

#312 Post by grovkillen » 22 Jul 2018, 16:34

Do you use rules for intercepting the command? What if the exact command you use? We have a little parsing error that is going to be fixed here in some days.
ESP Easy Flasher [flash tool and wifi setup at flash time]
ESP Easy Webdumper [easy screendumping of your units]
ESP Easy Netscan [find units]
Official shop: https://firstbyte.shop/
Sponsor ESP Easy, we need you :idea: :idea: :idea:

BertB
Normal user
Posts: 1049
Joined: 25 Apr 2015, 14:39

Re: Nextion display plugin

#313 Post by BertB » 22 Jul 2018, 17:20

grovkillen wrote: 22 Jul 2018, 16:34 Do you use rules for intercepting the command? What if the exact command you use? We have a little parsing error that is going to be fixed here in some days.
This is the rule:

Code: Select all

on Nextion#idx=2039 do
    SendToHTTP xxx.xxx.xxx.xxx,8080,/json.htm?type=command&param=switchlight&idx=293&switchcmd=Toggle
endon 

User avatar
ThomasB
Normal user
Posts: 1065
Joined: 17 Jun 2018, 20:41
Location: USA

Re: Nextion display plugin

#314 Post by ThomasB » 22 Jul 2018, 18:15

You have limited the number of lines and the max number of characters. I guess it is to limit the memory usage ...
The original Nextion plugin was violating the SPIFFS memory allowance. According to the Developer's Guide, only 512 bytes are allowed for custom config, so I reduced the optional Lines count and their length (was 12 lines x 64 chars, now 8 x 48). There's some extra bytes that would allow two more lines. Or it can be used to increase the length of the 8 lines to 62 chars. Which do think would have the widest appeal?
Something seems to be not ok with the latest release Release mega-20180722, as it does not do the switching in Domoticz.
Release Release mega-20180719 seems to work.
That's a relief the latest Nextion plugin works in the 0719 release.

But despite that you got the latest Nextion plugin to work, I just realized my interval "fix" might not work correctly for everyone. So some questions for you.
1. I understand that you are using the Nextion "Send Component ID" on the Touch Press Event. Is the Touch Press Release Event also being used with the Press Event?
2. Does the Nextion button continue to work correctly after the first press? Or does it only work the first time you press it?

- Thomas

BertB
Normal user
Posts: 1049
Joined: 25 Apr 2015, 14:39

Re: Nextion display plugin

#315 Post by BertB » 22 Jul 2018, 18:31

ThomasB wrote: 22 Jul 2018, 18:15 Which do think would have the widest appeal?
I think more lines, but per haps it is not necessary to use that much ccharacters. 32 was just too few. Maybe 40 is ok.
But despite that you got the latest Nextion plugin to work, I just realized my interval "fix" might not work correctly for everyone. So some questions for you.
1. I understand that you are using the Nextion "Send Component ID" on the Touch Press Event. Is the Touch Press Release Event also being used with the Press Event?
No, I only use the Tough Release Event.
2. Does the Nextion button continue to work correctly after the first press? Or does it only work the first time you press it?
Yes it does continue to work just fine.

User avatar
ThomasB
Normal user
Posts: 1065
Joined: 17 Jun 2018, 20:41
Location: USA

Re: Nextion display plugin

#316 Post by ThomasB » 22 Jul 2018, 19:51

I think more lines, but per haps it is not necessary to use that much characters. 32 was just too few. Maybe 40 is ok.
Ok, a couple more Lines it is. Keep in mind that Lines statements can consume a lot of characters. For example, this useful Nextion text update would require a line length of 50 bytes.

Code: Select all

page7.t1.txt="Date %sysmonth%:%sysday%:%sysyears%"
But really long Nextion command statements can be handled in the rules file rather than by user Lines. So all situations are covered.
Yes it does continue to work just fine.
Thanks for the additional info. It confirms that the latest release is working as intended. But for more user flexibility I will add another checkbox that allows the user to restore the default interval behavior.

There are two open issues on the plugin that are being reviewed by the ESPeasy developers. As follows:
1. The user assigned Plugin name must be NEXTION. If it is named anything else some functionality is lost.
2. The Plugin sometimes will crash/brick the firmware if you have any NEXTION rules in the ESP rules file when you delete the plugin. Bricking requires erasing the flash memory and re-installing ESPeasy.
Unbelievably, these two issues are related. Software can be so cruel!

I'll post the final (hopefully it's final) version this week. If all goes well it will be the one to add to the official TESTING distribution.

BTW, I believe I'm the first to fully incorporate the new hard serial Nextion plugin in a finished project. And it has been working great. It's a little gadget that is integrated with Amazon Echo that provides a voice notification when the laundry is done. I'll post some build photos and more details soon.
.
DSCN5098.JPG
DSCN5098.JPG (1.58 MiB) Viewed 158042 times
- Thomas

BertB
Normal user
Posts: 1049
Joined: 25 Apr 2015, 14:39

Re: Nextion display plugin

#317 Post by BertB » 22 Jul 2018, 21:37

very nice indeed.
I have two work in progress projects.
One is a thermostat to be placed in the various rooms in my house.
The other one is a general purpose control panel.
I am now testing the pont control.
Pont control.PNG
Pont control.PNG (184.85 KiB) Viewed 158036 times

waspie
Normal user
Posts: 127
Joined: 09 Feb 2017, 19:35

Re: Nextion display plugin

#318 Post by waspie » 23 Jul 2018, 02:42

Nice projects guys.
Here are my 2 3.5" models. I have a few 2.4s in bedrooms for light/temp/vent control.

In out main living room there are 4 (yeah, 4) small ceiling fan/lights. Previously, a single 3-way (2-way?) switch turned them on and off and you had to use pull chains at each fan to make adjustments. Now there's an on/off for all lights and fans as well as a screen where individual lights/fans can be turned on and off. Garage doors can be actuated, stair light, tart warmer, neato schedule etc...
20180722_202809.jpg
20180722_202809.jpg (218.76 KiB) Viewed 158028 times
20180722_202819.jpg
20180722_202819.jpg (269.8 KiB) Viewed 158028 times
20180722_202815.jpg
20180722_202815.jpg (339.09 KiB) Viewed 158028 times
This one is by the front door. It controls some lights and gives some basic info before heading out. Temps, UV Index, and burn times.
20180722_203158.jpg
20180722_203158.jpg (779.21 KiB) Viewed 158028 times

User avatar
grovkillen
Core team member
Posts: 3621
Joined: 19 Jan 2017, 12:56
Location: Hudiksvall, Sweden
Contact:

Re: Nextion display plugin

#319 Post by grovkillen » 23 Jul 2018, 06:49

Really love these project pictures. Inspiring!
ESP Easy Flasher [flash tool and wifi setup at flash time]
ESP Easy Webdumper [easy screendumping of your units]
ESP Easy Netscan [find units]
Official shop: https://firstbyte.shop/
Sponsor ESP Easy, we need you :idea: :idea: :idea:

User avatar
ThomasB
Normal user
Posts: 1065
Joined: 17 Jun 2018, 20:41
Location: USA

Re: Nextion display plugin

#320 Post by ThomasB » 23 Jul 2018, 20:57

Cool projects! More photos of working Nextion projects will help spread the Nextion plugin love. So keep the photos coming!

Currently the Nextion wiki (https://www.letscontrolit.com/wiki/index.php/Plugin75) is an empty page. I'd volunteer to add some information to it if I was granted write/edit privileges.

Some project details to share to help inspire other Nextion/ESPeasy projects:
My recently completed Nextion project is a simple application that provides Amazon Echo voice notifications when the laundry is ready. The device slips onto the dryer's control panel and is held in place by a hidden magnet. Power is provided by a orphan USB charger supply.
Finished unit.
Finished unit.
LaundryBuddy1_800.jpg (96.21 KiB) Viewed 157992 times
Overview:
A single ESP8266 monitors the washer and dryer, which are ten year old GE machines. ESPeasy's Nextion plugin communicates the touch screen entries to the home automation controller (Openhabian) using MQTT. In turn, the home automation system can interact with the ESP8266/Nextion using HTTP messages. All touch screen commands have equivalent Echo voice commands (touch and voice commands duplicate each other).

Hardware:
The ESP8266 is the Lolin NodeMCU v3. It's my go-to board for ESPeasy projects. Cost is less than $5 USD from China suppliers. The display is a $20 Nextion 2.8-inch, #NX3224T028.

Here's an overview of all the pieces, including the 3D printed plastic parts:
All the pieces.
All the pieces.
LaundryBuddy2_800.jpg (148.23 KiB) Viewed 157992 times
The ESP8266 needs to know when the washer or dryer are running and when they turn off. My goal was to avoid any electrical connections to them. This was possible on the dryer using a $2USD MPU6050 accelerometer that senses vibration from the spinning drum. Sensitivity is amazing, it can detect ANY size laundry load. The ESP8266 has a MPU6050 plugin that makes this possible with minimal effort.

But the washer required invasive electrical surgery. My machine doesn't have indicator lights and sensing vibration won't work because of the motionless soak cycles. Monitoring machine current was considered, but current draw is nearly zero during some operating states so current loop solutions weren't practical.

The chosen solution was a $2USD high voltage optoisolator board designed for 220VAC. Fortunately it works fine on the washer's 120VAC mains without any modifications. The board safely isolates the washing machine's high voltage and provides TTL compatible On/Off status to the ESP8266. For moisture protection all PCB circuitry was coated in epoxy and protected with shrink wrap.
Optoisolator in washing machine.
Optoisolator in washing machine.
Optoisolator1_800.jpg (116.12 KiB) Viewed 157992 times
Optoisolator connection to washer machine timer.
Optoisolator connection to washer machine timer.
WasherTimer1_800.jpg (96.7 KiB) Viewed 157992 times
The plastic parts were created in 123D Design and 3D printed in white ABS plastic. All visible surfaces were sanded, acetone polished, then spray painted with Appliance White epoxy paint.

Basic Operation:
The home automation system (Openhabian) provides the interface to the Amazon Echo voice functions and monitors the machines with two large Rules files. Besides giving vocal announcements when the washer or dryer are done, it also provides loss-of-communication warnings and reports user mistakes (like forgetting to turn on the machine). Some simple animations are shown on the display to indicate the operating mode.

Below is a video of the washer and dryer running. At the 13 second mark the washer ends it cleaning cycle (graphic changes color). Not heard on the video is the "The washing machine is done, your laundry is ready" message broadcast by our Amazon Echo speakers.

https://youtu.be/gVsYJ0QBaxY

- Thomas

waspie
Normal user
Posts: 127
Joined: 09 Feb 2017, 19:35

Re: Nextion display plugin

#321 Post by waspie » 25 Jul 2018, 18:03

to take advantage of H/W serial using the pin swap option it needs to be wired like this, correct?
NextionHwSerialPinout1.jpg
NextionHwSerialPinout1.jpg (52.56 KiB) Viewed 157753 times

BertB
Normal user
Posts: 1049
Joined: 25 Apr 2015, 14:39

Re: Nextion display plugin

#322 Post by BertB » 25 Jul 2018, 20:29

Correct, although I do not use the resistors.

User avatar
ThomasB
Normal user
Posts: 1065
Joined: 17 Jun 2018, 20:41
Location: USA

Re: Nextion display plugin

#323 Post by ThomasB » 26 Jul 2018, 01:29

@waspie, I recommend using the resistors (with the transistor) on your development board since it will be booted a lot while you work on coding. But your "production" boards should be fine with just the transistor (without the resistors).

There is a silicon bug on the ESP8266 that prevents reliable soft booting after a firmware flashing. Unfortunately the transistor doesn't offer any special magic to fix that issue; I've made a habit of pressing the reset button immediately after fresh firmware is loaded.

- Thomas

waspie
Normal user
Posts: 127
Joined: 09 Feb 2017, 19:35

Re: Nextion display plugin

#324 Post by waspie » 26 Jul 2018, 01:39

all good, the board i designed has pads so i can bridge them or put in resistors. thanks!

Robert
New user
Posts: 3
Joined: 14 Dec 2016, 22:40

Re: Nextion display plugin

#325 Post by Robert » 26 Jul 2018, 13:41

Hi,

actually my question is not about the plugin but about serial.swab and this plugin is the only thing I have found where it is used.
I flashed all my SonOff from R120 to ESP_Easy_mega-20180615_normal_ESP8266_1024.bin. no hassle but I lost Serial.swap which I had build in.
What I have read Serial.swap should be part of the package now and I find it back in HardwareSerial.h/cpp but cannot find how to use it anywhere on the web interface.

As it is used here for this plugin I hoped I would find some help how to use it in a general matter.

Regards, Rob

BertB
Normal user
Posts: 1049
Joined: 25 Apr 2015, 14:39

Re: Nextion display plugin

#326 Post by BertB » 26 Jul 2018, 18:34

Robert wrote: 26 Jul 2018, 13:41
What I have read Serial.swap should be part of the package now and I find it back in HardwareSerial.h/cpp but cannot find how to use it anywhere on the web interface.

Regards, Rob
Where did you see this?
If you want to know how to use Serial.swap(), you could look here http://esp8266.github.io/Arduino/versio ... rence.html

Robert
New user
Posts: 3
Joined: 14 Dec 2016, 22:40

Re: Nextion display plugin

#327 Post by Robert » 27 Jul 2018, 13:28

Hi Bert,
I read this on https://github.com/costonisp/MiniESPEasy and the forum also shows 'hits' searching for Serial.swap. I just cannot find a hint how to use it out of the box.

What I am doing now is trying to implement it the same way I did in R-120.
There are so many changes in the mega/2.0 branch that I'm not sure where to look if I don't get my I2c port seeing sensors as it did before.
I changed EspEasy.ino and Mics.ino on three places total, where one finds the Serial.begin statements, and WebServer.ino to enable the GPIO's.

I'm sure somebody has don it before but cannot find anything. Regards Rob

BertB
Normal user
Posts: 1049
Joined: 25 Apr 2015, 14:39

Re: Nextion display plugin

#328 Post by BertB » 27 Jul 2018, 17:33

@ThomasB
Sorry to say, but the disco is back again.
I am now using 20180723.

I will try an older version.

BertB
Normal user
Posts: 1049
Joined: 25 Apr 2015, 14:39

Re: Nextion display plugin

#329 Post by BertB » 27 Jul 2018, 18:07

Had the same problem. I do not know why I did not notice this before.
I put some Serial.prints in the code (I can bwecause I use soft serial) an found that:
Settings.TaskDevicePluginConfig[event->TaskIndex][2]=0 whereas
UserVar[event->BaseVarIndex]= 0.00000000
or 2039 vs 2039.000000
And they don't compare.
So I changed the code a bit to:

Code: Select all

        if ((int(Settings.TaskDevicePluginConfig[event->TaskIndex][2]) != int(UserVar[event->BaseVarIndex])) ||
          (int(Settings.TaskDevicePluginConfig[event->TaskIndex][3]) != int(UserVar[event->BaseVarIndex+1]))) {
            Settings.TaskDevicePluginConfig[event->TaskIndex][2] = UserVar[event->BaseVarIndex];  // Save new idx.
            Settings.TaskDevicePluginConfig[event->TaskIndex][3] = UserVar[event->BaseVarIndex+1]; // Save new value.
            success = true;
Seems to work, but I wonder.
Why do we need this event stuff here anyway?
Al important data is send over immediately.

I went back to take a look at my original code and found that it was not there either. This explains why the problem did not pop up before.

And I also think something is wrong with the event structure.

BertB
Normal user
Posts: 1049
Joined: 25 Apr 2015, 14:39

Re: Nextion display plugin

#330 Post by BertB » 27 Jul 2018, 18:17

My little change did not help either.
Imagine Switch 1 has code 2039 and Switch 2 has 2040
After the first action 2039 is being remebered,, so when 2040 arrives, a difference is found and the action is repeated.
Every time you use another switch, the problem sohws up.

Post Reply

Who is online

Users browsing this forum: No registered users and 86 guests