Changing plugin _P144, how/what is the best way, please advice

Moderators: grovkillen, Stuntteam, TD-er

Post Reply
Message
Author
hoeby
Normal user
Posts: 33
Joined: 19 Sep 2018, 21:03

Changing plugin _P144, how/what is the best way, please advice

#1 Post by hoeby » 21 Sep 2021, 21:30

Last days i used the plugin _P144.
After some troubles to compile, i got it working. And the project where i used this for is finished.

When looking at plugin _P144 i thoughed, this could be a nice project to add things to this plugin.
But what is the best way to do this?
I think the best way is to fork it and do my modifications. After that i could do a pull request.
My progamming skills are very low. That i need some help so now and then.

Because of needing help, is the best to keep it on the forum. And when the code looks finished, then do the pull request?

What are my idea's:
- Add receive function -> already added
- Add timeout on receive function, that it doesn't always runs, only when doing debug
- Add extender function. All codes received will be send again.
- Add mod-fields. If code X is received then code Y will be send.

TD-er
Core team member
Posts: 8643
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: Changing plugin _P144, how/what is the best way, please advice

#2 Post by TD-er » 22 Sep 2021, 11:56

Yep, forking and adding it via a pull request is the way to go.

Please note that it is the best way to create a branch for it.
- Fork the project
- Create a new branch + checkout the new branch
- Copy your modified code to the source tree you checked out in your new branch
- Commit the code
- Push the commit(s) to your own fork
- Move over to the GitHub page (of letscontrolit/ESPEasy) after pushing it, then GitHub will show a yellow-ish banner suggesting to create a pull request
- Create a pull request

This Pull request will be evaluated by me and probably other regular contributors too.
This will result in a number of suggestions to change.
You make the changes, commit them and then push the commit(s)

As soon as you pushed the new commits, they will be automatically appended to the open pull request.

hoeby
Normal user
Posts: 33
Joined: 19 Sep 2018, 21:03

Re: Changing plugin _P144, how/what is the best way, please advice

#3 Post by hoeby » 05 Oct 2021, 20:24

I am running in a issue, which i don't know if i do something wrong. Or i am running to the max of the code.

I am trying to use the Aurel rtx-mid transceiver for the 433mhz plugin.
For this i need 4 gpio's:
1. for the TX data
2. for the RX data
3. for enable function
4. for switching between TX or RX mode.

Made this part in the "case PLUGIN_INIT:"

Code: Select all

if (Settings.TaskDevicePin1[event->TaskIndex] >= 0)  //TX pin
  pinMode(Settings.TaskDevicePin1[event->TaskIndex], OUTPUT);
if (Settings.TaskDevicePin2[event->TaskIndex] >= 0)  //RX pin
  pinMode(Settings.TaskDevicePin2[event->TaskIndex], INPUT_PULLUP);
if (Settings.TaskDevicePin3[event->TaskIndex] >= 0)  //enable pin
  pinMode(Settings.TaskDevicePin3[event->TaskIndex], OUTPUT);
if (Settings.TaskDevicePin4[event->TaskIndex] >= 0)  //TX_RX pin
  pinMode(Settings.TaskDevicePin4[event->TaskIndex], OUTPUT); 
But getting this error:

Code: Select all

error: 'SettingsStruct' has no member named 'TaskDevicePin4'
           pinMode(Settings.TaskDevicePin4[event->TaskIndex], OUTPUT);
Is this because i am running in to the max options of the main code?
Or is there an other way to achieve what i would like to make?

User avatar
Ath
Normal user
Posts: 3416
Joined: 10 Jun 2018, 12:06
Location: NL

Re: Changing plugin _P144, how/what is the best way, please advice

#4 Post by Ath » 05 Oct 2021, 20:38

You can access that 4th 'pin' either by using TaskDevicePort (no numeric addition, and specified as uint8_t instead of int8_t) or by using TaskDevicePin[0]..TaskDevicePin[3]
/Ton (PayPal.me)

TD-er
Core team member
Posts: 8643
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: Changing plugin _P144, how/what is the best way, please advice

#5 Post by TD-er » 05 Oct 2021, 20:59

Better not use that work-around.
If you need more pins, store their pin nr in separate task values.
See the PCONFIG() macro for this.

As an example, see P109, around line 200:

Code: Select all

      addFormPinSelect(F("Button left"),  F("taskdevicepin1"), CONFIG_PIN1);
      addFormPinSelect(F("Button right"), F("taskdevicepin2"), CONFIG_PIN2);
      addFormPinSelect(F("Button mode"),  F("taskdevicepin3"), CONFIG_PIN3);

      addFormPinSelect(F("Relay"),        F("heatrelay"),      PCONFIG(4));
And of course also the places where "heatrelay" is saved and during the PLUGIN_INIT.

hoeby
Normal user
Posts: 33
Joined: 19 Sep 2018, 21:03

Re: Changing plugin _P144, how/what is the best way, please advice

#6 Post by hoeby » 05 Oct 2021, 21:22

