Getting device name

I have the following code which I like to include in all of my applications so I know what application each device is running and what version(date) of the application and OS by simply requesting the associated Particle variable:

#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
char gDeviceInfo [200] = "";
void updateDeviceInfo() {
  snprintf(gDeviceInfo, sizeof(gDeviceInfo)
          ,"Application: %s, Date: %s, Time: %s, System firmware: %s, SSID: %s"
          ,__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*
          );
}

I also have this in setup()

updateDeviceInfo();
Particle.variable("deviceInfo",gDeviceInfo);

I would like to include the actual name of the device in this Particle variable and so I made the following changes:

gDeviceName  char [40] = "";
void nameHandler(const char *topic,const char *data) {
  strncpy(gDeviceName,data,sizeof(gDeviceName-1));
  updateDeviceInfo();
}

I also added the following to setup();

Particle.subscribe("particle/device/name",nameHandler);
Particle.publish("particle/device/name",PRIVATE);

and modified my updateDeviceInfo to this:

void updateDeviceInfo() {
  snprintf(gDeviceInfo, sizeof(gDeviceInfo)
          ,"Name: %s, Application: %s, Date: %s, Time: %s, System firmware: %s, SSID: %s"
          ,(const char*)gDeviceName
          ,__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*
          );
}

I’m finally getting SOMETHING out for Name, but only 4 characters. The actual device name is MailboxChimeMonitor, but here’s the output when I look at deviceInfo:

Name: Mail, Application: MailboxChimeMonitor.ino, Date: Jan  5 2021, Time: 15:44:29, System firmware: 2.0.1, SSID: HVAC Star 2.4

I’ve been looking at this too long and can’t see the forest for the trees, as they say. Suggestions would be greatly appreciated!

Not sure what this syntax is.
Didn’t you rather mean to write

char gDeviceName[40] = "";

Also in order to debug your subscribe handler you may want to add some Serial.print() statements to monitor the incoming and outgoing data :wink:

Hahaha…typed too fast. It’s actually what you had suggested…my brain was not engaged with my fingers.

The device is remote, so I might have to try with one that’s local. However, other than my mis-typing above, everything else must look “reasonable”. Thanks!

I think you want:

strncpy(gDeviceName,data,sizeof(gDeviceName)-1);

not

strncpy(gDeviceName,data,sizeof(gDeviceName-1));

I’m kind of surprised that compiled.

1 Like

:man_facepalming:…I just couldn’t see it. Thanks! Yay!!! It’s working now!

By the way, does this technique work for all device types (Argon, Boron, Electron and Photon)?

Also, what are the timing considerations? I have an Electron and used the above code, but seemed to have problems when I had the Particle.subscribe() in setup() followed by the Particle.publish(). Does best practice require some time pass between the two statement executions?

I ended up putting the Particle.publish() in a portion of the loop() function and that resolved the issue.

Yes, putting Particle.subscribe() in setup() and calling Particle.publish() from loop() after Particle.connected() returns true is the recommended method when using system thread mode.

If you use non-threaded AUTOMATIC mode the example in the docs works as-is, but it’s on the list to fix the basic example so it works properly if threading is enabled. Essentially, it’s possible to get into a situation where the publish goes out and the result comes back before the subscription is complete if you do both back-to-back in certain modes.

1 Like