@BulldogLowell I got it working using topics!
The code I used is a mix between the latest code in the Particle Documentation which uses a different formatted Particle.subscribe
function code.
Here is what I used that is working so far:
@ScruffR Am I using the correct container format to hold the cityLocation & statLocation text? I see you can use strings also, but I just searched around on the forum until I found more code by @BulldogLowell
where he used the const char*
Program Code:
// called once on startup
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.
// Learn more about the serial commands at https://docs.particle.io/reference/firmware/photon/#serial
// for the Photon, or https://docs.particle.io/reference/firmware/core/#serial for the Core
// You can also watch what's sent over serial with the particle cli with
// particle serial monitor
Serial.begin(115200);
// Lets listen for the hook response
// Subscribe to the integration response event
Particle.subscribe(System.deviceID() + "_current_weather", gotWeatherData, 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);
// and wait at least 60 seconds before doing it again
delay(60000 * 5 );
}
// 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.
//
// Sample data:
// <location>Minneapolis, Minneapolis-St. Paul International Airport, MN</location>
// <weather>Overcast</weather>
// <temperature_string>26.0 F (-3.3 C)</temperature_string>
// <temp_f>26.0</temp_f>
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);
}
}
// 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);
}
The Post URL is: http://api.wunderground.com/api/YourAPIkey/conditions/q/{{my-state}}/{{my-city}}.json