thanks for the quick response.

the taskdevicepin0 doesn't work. That gives the same error.
Will have a look at PCONFIG, also thanks for the example, always nice to have a view in other codes

User avatar
Ath
Normal user
Posts: 3416
Joined: 10 Jun 2018, 12:06
Location: NL

Re: Changing plugin _P144, how/what is the best way, please advice

#7 Post by Ath » 05 Oct 2021, 21:24

hoeby wrote: 05 Oct 2021, 21:22 the taskdevicepin0 doesn't work. That gives the same error.
You have probably left out the square braces, TaskDevicePin[0]..TaskDevicePin[3], it is an array with 4 elements.
/Ton (PayPal.me)

hoeby
Normal user
Posts: 33
Joined: 19 Sep 2018, 21:03

Re: Changing plugin _P144, how/what is the best way, please advice

#8 Post by hoeby » 05 Oct 2021, 21:26

Could it be the example number was wrong?
For example P109 line 200, i can't fine anything about PCONFIG

https://github.com/letscontrolit/ESPEas ... ol_Pro.ino

User avatar
Ath
Normal user
Posts: 3416
Joined: 10 Jun 2018, 12:06
Location: NL

Re: Changing plugin _P144, how/what is the best way, please advice

#9 Post by Ath » 05 Oct 2021, 21:30

Try the official ESPEasy repo, not the playground: https://github.com/letscontrolit/ESPEas ... #L199-L203
/Ton (PayPal.me)

hoeby
Normal user
Posts: 33
Joined: 19 Sep 2018, 21:03

Re: Changing plugin _P144, how/what is the best way, please advice

#10 Post by hoeby » 05 Oct 2021, 22:29

Thanks for the link.
Tried to add it. Errors are gone and the extra gpio field is there.
For now, there are 2 gpio fields to much in there, see the yellow gpio fields. Don't know yet why, have to search for it, but not today.
Tried a quick test, the Aurel doens't work, transceiver function needs work.
Testing with a cheap 433 receiver, then the code works. But this doens't need the extra 2 gpio's
whygpio12.JPG
whygpio12.JPG (39.5 KiB) Viewed 6876 times
This is my code, sorry i am not a progammer, just hobby.
Could be that there are things, where you think: why did he do that

Code: Select all

#include "_Plugin_Helper.h"
//#ifdef USES_P144


//#######################################################################################################
//#################################### Plugin 144: RC-Switch TX #########################################
//#######################################################################################################
// written by Jochen Krapf (jk@nerd2nerd.org)
// 21-09-2021: Forked by PH
// 21-09-2021: Added receive 433mhz code

// List of commands:
// (1) RC,<param>
// (2) RC,<param>,<param>,<param>

// List of RC params:
// (a) SEND=<binary_code>
//     Send binary code with any length ("RC,SEND=000000000001010100010001")
// (b) SEND=<tristate_code>
//     Send tristate code with any length ("RC,SEND=00000FFF0F0F")
// (c) SENDDEC=<decimal_code>
//     Send 24 bit decimal code ("RC,SENDDEC=5393")
// (d) ON=<binary_code>
//     Send binary code for simple 10 DIP switch devices ("RC,ON=1010100010")
// (e) ON=<1..4><1..4>
//     Send switch position for simple 2 rotary switch devices ("RC,ON=42")
// (f) ON=<a..f><1..4><1..4>
//     Send switch position for Intertechno devices ("RC,ON=a42")
// (f) OFF=   as ON...
// (g) PROTOCOL=<number>
//     Set protocoln for devices ("RC,PROTOCOL=2") default=1
// (h) PULSE=<number>
//     Set pulse length ("RC,PULSE=320") default=320
// (i) REPEAT=<number>
//     Set number of transmission repeats ("RC,REPEAT=15") default=?
//
// Combinations:
// e.g. "RC,PROTOCOL=2,PULSE=320,REPEAT=15,SEND=000000000001010100010001"

#include <RCSwitch.h>   //https://github.com/sui77/rc-switch.git

static RCSwitch Plugin_144_RC = RCSwitch();

#define PLUGIN_144
#define PLUGIN_ID_144         144
#define PLUGIN_NAME_144       "RC-Switch TX"
#define PLUGIN_ValueNAME1_144 "RF"


