Your new topic does not fit any of the above??? Check first. Then post here. Thanks.

Moderator: igrr

User avatar
By markstoehr
#64282 I have a XML feed http://www.toronto.ca/fire/cadinfo/livecad.xml that shows if a Fire Truck in Toronto Canada is on the road. I want to find a specific Fire Truck then turn ON an LED attached to the ESP. If not found keep LED OFF. I have added a sample XML feed and below that is my NOOB attempt at the code. I want to find 3 different trucks and turn on 3 different LEDS (R421 A421 LA421)

The problem I'm having is that String content = client.readStringUntil('\n'); reads line by line and if the truck say R421 is found it turns ON the LED but then continues reading down the page and turns it OFF again.

1. Can String content = client.readStringUntil('\n'); read the entire page at once into a String and not line by line?

2. How can i loop through or add the additional trucks?


XML Sample

Code: Select all<tfs_active_incidents>
<update_from_db_time>2017-03-27 11:58:25</update_from_db_time>
<event>
<prime_street>DUFFERIN ST NY_HARVEY'S ,</prime_street>
<cross_streets>/</cross_streets>
<dispatch_time>2017-03-27 11:53:37</dispatch_time>
<event_num>F17027706</event_num>
<event_type>Medical - Trouble Breathing</event_type>
<alarm_lev>0</alarm_lev>
<beat>145</beat>
<units_disp>P142,</units_disp>
</event>
<event>
<prime_street>HUMBER BLVD, YK</prime_street>
<cross_streets>ALLIANCE AVE / HILLDALE RD</cross_streets>
<dispatch_time>2017-03-14 17:22:57</dispatch_time>
<event_num>F17023566</event_num>
<event_type>Alarm Highrise Residential</event_type>
<alarm_lev>0</alarm_lev>
<beat>421</beat>
<units_disp> R421, A421, R423, C42, LA421</units_disp>
</event>
</tfs_active_incidents>


My arduino code is

Code: Select all#include <ESP8266WiFi.h>

const char* ssid = "*********"; //actual removed
const char* password = "******"; //actual removed
////LIVE SERVER/////
//const char* host = "www.toronto.ca";
//String url = "/fire/cadinfo/livecad.xml";
////////////////////////////
////LOCAL TEST SERVER/////
const char* host = "192.168.1.103";
String url = "/tfs.xml";
////////////////////////////
int find_text(String needle, String haystack,int from) {
  int foundpos = -1;
  if (haystack.length()<needle.length())
    return foundpos;
  for (int i = from; (i < haystack.length() - needle.length()); i++) {
    if (haystack.substring(i,needle.length()+i) == needle) {
      foundpos = i;
      return foundpos;
    }
  }
  return foundpos;
}

void setup() {
  Serial.begin(115200);
  delay(100);
  pinMode(5, OUTPUT); //WIFI Indicator
  pinMode(14, OUTPUT); // First Truck
  pinMode(12, OUTPUT); // Second Truck
  pinMode(13, OUTPUT); // Third Truck
 
 // We start by connecting to a WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
 
  WiFi.begin(ssid, password);
 
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  digitalWrite(5, HIGH);
  delay(250);
  digitalWrite(5, LOW);
  delay(250);
  digitalWrite(5, HIGH);
  delay(250);
  digitalWrite(5, LOW);
  delay(250);
  digitalWrite(5, HIGH);
  delay(250);
  Serial.println("");
  Serial.println("WiFi connected"); 
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  Serial.println();
  Serial.println();
  Serial.println("LED Test");
 // Blink LEDS for test CODE REMOVED for now
}
void loop() {
  // Use WiFiClient class to create TCP connections
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
  }
   // We now create a URI for the request
  Serial.print("Requesting URL: ");
  Serial.println(url);
    Serial.println();
  // This will send the request to the server
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");
  delay(500);
// FIND R421
while(client.available()){
  String content = client.readStringUntil('\n');
  Serial.print(content);
        Serial.println(); 
int R421 = find_text("R421",content,0);
if (R421 == -1)
{
  Serial.println(R421);
  digitalWrite(14, LOW);
}
else
{
  Serial.println();
  Serial.println();
  Serial.println();
  Serial.println("---------------------------------"); 
  Serial.println(R421);
  Serial.println("R421 On Call");
  digitalWrite(14, HIGH);
  Serial.println("---------------------------------");
  Serial.println();
  Serial.println();
  Serial.println();
}
}
  delay(15000);//15sec
//  delay(30000);//30sec
//  delay(180000);//3min
}
User avatar
By markstoehr
#64337 Thanks for the response. I did try changing the line but it causes the ESP to randomly crash. I have got a bit further on my code. It may be ugly but it works. It now finds the 3 trucks and the LEDs turn ON but i have a big problem. The find_text function finds A421 and LA421 both as A421.

I need to be able to tell the function that the character before can only be a space or >.

