Iād simplify the subscribe to respond to ANY publish preceded by your device ID and then sort it out from there:
Serial.begin(115200);
// Lets listen for the hook response
// Subscribe to the integration response event
Particle.subscribe(System.deviceID(), deviceWebhookHandler, MY_DEVICES); // every webhook preceeded by your deviceID gets handled by deviceWebhookHandler()!!
//Particle.subscribe(System.deviceID() + "_current_weather", gotWeatherData, MY_DEVICES);
//Particle.subscribe(System.deviceID() + "_Test3", gotForecast2, MY_DEVICES);
//Particle.subscribe(System.deviceID() + "_SunFishersIN", gotSunData, MY_DEVICES);
then sort it using the handler, you donāt need the deviceID here because you already filtered for that!!
void deviceWebhookHandler(const char* event, const char* data)
{
if(strstr(event, "current_weather")
{
gotWeatherData(event, data);
}
else if(strstr(event, "SunFishersIN")
{
gotSunData(event, data);
}
else if(strstr(event, "Test3")
{
gotForecast2(event, data)
}
else
{
Serial.println("recieved some unknown webhook");
}
}
finally, letās verify that the function got called by adding a publish that identifies it:
void gotForecast2(const char* event, const char* data)
{
Particle.publish("Handling my forecast!!", data); // so you know you are here... watch the console
static char weatherData[1024] = "";
if (strstr(event, "Test3/0"))
{
strcpy(weatherData, "");
strcpy(weatherData, data);
Serial.println(weatherData);
}
else if (strstr(event, "Test3/1"))
{
strcat(weatherData, data); //concatenate the first return with the second
// tokenize and parse here...
// strtok(weatherData, "~");
Serial.println(weatherData);
}
else
{
// error handling here...
}
}
entire edit:
const char* cityLocation = "Marion"; //City for my Photon
const char* stateLocation = "IN"; // State for my Photon
char publishString[128];
void setup() {
// For simplicity, we'll format our weather data as text, and pipe it to serial.
// but you could just as easily display it in a webpage or pass the data to another system.
Serial.begin(115200);
// Lets listen for the hook response
// Subscribe to the integration response event
Particle.subscribe(System.deviceID(), deviceWebhookHandler, MY_DEVICES); // every webhook preceeded by your deviceID gets handled by deviceWebhookHandler()!!
//Particle.subscribe(System.deviceID() + "_current_weather", gotWeatherData, MY_DEVICES);
//Particle.subscribe(System.deviceID() + "_Test3", gotForecast2, MY_DEVICES);
//Particle.subscribe(System.deviceID() + "_SunFishersIN", gotSunData, MY_DEVICES);
// Lets give ourselves 10 seconds before we actually start the program.
// That will just give us a chance to open the serial monitor before the program sends the request
for (int i = 0; i < 10; i++) {
Serial.println("waiting " + String(10 - i) + " seconds before we publish");
delay(1000);
}
}
// called forever really fast
void loop() {
// Let's request the weather, but no more than once every 60 seconds.
Serial.println("");
Serial.println("-------------------");
Serial.println("Requesting Weather!");
Serial.println("");
sprintf(publishString, "{\"my-city\": \"%s\", \"my-state\": \"%s\" }", cityLocation, stateLocation);
// publish the event that will trigger our Webhook
Particle.publish("current_weather", publishString, PRIVATE);
delay(5000);
//Particle.publish("SunFishersIN");
Particle.publish("Test3", publishString, PRIVATE);
// and wait at least 60 seconds before doing it again
delay(60000 * 5 );
}
void deviceWebhookHandler(const char* event, const char* data)
{
if(strstr(event, "current_weather")
{
gotWeatherData(event, data);
}
else if(strstr(event, "SunFishersIN")
{
gotSunData(event, data);
}
else if(strstr(event, "Test3")
{
gotForecast2(event, data)
}
else
{
Serial.println("recieved some unknown webhook");
}
}
///////////////////////////////////////////////////////////////////////////
// This function will get called when weather data comes in
void gotWeatherData(const char *name, const char *data) {
// Important note! -- Right now the response comes in 512 byte chunks.
// This code assumes we're getting the response in large chunks, and this
// assumption breaks down if a line happens to be split across response chunks.
String str = String(data);
String locationStr = tryExtractString(str, "<Location>", "</Location>");
String timeStr = tryExtractString(str, "<Time>", "</Time>");
String weatherdiscriptionStr = tryExtractString(str, "<WeatherDescription>", "</WeatherDescription>");
String tempStr = tryExtractString(str, "<Temp>", "</Temp>");
String humidityStr = tryExtractString(str, "<Humidity>", "</Humidity>");
String windStr = tryExtractString(str, "<Wind>", "</Wind>");
String heatindexStr = tryExtractString(str, "<HeatIndex>", "</HeatIndex>");
String windchillStr = tryExtractString(str, "<WindChill>", "</WindChill>");
String feelslikeStr = tryExtractString(str, "<FeelsLike>", "</FeelsLike>");
String visibilityStr = tryExtractString(str, "<Visibility>", "</Visibility>");
String sunradiationStr = tryExtractString(str, "<SunRadiation>", "</SunRadiation>");
String uvindexStr = tryExtractString(str, "<UvIndex>", "</UvIndex>");
String totalrainStr = tryExtractString(str, "<TotalRainInches>", "</TotalRainInches>");
String iconStr = tryExtractString(str, "<Icon>", "</Icon>");
if (locationStr != NULL) {
Serial.println("Weather for: " + locationStr);
}
if (timeStr != NULL) {
Serial.println("Timestamp: " + timeStr);
}
if (weatherdiscriptionStr != NULL) {
Serial.println("Weather Conditon: " + weatherdiscriptionStr);
}
if (tempStr != NULL) {
Serial.println("The Temp is: " + tempStr + String(" F"));
}
if (feelslikeStr != NULL) {
Serial.println("The Real Feel Temp is: " + feelslikeStr + String(" F"));
}
if (humidityStr != NULL) {
Serial.println("The Humidity is: " + humidityStr );
}
if (windStr != NULL) {
Serial.println("Wind Conditions: " + windStr);
}
if (heatindexStr != NULL) {
Serial.println("The Heat Index is: " + heatindexStr + String(" F"));
}
if (windchillStr != NULL) {
Serial.println("The Wind Chill Index is: " + windchillStr + String(" F"));
}
if (visibilityStr != NULL) {
Serial.println("The Visibility is: " + visibilityStr + String(" Miles"));
}
if (sunradiationStr != NULL) {
Serial.println("The Solar Radiation is: " + sunradiationStr + String(" W/m2"));
}
if (uvindexStr != NULL) {
Serial.println("The UV Index is: " + uvindexStr );
}
if (totalrainStr != NULL) {
Serial.println("Total Daily Rain Fall: " + totalrainStr + String(" Inches"));
}
if (iconStr != NULL) {
Serial.println("Icon for current weather: " + iconStr);
}
}
//////////////////////////////////////////////////////////////////////////////
void gotForecast2(const char* event, const char* data)
{
Particle.publish("Handling my forecast!!", data); // so you know you are here... watch the console
static char weatherData[1024] = "";
if (strstr(event, "Test3/0"))
{
strcpy(weatherData, "");
strcpy(weatherData, data);
Serial.println(weatherData);
}
else if (strstr(event, "Test3/1"))
{
strcat(weatherData, data); //concatenate the first return with the second
// tokenize and parse here...
// strtok(weatherData, "~");
Serial.println(weatherData);
}
else
{
// error handling here...
}
}
///////////////////////////////////////////////////////////////////////
// This function will get called when weather data comes in
void gotSunData(const char *name, const char *data) {
// Important note! -- Right now the response comes in 512 byte chunks.
// This code assumes we're getting the response in large chunks, and this
// assumption breaks down if a line happens to be split across response chunks.
//
// Sample data:
// <location>Minneapolis, Minneapolis-St. Paul International Airport, MN</location>
https://build.particle.io/build/5714505f328841b54e0002c2# // <weather>Overcast</weather>
// <temperature_string>26.0 F (-3.3 C)</temperature_string>
// <temp_f>26.0</temp_f>
String str = String(data);
String sunrisehourStr = tryExtractString(str, "<SunriseHour>", "</SunriseHour>");
String sunriseminuteStr = tryExtractString(str, "<SunriseMin>", "</SunriseMin>");
String sunsethourStr = tryExtractString(str, "SunsetHour>", "</SunsetHour>");
String sunsetminuteStr = tryExtractString(str, "<SunsetMinute>", "</SunsetMinute>");
uint hourofsunset = sunsethourStr.toInt();
int adjsunsethour = (hourofsunset - 12);
if (sunrisehourStr != NULL) {
Serial.println("Sunrise at: " + sunrisehourStr + String(":") + sunriseminuteStr + String(" AM") + " / Sunset at: " + adjsunsethour + String(":") + sunsetminuteStr + String(" PM"));
}
Serial.println("-------------------");
Serial.println("");
}
/////////////////////////////////////////////////////////////////////////
// Returns any text found between a start and end string inside 'str'
// example: startfooend -> returns foo
String tryExtractString(String str, const char* start, const char* end) {
if (str == NULL) {
return NULL;
}
int idx = str.indexOf(start);
if (idx < 0) {
return NULL;
}
int endIdx = str.indexOf(end);
if (endIdx < 0) {
return NULL;
}
return str.substring(idx + strlen(start), endIdx);
}
not compiled, not tested