boolean Plugin_144(byte function, struct EventStruct *event, String& string)
{
  boolean success = false;

  switch (function)
  {
    case PLUGIN_DEVICE_ADD:
      {
        Device[++deviceCount].Number = PLUGIN_ID_144;
        Device[deviceCount].Type = DEVICE_TYPE_DUAL;
        Device[deviceCount].Ports = 0;
        Device[deviceCount].VType = Sensor_VType::SENSOR_TYPE_DUAL;
        Device[deviceCount].PullUpOption = false;
        Device[deviceCount].InverseLogicOption = false;
        Device[deviceCount].FormulaOption = false;
        Device[deviceCount].ValueCount = 1;
        Device[deviceCount].SendDataOption = true;
        Device[deviceCount].TimerOption = false;
        Device[deviceCount].TimerOptional = false;
        Device[deviceCount].GlobalSyncOption = true;
        break;
      }

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

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

    case PLUGIN_WEBFORM_LOAD:
      {  
        addFormPinSelect(F("TX-GPIO"),  F("taskdevicepin1"), CONFIG_PIN1);
        addFormPinSelect(F("RX-GPIO"),  F("taskdevicepin2"), CONFIG_PIN2);
//      addFormCheckBox(F("Use transceiver"), F("transceiver"), PCONFIG(1));    //future work
        addFormPinSelect(F("Enable-GPIO"),  F("taskdevicepin3"), CONFIG_PIN3);
        addFormPinSelect(F("TX_RX Toggle-GPIO"),  F("taskdevicetoggle"), PCONFIG(2));
        
        success = true;
        break;
      }

    case PLUGIN_WEBFORM_SAVE:
      {
//        PCONFIG(1)       = isFormItemChecked(F("transceiver"));    //future work
        PCONFIG(2)       = getFormItemInt(F("taskdevicetoggle"));
        success = true;
        break;
      }

    case PLUGIN_INIT:
      {
        if (CONFIG_PIN1 >= 0) //TX-pin
        {
          pinMode(CONFIG_PIN1, OUTPUT);
          String log = F("RC-Sw: Send Pin ");
          log += CONFIG_PIN1;
          log += F(" ");

          Plugin_144_RC.enableTransmit(CONFIG_PIN1);

          addLog(LOG_LEVEL_INFO, log);
        }

        if (CONFIG_PIN2 >= 0) // RX-pin
        {
          pinMode(CONFIG_PIN2, INPUT_PULLUP);
          String log = F("RC-Sw: Receive pin ");
          log += CONFIG_PIN2;
          log += F(" ");

          Plugin_144_RC.enableReceive(CONFIG_PIN2);

          addLog(LOG_LEVEL_INFO, log);
        }

        if (CONFIG_PIN3 >= 0)  //enable pin
          pinMode(CONFIG_PIN3, OUTPUT);
        if (PCONFIG(2) >= 0)  //TX_RX pin
          pinMode(PCONFIG(2), OUTPUT);  
        

        //Prefix Enable and TX_RX pin to low
        digitalWrite (CONFIG_PIN3, LOW);
        digitalWrite (PCONFIG(2), LOW);
        
        //Set transceiver to RX after powerdown
        digitalWrite (CONFIG_PIN3, HIGH);
        delayMicroseconds(20);
        digitalWrite (PCONFIG(2), HIGH);
        delayMicroseconds(200);
        digitalWrite (PCONFIG(2), LOW);
        delayMicroseconds(40);
        digitalWrite (CONFIG_PIN3, LOW);
        delayMicroseconds(20);
        digitalWrite (CONFIG_PIN3, HIGH);
        delayMicroseconds(200);

        success = true;
        break;
      }

      case PLUGIN_ONCE_A_SECOND:
        {
          if (CONFIG_PIN2 >= 0) {
            if (UserVar[event->BaseVarIndex] != 0) {
              UserVar[event->BaseVarIndex] = (0);
            }
            
            if (Plugin_144_RC.available())
              {
                Serial.print("RF recieved");
                int valuerf = Plugin_144_RC.getReceivedValue();

                if (valuerf == 0) {
                  String log = F("RF Code Recieved: ");
                  log += String(valuerf);
                  log += " =Unknown encoding";
                  addLog(LOG_LEVEL_INFO, log);
        
                } else {

                   int databuffer[64]; // get a copy of the received timings before they are overwritten
                   int numberoftimings = 2 * Plugin_144_RC.getReceivedBitlength() + 2;
                   if(numberoftimings > 64) numberoftimings = 64;
                   for (int i = 0; i < numberoftimings; i++) {
                     databuffer[i] = Plugin_144_RC.getReceivedRawdata()[i];
                   }

                   String printSerial1 = F("Received ");
                   printSerial1 += ( Plugin_144_RC.getReceivedValue() );
                   printSerial1 += F(" / ");
                   printSerial1 += ( Plugin_144_RC.getReceivedBitlength() );
                   printSerial1 += F("bit ");
                   printSerial1 += F("Protocol: ");
                   printSerial1 += ( Plugin_144_RC.getReceivedProtocol() );
                   addLog(LOG_LEVEL_INFO, printSerial1);
                   
                   unsigned int databitsoffset = abs( (int)Plugin_144_RC.getReceivedLevelInFirstTiming() - (int)Plugin_144_RC.getReceivedInverted());
                   
                   unsigned long dataduration = 0;
                   for (unsigned int i = 1 + databitsoffset; i < numberoftimings - 1 + databitsoffset; i++) {
                     dataduration += databuffer[i];
                   }
                   String printSerial2 = F("data bits of pulse train duration: ");
                   printSerial2 += ( dataduration );
                   addLog(LOG_LEVEL_INFO, printSerial2);

                   unsigned int averagebitduration = (int)(0.5 + ((double)dataduration)/Plugin_144_RC.getReceivedBitlength());
                   unsigned int protocolratio = (unsigned int)(0.5 + ((double)(averagebitduration - Plugin_144_RC.getReceivedDelay())) / (double)Plugin_144_RC.getReceivedDelay());
                   String printSerial3 = F("proposed protocol: { ");
                   printSerial3 += (Plugin_144_RC.getReceivedDelay());
                   printSerial3 += F(", { ");
                   printSerial3 += ( (databitsoffset==0) ? 
                   (int) (0.5 + (double)databuffer[2*Plugin_144_RC.getReceivedBitlength()+1]/(double)Plugin_144_RC.getReceivedDelay())
                   :
                   (int) (0.5 + (double)databuffer[0]/(double)Plugin_144_RC.getReceivedDelay())
                   );
                   printSerial3 += F(", ");
                   printSerial3 += ( (databitsoffset==0) ?
                   (int) (0.5 + (double)databuffer[0]/(double)Plugin_144_RC.getReceivedDelay())
                   :
                   (int) (0.5 + (double)databuffer[1]/(double)Plugin_144_RC.getReceivedDelay())
                   );
                   printSerial3 += F(" }, { ");
                   printSerial3 += F("1");
                   printSerial3 += F(", ");
                   printSerial3 += (protocolratio);
                   printSerial3 += F(" }, { ");
                   printSerial3 += (protocolratio);
                   printSerial3 += F(", ");
                   printSerial3 += F("1");
                   printSerial3 += F(" }, ");
                   printSerial3 += ((Plugin_144_RC.getReceivedInverted()) ? "true" : "false" );
                   printSerial3 += F(" }");
                   addLog(LOG_LEVEL_INFO, printSerial3);

                   binair(Plugin_144_RC.getReceivedValue(), Plugin_144_RC.getReceivedBitlength());

                   UserVar[event->BaseVarIndex] = (valuerf);
                   sendData(event);
                                
                }
              Plugin_144_RC.resetAvailable();
            }
            success = true;
            break;
          }
        }
  
    case PLUGIN_WRITE:
      {
        if (CONFIG_PIN1 >= 0) {
          String command = parseString(string, 1);

          if (command == F("rc")) {
            String param;
            byte paramIdx = 2;

            string.replace("  ", " ");
            string.replace(" =", "=");
            string.replace("= ", "=");

            param = parseString(string, paramIdx++);
            while (param.length()) {
              addLog(LOG_LEVEL_DEBUG_MORE, param);

              int index = param.indexOf('=');
              if (index > 0) {
                String paramKey = param.substring(0, index);
                String paramVal = param.substring(index+1);
                paramKey.toUpperCase();

                addLog(LOG_LEVEL_DEBUG_MORE, paramKey);
                addLog(LOG_LEVEL_DEBUG_MORE, paramVal);

                if (paramKey == F("SEND")) {
                  if (paramVal.indexOf("F") >= 0)
                    Plugin_144_RC.sendTriState(&(paramVal[0]));
                  else
                    Plugin_144_RC.send(&(paramVal[0]));
                }
                if (paramKey == F("SENDDEC")) {
                  Plugin_144_RC.send(paramVal.toInt(), 24);
                }
                if (paramKey == F("ON")) {
                  if (paramVal.length()==10)   //simple 10 DIP switch
                    Plugin_144_RC.switchOn(&(paramVal.substring(0, 5)[0]), &(paramVal.substring(5)[0]));
                  else if (paramVal.length()==2)   //2x rotary switch 1..4
                    Plugin_144_RC.switchOn(paramVal[0]-'0', paramVal[1]-'0');
                  else if (paramVal.length()==3)   //Intertechno outlets
                    Plugin_144_RC.switchOn(paramVal[0], paramVal[1]-'0', paramVal[2]-'0');
                }
                if (paramKey == F("OFF")) {
                  if (paramVal.length()==10)   //simple 10 DIP switch
                    Plugin_144_RC.switchOff(&(paramVal.substring(0, 5)[0]), &(paramVal.substring(5)[0]));
                  else if (paramVal.length()==2)   //2x rotary switch 1..4
                    Plugin_144_RC.switchOff(paramVal[0]-'0', paramVal[1]-'0');
                  else if (paramVal.length()==3)   //Intertechno outlets
                    Plugin_144_RC.switchOn(paramVal[0], paramVal[1]-'0', paramVal[2]-'0');
                }
                if (paramKey == F("PROTOCOL")) {
                  Plugin_144_RC.setProtocol(paramVal.toInt());
                }
                if (paramKey == F("PULSE")) {
                  Plugin_144_RC.setPulseLength(paramVal.toInt());
                }
                if (paramKey == F("REPEAT")) {
                  Plugin_144_RC.setRepeatTransmit(paramVal.toInt());
                }
              }

              param = parseString(string, paramIdx++);
            }

            success = true;
          }

          break;
        }
      }

    case PLUGIN_READ:
      {
        //no values
        success = true;
        break;
      }

  }
  return success;
}

