String Manipulation when combining multiple Sensor Values into 1 Publish Event [Resolved]

Background-
This project reads 8 sensors and I originally used the ThingSpeak library and a Photon, worked fine.
I’m starting over to be more bandwidth efficient for an Electron.

I have 8 float variables (CH1 through CH8) containing the Sensor Readings.

I created a webhook from the tutorial Here (GREAT Job btw), and have all 8 ThingSpeak fields updating correctly w/ 1 Decimal Precision via the webhook and 1 Particle.Publish Event every 5 minutes:

EventName & API changed:

 Particle.publish("EVENTNAME", "{ \"1\": \"" + String(CH1,1) + "\", \"2\": \"" + String(CH2,1) + "\", \"3\": \"" + String(CH3,1) + "\", \"4\": \"" + String(CH4,1) + "\", \"5\": \"" + String(CH5,1) + "\", \"6\": \"" + String(CH6,1) + "\", \"7\": \"" + String(CH7,1) + "\", \"8\": \"" + String(CH8,1) + "\", \"k\": \"MyAPI\" }", PRIVATE, NO_ACK);

Many of the sensor values don’t change very often and waste data. The reading in CH8 will change and require updating every 5 minutes & should keep the Electron session alive.

I’m looking for a clean way to evaluate each of the 8 Floats (CH1…CH8) vs their previous value, and then build the Particle.publish String with only the fields that require updating.

In my mind, the single Publish Event breaks down like this:

   Individual String CONTENTS:                           Desc:

         ("EVENTNAME", "{                        //Prefix Info for Publish 
         \"1\": \"" + String(CH1,1) +            //Channel 1 String
    "\", \"2\": \"" + String(CH2,1) +            //Channel 2 String
    "\", \"3\": \"" + String(CH3,1) +            //Channel 3 String
    "\", \"4\": \"" + String(CH4,1) +            //Channel 4 String
    "\", \"5\": \"" + String(CH5,2) +            //Channel 5 String
    "\", \"6\": \"" + String(CH6,1) +            //Channel 6 String
    "\", \"7\": \"" + String(CH7,2) +            //Channel 7 String
    "\", \"8\": \"" + String(CH8,2) +            //Channel 8 String
    "\", \"k\": \"MyAPI\" }", PRIVATE, NO_ACK)   //Suffix Info for Publish 

From my research, this looks like a job for a String Array, but I’m getting nowhere.

All help, suggestions, and comments are greatly appreciated.
Thanks in Advance !

This would be one way (which also avoids the use of dynamic String allocation)

// not verified if it builds, but the concept should work
void fn()
{
  const int precission[8] = {1,1,1,1,2,1,2,2};
  static int oldVal[8] = {0,0,0,0,0,0,0,0}; // equality checks are safer with ints 
  float valF;
  int   valI;
  char msg[128] = "{";
  char valStr[16];
  bool needPublish = false;

  for(int i=0; i<8; i++)
  {
    valF = readFloat(i);
    valI = round(valF * 10);
    if(valI != oldVal[i])
    {
      oldVal[i] = valI;
      snprintf(valStr, sizeof(valStr), "\"%d\":\"%.*f\",", i+1, precission[i], valF);
      strncat(msg, valStr, sizeof(msg)); 
      needPublish=true;
    }
  }
  if(needPublish)
  {
    strncat(msg, "\"k\":\"MyAPI\"}", sizeof(msg));
    Particle.publish("EVENTNAME", msg, PRIVATE, NO_ACK);
  }
}
5 Likes

Thanks for your help ScruffR !
I had to go a slightly different route due to my limited coding skills, but your suggestions were a tremendous help.

Thanks for the help @ScruffR