Getting info about field (and desk) devices

@ScruffR, See…that’s a “smarter” way to do it. By the way, it is __FILE__ (those are double underscores on either end).

The returned filename is fully qualified, so I may do a character search on it to get just the last portion. The date and time are great, too!

Thanks for the constructive feedback! I’ll move forward with your suggestions.

One other thing was this

  String fw = System.version();
  char SystemFW[20];
  fw.toCharArray(SystemFW,15);
  sprintf(buf, "%s", SystemFW);

can be written more concise

  sprintf(buf, "%s", (const char*)System.version());
  // or
  sprintf(buf, "%s", System.version().c_str());

Yup, double underscores.
I’m not sure but __FILENAME__ might be just the file. I’ll have to check GCC compiler variables.
Doesn’t seem to be in the standard.

I wanted to try these out, but the __DATE__and__TIME__ line is not compiling for me (was not declared in this scope error). That one works for you?

Yes, they did. I’ve simplified mine to:

char gDeviceInfo[200];
char buf[15];

  //Publishes info about the device
  sprintf(buf, "%s", (const char*)System.version());
  sprintf(gDeviceInfo,"Application: %s, Date: %s, Time: %s, System firmware: %s, SSID: %s, RSSI: %i",strstr(__FILE__,"//"),__DATE__,__TIME__,buf,WiFi.SSID(),WiFi.RSSI());
  Particle.variable("deviceInfo",gDeviceInfo);
  //

Gettin’ closer to being elegant!

Oh duh, I was reading that as one date and time string, not as two separate things
__DATE__
__TIME__

The lowercase “and” should have been a clue I guess.

How is that working? I don't have any double slash in the raw __FILE__ output.

Hmmmm…well…I’m using Particle Dev. Perhaps that’s at the root of the difference. With out that string function, I’m getting a verrrrrrry long fully-qualified app name.

Yep, that was the difference. In Dev, you get, “//src/appName.cpp” after the long 60 character string, but Build doesn’t have that “//src” in there. Good to know that.

so…what we need to find is the string function that allows us to find the last “/” in the filename and that should do it for both avenues. I thought I had it…but not yet.

Here it is,

strrchr(__FILE__,'/')

This finds the last occurrence of a character (including the terminal NULL character if you want to get the end of a string).

I’ve been using this for a while and it seems safe…

#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)

void setup()
{
  Particle.variable("FileName",__FILENAME__);
}
void loop()
{
  
}

1 Like

@ctmorrison, that buf was just an example :wink:
The maximum conciseness would be with this

  snprintf(gDeviceInfo, sizeof(gDeviceInfo)
          ,"Application: %s, Date: %s, Time: %s, System firmware: %s, SSID: %s, RSSI: %i"
          ,strstr(__FILE__,"//")
          ,__DATE__
          ,__TIME__
          ,(const char*)System.version()  // cast required for String
          ,(const char*)WiFi.SSID()       // cast not required but always safe when in doubt if String or char*
          ,WiFi.RSSI()
          );

(I also added the safety check to obey the buffer boundaries)

The above example also illustrates why I prefer (const char*)stringObject over the widely used alternative stringObject.c_str() since the former always works while the other would throw an error on a non-String.

Since you are looking for the last occurance of a single character you can use strrchr()

(Oops, didn’t see all these posts in between pointing out strrchr() already :blush: - got a rather slow net here)

So, wrapping it all up here with @BulldogLowell’s and @Ric’s tips and @ScruffR’s framework , I think we have:

#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)

char gDeviceInfo[200];

  snprintf(gDeviceInfo, sizeof(gDeviceInfo)
          ,"Application: %s, Date: %s, Time: %s, System firmware: %s, SSID: %s, RSSI: %i"
          ,__FILENAME__
          ,__DATE__
          ,__TIME__
          ,(const char*)System.version()  // cast required for String
          ,(const char*)WiFi.SSID()       // cast not required but always safe when in doubt if String or char*
          ,WiFi.RSSI()
          );

Particle.variable("deviceInfo",gDeviceInfo);

Thanks! I’ll be using this in all of my source code and a slightly different version for Electrons.

4 Likes

@ctmorrison, this is not working for me. Nothing appears after TIME.

@peekay123 Are you getting the short file name (just “projectName.cpp”), or are you getting the whole long version? His code works for me, but if I make it get the whole output of __FILE__, then it stops after the time value due to running out of room in the char array.

@Ric, I get this:
Application: PegasusSPI.cpp, Date: Feb 18 2017, Time: 02:02:22,

@peekay123 hmm… that’s weird. I just re-copied and pasted his code, to make sure mine was identical to his, and it worked fine (Photon, checked by Serial print and variable GET through CLI).

Application: epromlengthproblem.cpp, Date: Feb 18 2017, Time: 02:21:09, System firmware: 0.6.0, SSID: Ric's WiFi, RSSI: -50

@ric, how did you place your code?

@Ric, found the issue. I moved the array declaration to make it global (DOH!).

@peekay123 It was all in setup, except for the declaration of gDeviceInfo which was global.

1 Like