/* extended logging, for in terminal monitor */
static char * dec2binWzerofill(unsigned long Dec, unsigned int bitLength);

void binair(unsigned long decimal, unsigned int length) {
      if (decimal == 0) {
        Serial.print("Unknown encoding.");
      } else {
        const char* b = dec2binWzerofill(decimal, length);
          String printBinary = F("Binary: "); 
          printBinary += b;
          addLog(LOG_LEVEL_INFO, printBinary);

          String url = String(NetworkLocalIP().toString()) + "/control?cmd=RC";
          String printString = F("Use this command: http://");
          printString += url;
          printString += F(",PROTOCOL=");
          printString += ( Plugin_144_RC.getReceivedProtocol() );
          printString += F(",REPEAT=1,SEND=");
          printString += b;
          printString += F("");
          addLog(LOG_LEVEL_INFO, printString);
      }
}

static char * dec2binWzerofill(unsigned long Dec, unsigned int bitLength) {
        static char bin[64];
        unsigned int i=0;

        while (Dec > 0) {
                bin[32+i++] = ((Dec & 1) > 0) ? '1' : '0';
                Dec = Dec >> 1;
        }

        for (unsigned int j = 0; j< bitLength; j++) {
                if (j >= bitLength - i) {
                        bin[j] = bin[ 31 + i - (j - (bitLength - i)) ];
                } else {
                        bin[j] = '0';
                }
        }
        bin[bitLength] = '\0';

        return bin;
}
//#endif

