Re: Nextion display plugin
Posted: 14 Jul 2018, 09:17
Sounds like a good idea to me.
Have fun with controlling everything!
https://www.letscontrolit.com/forum/
600472 : LoadFromFile: config.dat index: 4096 datasize: 472
600475 : LoadFromFile: config.dat index: 5120 datasize: 768
600537 : LoadFromFile: config.dat index: 6144 datasize: 472
600543 : LoadFromFile: config.dat index: 4096 datasize: 472
600572 : LoadFromFile: config.dat index: 6144 datasize: 472
600575 : LoadFromFile: config.dat index: 4096 datasize: 472
600603 : LoadFromFile: config.dat index: 6144 datasize: 472
600606 : LoadFromFile: config.dat index: 4096 datasize: 472
600637 : LoadFromFile: config.dat index: 6144 datasize: 472
600639 : LoadFromFile: config.dat index: 4096 datasize: 472
600676 : EVENT: E16Nextion#idx=1274.00
600684 : ACT : SendToHTTP xxx.xxx.xxx.xxx,8080,/json.htm?type=command¶m=switchlight&idx=387&switchcmd=Toggle
600700 : Command: sendtohttp
600732 : HTTP/1.1 200 OK
600770 : EVENT: E16Nextion#idx=1274.00 Processing time:94 milliSeconds
600771 : EVENT: E16Nextion#value=0.00
600795 : EVENT: E16Nextion#value=0.00 Processing time:25 milliSeconds
600796 : LoadFromFile: config.dat index: 28672 datasize: 724
600814 : Domoticz: Sensortype: 5 idx: 1 values: 1274;0
600815 : MQTT : {"idx":1,"RSSI":3,"nvalue":0,"svalue":"1274;0"}
600818 : LoadFromFile: config.dat index: 29696 datasize: 724
600837 : HTTP : connecting to xxx.xxx.xxx.xxx:8080
600851 : Domoticz: Sensortype: 5 idx: 310 values: 1274;0
600881 : HTTP : Success
600888 : HTTP : closing connection
600985 : NEXTION075 : WRITE, Command is page3.b5.bco=48631
601472 : LoadFromFile: config.dat index: 6144 datasize: 472
603475 : EVENT: Clock#Time=Sat,23:02
603500 : EVENT: Clock#Time=Sat,23:02 Processing time:25 milliSeconds
603571 : LoopStats: shortestLoop: 46 longestLoop: 1137307 avgLoopDuration: 128.59 systemTimerDuration: 21.62 systemTimerCalls: 32 loopCounterMax: 652173 loopCounterLast: 230924 countFindPluginId: 0
603580 : PluginStats P_37_Generic - MQTT Import READ Count: 1 Avg/min/max 2541.00/2541/2541 usec
603589 : PluginStats P_37_Generic - MQTT Import ONCE_A_SECOND Count: 31 Avg/min/max 2177.32/2127/2541 usec
603599 : PluginStats P_37_Generic - MQTT Import TEN_PER_SECOND Count: 297 Avg/min/max 2225.59/2083/3868 usec
603609 : PluginStats P_37_Generic - MQTT Import WRITE Count: 2 Avg/min/max 2311.50/2094/2529 usec
603619 : PluginStats P_37_Generic - MQTT Import EVENT_OUT Count: 1 Avg/min/max 2813.00/2813/2813 usec
603629 : PluginStats P_37_Generic - MQTT Import SERIAL_IN Count: 1 Avg/min/max 2068.00/2068/2068 usec
603639 : PluginStats P_37_Generic - MQTT Import FIFTY_PER_SECOND Count: 1476 Avg/min/max 2147.14/2055/2684 usec
603647 : PluginStats P_71_Display - Nextion [TESTING_V3] READ Count: 1 Avg/min/max 200096.00/200096/200096 usec
603658 : PluginStats P_71_Display - Nextion [TESTING_V3] ONCE_A_SECOND Count: 31 Avg/min/max 34.45/26/47 usec
603668 : PluginStats P_71_Display - Nextion [TESTING_V3] TEN_PER_SECOND Count: 297 Avg/min/max 133.53/122/159 usec
603679 : PluginStats P_71_Display - Nextion [TESTING_V3] WRITE Count: 3 Avg/min/max 7632.00/134/22608 usec
603689 : PluginStats P_71_Display - Nextion [TESTING_V3] EVENT_OUT Count: 1 Avg/min/max 58.00/58/58 usec
603700 : PluginStats P_71_Display - Nextion [TESTING_V3] SERIAL_IN Count: 1 Avg/min/max 47.00/47/47 usec
603710 : PluginStats P_71_Display - Nextion [TESTING_V3] FIFTY_PER_SECOND Count: 1476 Avg/min/max 38.09/27/48 usec
603720 : Load File stats: Count: 13 Avg/min/max 4399.46/1332/19547 usec
603726 : Plugin call 50 p/s stats: Count: 1476 Avg/min/max 3122.74/2974/3819 usec
603734 : Plugin call 10 p/s stats: Count: 297 Avg/min/max 3275.19/3090/4900 usec
603741 : Plugin call 10 p/s U stats: Count: 297 Avg/min/max 3235.36/2997/3832 usec
603748 : Plugin call 1 p/s stats: Count: 31 Avg/min/max 18967.03/4096/425777 usec
603756 : checkSensors() stats: Count: 31 Avg/min/max 14398.42/547/422162 usec
603763 : sendData() stats: Count: 1 Avg/min/max 217326.00/217326/217326 usec
603771 : Compute formula stats: Count: 1 Avg/min/max 19.00/19/19 usec
603777 : WD : Uptime 10 ConnectFailures 0 FreeMem 14200
As an alternative you can set both to -1 (or any other number) after your MQTT. Just choose a number that does not normally occur so that you can ignore it.In this case the event only triggers a rule. Idx will be id of the switch. Value is always 0.
Code: Select all
on NEXTION#idx do
if [NEXTION#idx]>=10 and [NEXTION#idx]<=30
Publish /%sysname%/NEXTION/idx,[NEXTION#idx]
endif
if [NEXTION#idx]>=500 // Touch Events
Publish /%sysname%/NEXTION/idx,[NEXTION#idx]
Publish /%sysname%/NEXTION/value,[NEXTION#value]
NEXTION#value = -1
endif
NEXTION#idx = -1
endon
I dare to disagree . I carried out some investigation and found out that your latest (7-13-2018) code has the flaw, whereas my latest modification (07082018) has not.
Code: Select all
//#######################################################################################################
//################################### Plugin 075: Nextion <info@sensorio.cz> ###########################
//################################### Created on the work of majklovec ###########################
//#######################################################################################################
#ifdef USES_P075
#define PLUGIN_075
#define PLUGIN_ID_075 75
//#define PLUGIN_NAME_075 "Display - Nextion [TESTING]"
#define PLUGIN_NAME_075 "Display - Nextion [BERTB REV3]"
#define PLUGIN_VALUENAME1_075 "code"
#define PLUGIN_VALUENAME2_075 "value"
#define Nlines 12 // The number of different lines which can be displayed - each line is 64 chars max
boolean Plugin_075_init = false;
boolean Plugin_075(byte function, struct EventStruct *event, String &string) {
boolean success = false;
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].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));
success = true;
break;
}
case PLUGIN_GET_DEVICEGPIONAMES: {
int rxPin = Settings.TaskDevicePin1[event->TaskIndex];
int txPin = Settings.TaskDevicePin2[event->TaskIndex];
if ((rxPin == 3 && txPin == 1) || (rxPin == 13 && txPin == 15)) {
event->String1 = F("GPIO HW RX ←");
event->String2 = F("GPIO HW TX →");
}
else { // Soft Serial.
event->String1 = F("GPIO SS RX ←");
event->String2 = F("GPIO SS TX →");
}
break;
}
case PLUGIN_INIT: {
/* LoadTaskSettings(event->TaskIndex);
if (Settings.TaskDevicePin1[event->TaskIndex] != -1)
{
Plugin_075_RXpin = Settings.TaskDevicePin1[event->TaskIndex];
}
if (Settings.TaskDevicePin2[event->TaskIndex] != -1)
{
Plugin_075_TXpin = Settings.TaskDevicePin2[event->TaskIndex];
}
if (!nextion) {
nextion = new ESPeasySoftwareSerial(Plugin_075_RXpin , Plugin_075_TXpin);
}
*/
Serial.begin(9600);
Serial.flush();
Serial.swap();
Plugin_075_init = true;
success = true;
break;
}
case PLUGIN_TEN_PER_SECOND: {
if(Plugin_075_init) {
char __buffer[80];
uint16_t i;
uint8_t c;
String Vidx;
String Nvalue;
String Svalue;
String Nswitch;
while (Serial.available() > 0) {
delay(10);
c = Serial.read();
if (0x65 == c) {
if (Serial.available() >= 6) {
__buffer[0] = c;
for (i = 1; i < 7; i++) {
__buffer[i] = Serial.read();
}
__buffer[i] = 0x00;
if (0xFF == __buffer[4] && 0xFF == __buffer[5] && 0xFF == __buffer[6]) {
UserVar[event->BaseVarIndex] = __buffer[1] * 256 + __buffer[2];
UserVar[event->BaseVarIndex + 1] = __buffer[3];
String log = F("Nextion : code: ");
log += __buffer[1];
log += ",";
log += __buffer[2];
log += ",";
log += __buffer[3];
addLog(LOG_LEVEL_INFO, log);
sendData(event);
success = true;
}
else success = false;
return success;
}
}
else if (c == '|') {
i = 1;
__buffer[0] = c;
c=0;
while (Serial.available() > 0) {
__buffer[i] = Serial.read();
if (__buffer[i]==0x0d) break;
i++;
}
__buffer[i] = 0x00;
String tmpString = __buffer;
int argIndex = tmpString.indexOf(F(",i"));
int argEnd = tmpString.indexOf(',', argIndex + 1);
if (argIndex)
Vidx = tmpString.substring(argIndex + 2,argEnd);
switch (__buffer[1]){
case 'u':
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':
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;
default:
success = false;
return success;
break;
}
UserVar[event->BaseVarIndex] = Vidx.toFloat();
UserVar[event->BaseVarIndex+1] = Svalue.toFloat();
String log = F("Nextion : send command: ");
log += __buffer;
log += UserVar[event->BaseVarIndex];
addLog(LOG_LEVEL_INFO, log);
sendData(event);
ExecuteCommand(VALUE_SOURCE_SYSTEM, __buffer);
success = true;
}
else success = false;
}
}
break;
}
case PLUGIN_ONCE_A_SECOND: {
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;
// strncpy(deviceTemplate[varNr], WebServer.arg(argName).c_str(), sizeof(deviceTemplate[varNr]));
}
SaveCustomTaskSettings(event->TaskIndex, (byte*)&deviceTemplate, sizeof(deviceTemplate));
success = true;
break;
}
case PLUGIN_WEBFORM_LOAD: {
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);
}
success = true;
break;
}
/* case PLUGIN_EXIT:
{
if (nextion)
{
delete nextion;
nextion=NULL;
}
break;
}
*/
case PLUGIN_READ: {
char deviceTemplate[Nlines][64];
LoadCustomTaskSettings(event->TaskIndex, (byte*)&deviceTemplate, sizeof(deviceTemplate));
String newString;
for (byte x = 0; x < Nlines; x++) {
String tmpString = deviceTemplate[x];
if (tmpString.length())
{
int rssiIndex = tmpString.indexOf(F("rssi"));
if(rssiIndex >= 0)
{
int barVal;
newString = tmpString.substring(0, rssiIndex);
int nbars = WiFi.RSSI();
if (nbars < -100)
barVal=0;
else if (nbars >= -100 and nbars < -90)
barVal=20;
else if (nbars >= -90 and nbars < -80)
barVal=40;
else if (nbars >= -80 and nbars < -70)
barVal=60;
else if (nbars >= -70 and nbars < -60)
barVal=80;
else if (nbars >= -60)
barVal=100;
newString += String(barVal,DEC);
}
else
{
newString = parseTemplate(tmpString, 0);
}
sendCommand(newString.c_str());
}
}
success = false;
break;
}
case PLUGIN_WRITE: {
String tmpString = string;
int argIndex = tmpString.indexOf(',');
if (argIndex)
tmpString = tmpString.substring(0, argIndex);
if (tmpString.equalsIgnoreCase(F("NEXTION"))) {
argIndex = string.indexOf(',');
tmpString = string.substring(argIndex + 1);
sendCommand(tmpString.c_str());
// Serial.println(tmpString);
success = true;
}
break;
}
}
return success;
}
void sendCommand(const char *cmd) {
Serial.print(cmd);
Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);
}
#endif // USES_P075
Code: Select all
//#######################################################################################################
//#######################################################################################################
//################################### Plugin 075: Nextion <info@sensorio.cz> ###########################
//################################### Created on the work of majklovec ###########################
//################################### Revisions by BertB and ThomasB ###########################
//################################### Last Revision: July-13-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 [TESTING_V3]"
#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].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 ← ");
event->String2 = F("GPIO SS TX → ");
if(AdvHwSerial == true) {
if ((rxPin == 3 && txPin == 1) || (rxPin == 13 && txPin == 15)) {
event->String1 = F("GPIO HW RX ← ");
event->String2 = F("GPIO HW TX → ");
}
}
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);
}
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
No problem. It is my baby tooThanks for doing the testing!
Code: Select all
on E16NEXTION#idx do
if [E16NEXTION#idx]>=1274 // Touch Events
SendToHTTP xxx.xxx.xxx.xxx,8080,/json.htm?type=command¶m=switchlight&idx=387&switchcmd=Toggle
E16NEXTION#value = -1
endif
E16NEXTION#idx = -1
endon
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¶m=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
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
Okay ... did not know that. I named it E16Nextion.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
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.After this there are no future log entries of the NEXTION since idx=-1 and the rule ignores it.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
[/qoute]
I only use the ids of Nextion objects. 60 sec thing was still hapening.
IDE 1.8.5 with 2.4.1Lastly, 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
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 ← ");
event->String2 = F("GPIO SS TX → ");
if(AdvHwSerial == true) {
if ((rxPin == 3 && txPin == 1) || (rxPin == 13 && txPin == 15)) {
event->String1 = F("GPIO HW RX ← ");
event->String2 = F("GPIO HW TX → ");
}
}
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
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
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.
So weird as on my wemos my latest code does not show the 60 sec on off behaviour. Tonite i will start from scrap..
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.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 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!).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
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.
I use the basic model.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.
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.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}.
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
}
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)ThomasB wrote: ↑17 Jul 2018, 19:03I use the basic model.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.
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.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}.
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:This method simplifies ESP and home automation rules by pushing some low level work onto the Nextion.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 }
- Thomas
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 ← ");
event->String2 = F("GPIO SS TX → ");
if(AdvHwSerial == true) {
if ((rxPin == 3 && txPin == 1) || (rxPin == 13 && txPin == 15)) {
event->String1 = F("GPIO HW RX ← ");
event->String2 = F("GPIO HW TX → ");
}
}
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
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 buttonsBertB 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.
Code: Select all
1480325 : NEXTION075 : code: ,,
1480328 : EVENT: Nextion#idx=2039.00
1480346 : ACT : SendToHTTP xxx.xxx.xxx.xxx,8080,/json.htm?type=command¶m=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¶m=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
Code: Select all
http://xxx.xxx.xxx.xxx:8080/json.htm?type=command¶m=switchlight&idx=293&switchcmd=Toggle
This is the rule: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.
Code: Select all
on Nextion#idx=2039 do
SendToHTTP xxx.xxx.xxx.xxx,8080,/json.htm?type=command¶m=switchlight&idx=293&switchcmd=Toggle
endon
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?You have limited the number of lines and the max number of characters. I guess it is to limit the memory usage ...
That's a relief the latest Nextion plugin works in the 0719 release.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.
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.
No, I only use the Tough Release Event.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?
Yes it does continue to work just fine.2. Does the Nextion button continue to work correctly after the first press? Or does it only work the first time you press it?
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.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.
Code: Select all
page7.t1.txt="Date %sysmonth%:%sysday%:%sysyears%"
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.Yes it does continue to work just fine.