I also need to cleanup the code and make it smaller maybe with some sort of array for the trucks and foreach??
int trucks[3]={R421,A421,LA421}; ?? Work in progress.


I need to change this to only allow the previous character to be a space or >

Code: Select allint find_text(String needle, String haystack,int from) {
  int foundpos = -1;
  if (haystack.length()<needle.length())
    return foundpos;
  for (int i = from; (i < haystack.length() - needle.length()); i++) {
    if (haystack.substring(i,needle.length()+i) == needle) {
      foundpos = i;
      return foundpos;
    }
  }
  return foundpos;
}


My Full Code

Code: Select all#include <ESP8266WiFi.h>
const char* ssid = "********"; //actual removed
const char* password = "**********"; //actual removed
////LIVE SERVER/////
//const char* host = "www.toronto.ca";
//String url = "/fire/cadinfo/livecad.xml";
////////////////////////////
////LOCAL TEST SERVER/////
const char* host = "***********";
String url = "/tfs.xml";
////////////////////////////
int find_text(String needle, String haystack,int from) {
  int foundpos = -1;
  if (haystack.length()<needle.length())
    return foundpos;
  for (int i = from; (i < haystack.length() - needle.length()); i++) {
    if (haystack.substring(i,needle.length()+i) == needle) {
      foundpos = i;
      return foundpos;
    }
  }
  return foundpos;
}
void setup() {
  Serial.begin(115200);
  delay(100);
  pinMode(5, OUTPUT); //WIFI Indicator
  pinMode(14, OUTPUT); // First Truck
  pinMode(12, OUTPUT); // Second Truck
  pinMode(13, OUTPUT); // Third Truck
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  digitalWrite(5, HIGH);
  delay(250);
  digitalWrite(5, LOW);
  delay(250);
  digitalWrite(5, HIGH);
  delay(250);
  digitalWrite(5, LOW);
  delay(250);
  digitalWrite(5, HIGH);
  delay(250);
  Serial.println("");
  Serial.println("WiFi connected"); 
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.println();
  Serial.println();
  Serial.println("LED Test");
 // Blink LEDS for test CODE REMOVED for now
}
void loop() {
  // Use WiFiClient class to create TCP connections
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
  }
   // We now create a URI for the request
  Serial.print("Requesting URL: ");
  Serial.println(url);
    Serial.println();
  // This will send the request to the server
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");
  delay(500);
// FIND R421
int XXX = 0;
int YYY = 0;
int ZZZ = 0;
while(client.available()){
  String content = client.readStringUntil('\n');
  Serial.print(content);
        Serial.println(); 
////////////////////////////////////////////////////////////////
int XX = find_text(" R421",content,0);
if (XXX != 1){
if (XX == -1)
{
  XXX = 0;
}
else
{
  XXX = 1;
}
}
////////////////////////////////////////////////////////////////
int YY = find_text(" A421",content,0);
if (YYY != 1){
if (YY == -1)
{
  YYY = 0;
}
else
{
  YYY = 1;
}
}
////////////////////////////////////////////////////////////////
int ZZ = find_text(" LA421",content,0);
if (ZZZ != 1){
if (ZZ == -1)
{
  ZZZ = 0;
}
else
{
  ZZZ = 1;
}
}
////////////////////////////////////////////////////////////////
}
////////////////////////////////////////////////////////////////
if (XXX == 1)
{
  Serial.println();
  Serial.println("---------------------------------"); 
  Serial.println("R421 On Call");
  digitalWrite(14, HIGH);
  Serial.println("---------------------------------");
  Serial.println();
}
else
{
    digitalWrite(14, LOW);
}
////////////////////////////////////////////////////////////////
if (YYY == 1)
{
  Serial.println();
  Serial.println("---------------------------------"); 
  Serial.println("A421 On Call");
  digitalWrite(12, HIGH);
  Serial.println("---------------------------------");
  Serial.println();
}
else
{
    digitalWrite(12, LOW);
}
////////////////////////////////////////////////////////////////
if (ZZZ == 1)
{
  Serial.println();
  Serial.println("---------------------------------"); 
  Serial.println("LA421 On Call");
  digitalWrite(13, HIGH);
  Serial.println("---------------------------------");
  Serial.println();
}
else
{
    digitalWrite(13, LOW);
}
////////////////////////////////////////////////////////////////
  delay(15000);//15sec
//  delay(30000);//30sec
//  delay(180000);//3min
}
User avatar
By lethe
#64340 Reading the entire output at once may not be a good idea, since you don't know how large the output will be and RAM is very limited... It's also completely unecessary.

The issue with your original code is, that you set or clear the LEDs with each line you read.
Just reorganize your code a bit and it will work as expected:
1) use a bool variable for each truck
2) set all variables to false before you do the HTTP request
3) parse each line as you do right now, if you find a specific truck ID, set its variable to true
4) when you have read the complete reply (after the "while(client.available())" loop), set all LEDs according to the corresponding truck's bool variable