TD-er
Core team member
Posts: 8643
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: Changing plugin _P144, how/what is the best way, please advice

#11 Post by TD-er » 05 Oct 2021, 22:37

This line determines the default pin selectors:

Code: Select all

 Device[deviceCount].Type = DEVICE_TYPE_DUAL;
 
In DeviceStruct.h the alternative values are defined.

You can also set the labels for the first N (upto 3) pin select comboboxes via the plugin call: PLUGIN_GET_DEVICEGPIONAMES

hoeby
Normal user
Posts: 33
Joined: 19 Sep 2018, 21:03

Re: Changing plugin _P144, how/what is the best way, please advice

#12 Post by hoeby » 25 Oct 2021, 09:50

Still working on the code.
It is hobby and i am not a programmer guy, so it takes time.

But i am running in a challenge i can't find how to solve.

When i fire a 64-bits code, this is in the log (sync bit makes it 65 bit)
  • 211038: RFcode: Protocol: 1, 65 bit
    211038: RFcode: Data bits of pulse train duration: 34339
    211040: RFcode: Proposed protocol: { 350, { 3067712, 142 }, { 1, 1 }, { 1, 1 }, false }
    211041: RFcode: Binary: 00110000101111001101010110010011001100110011110011001100110011001
    211042: RFcode: Decimal: 7023833275277351321
    211043: RFcode: http://192.168.178.164/control?cmd=RC,P ... 0110011001
    585088: EVENT: 433test#RF=7023833110349350761
Where the challenge is, that line 211042 is the correct value. And i want this to send to the UserVar[event->BaseVarIndex]
But when looking at line 585088, this is the event, but the value is different. I can't find out why.
Tried different ways to archieve the same result in value, but without luck.
It works when max 26bits are send. Everything more then 26 bits gives a wrong value
What am i doing wrong?

On line 250 i write the UserVar[event->BaseVarIndex]
On line 390 the correct value is set for Decimal

This is the plugin code (for now) what i have

Code: Select all

#ifdef USES_P144
//#######################################################################################################
//#################################### Plugin 144: RC-Switch TX #########################################
//#######################################################################################################
// written by Jochen Krapf (jk@nerd2nerd.org)
// 21-09-2021: Forked by Paul Hermans
// 21-09-2021: Added receive 433mhz code
// 24-10-2021: Added 64 bits send/receive (senddec not possible anymore)

// List of commands:
// (1) RC,<param>
// (2) RC,<param>,<param>,<param>

// List of RC params:
// (a) SEND=<binary_code>
//     Send binary code with any length ("RC,SEND=000000000001010100010001")
// (b) SEND=<tristate_code>
//     Send tristate code with any length ("RC,SEND=00000FFF0F0F")
// (d) ON=<binary_code>
//     Send binary code for simple 10 DIP switch devices ("RC,ON=1010100010")
// (e) ON=<1..4><1..4>
//     Send switch position for simple 2 rotary switch devices ("RC,ON=42")
// (f) ON=<a..f><1..4><1..4>
//     Send switch position for Intertechno devices ("RC,ON=a42")
// (f) OFF=   as ON...
// (g) PROTOCOL=<number>
//     Set protocoln for devices ("RC,PROTOCOL=2") default=1
// (h) PULSE=<number>
//     Set pulse length ("RC,PULSE=320") default=320
// (i) REPEAT=<number>
//     Set number of transmission repeats ("RC,REPEAT=15") default=?
//
// Combinations:
// e.g. "RC,PROTOCOL=2,PULSE=320,REPEAT=15,SEND=000000000001010100010001"

