I am using Twilio along with Webhooks to send SMS’s to notify users of a condition indicating need for repair at various locations (NORTH, CENTRAL, SOUTH, etc. x 100). When creating the Webhook, I found the documentation stating that the pre-defined webhooks available for use in the message Body only include DEVICE ID, EVENT NAME, EVENT VALUE, and PUBLISHED AT.
However, I have named each device according to location and the repair notification process would be greatly simplified if the SMS included the Device Name instead of the Device ID. Is there a simple way to include the Device Name in the SMS rather than or in addition to the Device ID. This is possible using IFTTT Webhooks, but I would rather not use IFTTT for reliability reasons.
By actively embedding it in the event payload, do you mean to manually include that in the Event Value when publishing? Or is there another way to do this similar to how IFTTT can include it? If so, could you direct me to any resources you’re aware of to learn how to do this? I just don’t want to have to write 100 different Particle scripts for each device at each location. Sorry, I’m pretty new to the whole webhook/cloud API business.
That is a brilliant idea. I have been able to obtain and serially print the device name but have been unable to save the device name for later use in Event Contents/Body. I attempted to make a global variable “String dev_name” and write String(data) (which is the Device Name) to it in the handler function when using Particle.Subscribe. However, dev_name is not overwriting and is remaining NULL. I also tried to first save “data” to the buffer using strcpy and strcpy_P then to the variable but to no avail. See below for example code. How does one save “data” as a String for later use?
First, I’d stay away from String and stick with char[] which can also be passed to Particle.publish().
And second, subscribing alone isn’t enough. You also need to ask the cloud to send you the name to your subscription.
char dev_name[32] = "";
bool publishName = false;
void handler(const char *topic, const char *data) {
strncpy(dev_name, data, sizeof(dev_name)-1);
Serial.printlnf("received %s: %s", topic, dev_name);
publishName = true;
}
void setup() {
Particle.subscribe("particle/device/name", handler);
Particle.publish("particle/device/name"); // <-- ask the cloud for the name to be sent to you
}
void loop() {
if (publishName) {
Particle.publish("twilio_sms", dev_name, PRIVATE);
delay(1000); // to ensure adhering to rate limit
publishName = false;
}
}
I am new to Particle and also fairly new to IoT. I would like to display my device name and also was trying to flash two different electrons with same firmware. I currently hard coded the device name into the firmware but I am looking for a much better solution. For some reason particle json does not accept string or float values. Is there something I am doing wrong. Can someone help me with that.
@ScruffR I did refer to the document you mentioned. I have created a webhook with custom body. It has issues displaying string. It displays only integers and float.
I know this was almost 2 years ago, but I implemented this in my code today and had some unexpected behavior. Initially I tried a shortcut leaving the loop empty and moving the publish to Twilio_sms directly under the publish to "particle/device/name" with a 1 sec delay between them. I thought this would work and only send the SMS once while not having to include the publishName flag, but i was receiving a "null" by SMS. Once I moved the twilio_sms publish into the loop, it worked.
Two Questions:
Why did it only work with the twilio_sms publish in the loop. I'm an entry level coder, but I'm sure there's a basic explanation.
I haven't researched this more than 15 min, but since I'm writing this post. Is there a simple way to concatenate the device name with another message such as "Device01 restarted" (assuming the device is called device01). With the below code, it compiles, but returns only the device name.
You are requesting the device name from the cloud - which is an asynchronous action.
The Particle.publish() call only sends the request to the cloud, it doesn’t wait for the response. The time for the response to come in and be treated via your subscribe handler was obviously longer than your delay. delay(1000) only lets the cloud tasks run once every 1000ms, so even if the response was already there the device OS couldn’t actually deal with it in the first 1000ms of that delay.
If you write it like this it should also work
void setup() {
Particle.subscribe("particle/device/name", handler);
Particle.publish("particle/device/name");
// allow for up to 3 sec and maximum time to attend to cloud tasks
for (uint32_t ms = millis(); millis() - ms < 3000 && !publishName; Particle.process());
Particle.publish("twilio_sms", dev_name, PRIVATE);
}
Very helpful as always.
I didn’t think about the delay also locking up the system from dealing with the response. That clarifies it and I’ll use your alternative stalling method going forward. I just wanted to make sure I wasn’t missing some fundamental principle of how the setup and loop functions interact.
I tried the code below with SYSTEM_THREAD(ENABLED); and it won’t work. Any suggestions on how to get this working with that enabled?
void setup() {
Particle.subscribe("particle/device/name", handler);
Particle.publish("particle/device/name");
// allow for up to 3 sec and maximum time to attend to cloud tasks
for (uint32_t ms = millis(); millis() - ms < 3000 && !publishName; Particle.process());
Particle.publish("twilio_sms", dev_name, PRIVATE);
}
That worked but I’m running into an odd issue.
I created at app the that will process the device rename and after 3 seconds invoke a System.reset(); function. The device reboots but I still get the old name when having this code in the setup
When I completely power off and power on device it works as designed. What is so special about System.reset() that doesn’t allow the device to get the new name pulled properly?
To tell more we’d need to know how exactly you are renaming the device, how your subscribe handler works and how you have the device name stored on your device.
The apps successfully rename the device because the Console shows the updated name.
I have an iOS and Android app and use code similar to the following
iOS
myPhoton!.rename("myNewDeviceName", completion: { (error:Error?) -> Void in
if (error == nil) {
print("Device successfully renamed")
// Call Reset Function
}
})
Android
particleDevice.setName(newName); // Call Reset Function