#include "_Plugin_Helper.h"
#include <RCSwitch64.h>  

static RCSwitch64 Plugin_144_RC = RCSwitch64();
static char Str[24];      

#define PLUGIN_144
#define PLUGIN_ID_144         144
#define PLUGIN_NAME_144       "RC-Switch TX"
#define PLUGIN_ValueNAME1_144 "RF"

boolean Plugin_144(byte function, struct EventStruct *event, String& string)
{
  boolean success = false;
  
  switch (function)
  {
    case PLUGIN_DEVICE_ADD:
      {
        Device[++deviceCount].Number = PLUGIN_ID_144;
        //Device[deviceCount].Type = DEVICE_TYPE_DUAL;
        Device[deviceCount].Ports = 0;
        Device[deviceCount].VType = Sensor_VType::SENSOR_TYPE_DUAL;
        Device[deviceCount].PullUpOption = false;
        Device[deviceCount].InverseLogicOption = false;
        Device[deviceCount].FormulaOption = false;
        Device[deviceCount].ValueCount = 1;
        Device[deviceCount].SendDataOption = true;
        Device[deviceCount].TimerOption = false;
        Device[deviceCount].TimerOptional = false;
        Device[deviceCount].GlobalSyncOption = true;
        break;
      }

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

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

    case PLUGIN_WEBFORM_LOAD:
      {  
        addFormPinSelect(F("TX-GPIO"),  F("taskdevicepin1"), CONFIG_PIN1);
        addFormPinSelect(F("RX-GPIO"),  F("taskdevicepin2"), CONFIG_PIN2);
//      addFormCheckBox(F("Use transceiver"), F("transceiver"), PCONFIG(1));    //future work
        addFormPinSelect(F("Enable-GPIO"),  F("taskdevicepin3"), CONFIG_PIN3);
        addFormPinSelect(F("TX_RX Toggle-GPIO"),  F("taskdevicetxpin"), PCONFIG(2));
        
        success = true;
        break;
      }

    case PLUGIN_WEBFORM_SAVE:
      {
//        PCONFIG(1)       = isFormItemChecked(F("transceiver"));    //future work
        PCONFIG(2)       = getFormItemInt(F("taskdevicetxpin"));
        success = true;
        break;
      }

    case PLUGIN_INIT:
      {
        UserVar[event->BaseVarIndex] = 0;

        if (CONFIG_PIN1 >= 0) //TX-pin
        {
          pinMode(CONFIG_PIN1, OUTPUT);
          String log = F("RC-Sw: Send Pin ");
          log += CONFIG_PIN1;
          log += F(" ");

          Plugin_144_RC.enableTransmit(CONFIG_PIN1);

          addLog(LOG_LEVEL_INFO, log);
        }

        if (CONFIG_PIN2 >= 0) // RX-pin
        {
          pinMode(CONFIG_PIN2, INPUT_PULLUP);
          String log = F("RC-Sw: Receive pin ");
          log += CONFIG_PIN2;
          log += F(" ");

          Plugin_144_RC.enableReceive(CONFIG_PIN2);

          addLog(LOG_LEVEL_INFO, log);
        }

        if (CONFIG_PIN3 >= 0)  //enable pin
          pinMode(CONFIG_PIN3, OUTPUT);
        if (PCONFIG(2) >= 0)  //TX_RX pin
          pinMode(PCONFIG(2), OUTPUT);  
        

        //Prefix Enable and TX_RX pin to low
        digitalWrite (CONFIG_PIN3, LOW);
        digitalWrite (PCONFIG(2), LOW);
        delayMicroseconds(500);


        //Set transceiver to RX after powerdown
        digitalWrite (CONFIG_PIN3, HIGH);
        delayMicroseconds(20);
        digitalWrite (PCONFIG(2), HIGH);
        delayMicroseconds(200);
        digitalWrite (PCONFIG(2), LOW);
        delayMicroseconds(40);
        digitalWrite (CONFIG_PIN3, LOW);
        delayMicroseconds(20);
        digitalWrite (CONFIG_PIN3, HIGH);
        delayMicroseconds(200);

        success = true;
        break;
      }

      case PLUGIN_ONCE_A_SECOND:
        {
          if (CONFIG_PIN2 >= 0) {
            if (UserVar[event->BaseVarIndex] != 0) {
              UserVar[event->BaseVarIndex] = (0);
            }
            
            if (Plugin_144_RC.available())
              {
                Serial.print("RF recieved");
                int valuerf = Plugin_144_RC.getReceivedValue();

                if (valuerf == 0) {
                  String log = F("RFcode: ");
                  log += String(valuerf);
                  log += " =Unknown encoding";
                  addLog(LOG_LEVEL_INFO, log);
        
                } else {

                   int databuffer[128]; // get a copy of the received timings before they are overwritten
                   int numberoftimings = 2 * Plugin_144_RC.getReceivedBitlength() + 2;
                   if(numberoftimings > 128) numberoftimings = 128;
                   for (int i = 0; i < numberoftimings; i++) {
                     databuffer[i] = Plugin_144_RC.getReceivedRawdata()[i];
                   }

                   String printEmpty = F("");
                   addLog(LOG_LEVEL_INFO, printEmpty);

                   String printSerial1 = F("RFcode: ");
                   printSerial1 += F("Protocol: ");
                   printSerial1 += ( Plugin_144_RC.getReceivedProtocol() );
                   printSerial1 += F(", ");
                   printSerial1 += ( Plugin_144_RC.getReceivedBitlength() );
                   printSerial1 += F(" bit");
                   addLog(LOG_LEVEL_INFO, printSerial1);
                   
                   unsigned int databitsoffset = abs( (int)Plugin_144_RC.getReceivedLevelInFirstTiming() - (int)Plugin_144_RC.getReceivedInverted());
                   
                   unsigned long dataduration = 0;
                   for (unsigned int i = 1 + databitsoffset; i < numberoftimings - 1 + databitsoffset; i++) {
                     dataduration += databuffer[i];
                   }
                   String printSerial2 = F("RFcode: ");
                   printSerial2 += F("Data bits of pulse train duration: ");
                   printSerial2 += ( dataduration );
                   addLog(LOG_LEVEL_INFO, printSerial2);

                   unsigned int averagebitduration = (int)(0.5 + ((double)dataduration)/Plugin_144_RC.getReceivedBitlength());
                   unsigned int protocolratio = (unsigned int)(0.5 + ((double)(averagebitduration - Plugin_144_RC.getReceivedDelay())) / (double)Plugin_144_RC.getReceivedDelay());
                   String printSerial3 = F("RFcode: ");
                   printSerial3 += F("Proposed protocol: { ");
                   printSerial3 += (Plugin_144_RC.getReceivedDelay());
                   printSerial3 += F(", { ");
                   printSerial3 += ( (databitsoffset==0) ? 
                   (int) (0.5 + (double)databuffer[2*Plugin_144_RC.getReceivedBitlength()+1]/(double)Plugin_144_RC.getReceivedDelay())
                   :
                   (int) (0.5 + (double)databuffer[0]/(double)Plugin_144_RC.getReceivedDelay())
                   );
                   printSerial3 += F(", ");
                   printSerial3 += ( (databitsoffset==0) ?
                   (int) (0.5 + (double)databuffer[0]/(double)Plugin_144_RC.getReceivedDelay())
                   :
                   (int) (0.5 + (double)databuffer[1]/(double)Plugin_144_RC.getReceivedDelay())
                   );
                   printSerial3 += F(" }, { ");
                   printSerial3 += F("1");
                   printSerial3 += F(", ");
                   printSerial3 += (protocolratio);
                   printSerial3 += F(" }, { ");
                   printSerial3 += (protocolratio);
                   printSerial3 += F(", ");
                   printSerial3 += F("1");
                   printSerial3 += F(" }, ");
                   printSerial3 += ((Plugin_144_RC.getReceivedInverted()) ? "true" : "false" );
                   printSerial3 += F(" }");
                   addLog(LOG_LEVEL_INFO, printSerial3);

                   binair(Plugin_144_RC.getReceivedValue(), Plugin_144_RC.getReceivedBitlength());

//char* dec(uint64_t n);
//uint64_t cvttoull(const char *res);
//uint64_t val = cvttoull(Str);

//UserVar[event->BaseVarIndex] = (val);


                   String string_val = (Str);
                   float float_var;
                   float_var = string_val.toFloat();
            
                   UserVar[event->BaseVarIndex] = (float_var);
                   //UserVar[event->BaseVarIndex] = (valuerf);
                   sendData(event);

                }

              Plugin_144_RC.resetAvailable();
            }
            success = true;
            break;
          }
        }

        
  
    case PLUGIN_WRITE:
      {
        if (PCONFIG(2) >= 0) {
          String command = parseString(string, 1);

          if (command == F("rc")) {
            String param;
            byte paramIdx = 2;

            string.replace("  ", " ");
            string.replace(" =", "=");
            string.replace("= ", "=");

            param = parseString(string, paramIdx++);
            while (param.length()) {
              addLog(LOG_LEVEL_DEBUG_MORE, param);

              int index = param.indexOf('=');
              if (index > 0) {
                String paramKey = param.substring(0, index);
                String paramVal = param.substring(index+1);
                paramKey.toUpperCase();

                addLog(LOG_LEVEL_DEBUG_MORE, paramKey);
                addLog(LOG_LEVEL_DEBUG_MORE, paramVal);

                if (paramKey == F("SEND")) {
                  if (paramVal.indexOf("F") >= 0)
                    Plugin_144_RC.sendTriState(&(paramVal[0]));
                  else
                    Plugin_144_RC.send(&(paramVal[0]));
                }
                if (paramKey == F("ON")) {
                  if (paramVal.length()==10)   //simple 10 DIP switch
                    Plugin_144_RC.switchOn(&(paramVal.substring(0, 5)[0]), &(paramVal.substring(5)[0]));
                  else if (paramVal.length()==2)   //2x rotary switch 1..4
                    Plugin_144_RC.switchOn(paramVal[0]-'0', paramVal[1]-'0');
                  else if (paramVal.length()==3)   //Intertechno outlets
                    Plugin_144_RC.switchOn(paramVal[0], paramVal[1]-'0', paramVal[2]-'0');
                }
                if (paramKey == F("OFF")) {
                  if (paramVal.length()==10)   //simple 10 DIP switch
                    Plugin_144_RC.switchOff(&(paramVal.substring(0, 5)[0]), &(paramVal.substring(5)[0]));
                  else if (paramVal.length()==2)   //2x rotary switch 1..4
                    Plugin_144_RC.switchOff(paramVal[0]-'0', paramVal[1]-'0');
                  else if (paramVal.length()==3)   //Intertechno outlets
                    Plugin_144_RC.switchOn(paramVal[0], paramVal[1]-'0', paramVal[2]-'0');
                }
                if (paramKey == F("PROTOCOL")) {
                  Plugin_144_RC.setProtocol(paramVal.toInt());
                }
                if (paramKey == F("PULSE")) {
                  Plugin_144_RC.setPulseLength(paramVal.toInt());
                }
                if (paramKey == F("REPEAT")) {
                  Plugin_144_RC.setRepeatTransmit(paramVal.toInt());
                }
              }

              param = parseString(string, paramIdx++);
            }

            success = true;
          }

          break;
        }
      }

    case PLUGIN_READ:
      {
        //no values
        success = true;
        break;
      }

  }
  return success;
}

/* extended logging, for in terminal monitor */
static char * dec2binWzerofill(unsigned long long Dec, unsigned int bitLength);
static char * dec(unsigned long long Dec);

void binair(unsigned long long decimal, unsigned int length) {
      if (decimal == 0) {
        Serial.print("Unknown encoding.");
      } else {
        const char* b = dec2binWzerofill(decimal, length);

        String printBinary = F("RFcode: ");              
        printBinary += F("Binary: "); 
        printBinary += b;
        addLog(LOG_LEVEL_INFO, printBinary);

        String printDecimal = F("RFcode: ");
        printDecimal += F("Decimal: ");
        const char* d = dec(decimal);
        printDecimal += d;
        addLog(LOG_LEVEL_INFO, printDecimal);
 
        String url = String(NetworkLocalIP().toString()) + "/control?cmd=RC";
        String printString = F("RFcode: http://");
        printString += url;
        printString += F(",PROTOCOL=");
        printString += ( Plugin_144_RC.getReceivedProtocol() );
        printString += F(",SEND=");
        printString += b;
        printString += F("");
        addLog(LOG_LEVEL_INFO, printString);

        String printEmpty = F("");
        addLog(LOG_LEVEL_INFO, printEmpty);
      }
}

//uint64_t cvttoull(const char *res) {
//  uint64_t result = 0;
//  while (*res) {
//    result *= 10;
//    result += *res++ - '0';
//  }
//  return result;
//}

static char * dec (unsigned long long Dec) {
      //static char Str[20];      
      sprintf(Str, "%lld", Dec);
      return Str;
}

static char * dec2binWzerofill(unsigned long long Dec, unsigned int bitLength) {

        static char bin[128];
        unsigned int i=0;

        while (Dec > 0) {
                bin[64+i++] = ((Dec & 1) > 0) ? '1' : '0';
                Dec = Dec >> 1;
        }

        for (unsigned int j = 0; j< bitLength; j++) {
                if (j >= bitLength - i) {
                        bin[j] = bin[ 63 + i - (j - (bitLength - i)) ];
                } else {
                        bin[j] = '0';
                }
        }
        bin[bitLength] = '\0';
        
        return bin;
}
#endif

User avatar
Ath
Normal user
Posts: 3416
Joined: 10 Jun 2018, 12:06
Location: NL

Re: Changing plugin _P144, how/what is the best way, please advice

#13 Post by Ath » 25 Oct 2021, 10:56

hoeby wrote: 25 Oct 2021, 09:50 It works when max 26bits are send. Everything more then 26 bits gives a wrong value
What am i doing wrong?
The trouble you will run into, I assume, is that the value retrieved from the RF reader is 64 bit, and the UserVar[] array can only hold float values (32 bit, effectively usable up to 26 bit int values).
To overcome that, a method has been added to that type to use 2 floats to store an unsigned 64 bit number, as can be found in the RFID plugin. And a little above that line there is also the 'get' equivalent to retrieve the value, if needed.
/Ton (PayPal.me)

hoeby
Normal user
Posts: 33
Joined: 19 Sep 2018, 21:03

Re: Changing plugin _P144, how/what is the best way, please advice

#14 Post by hoeby » 25 Oct 2021, 11:02

Thanks for your reply.
I am going to look at your provided information

Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 34 guests