Problem with Time sync from Local HTTP server of Raspberry Pi

I am running local HTTP server that will return current UTC time in milliseconds as a response of get method.

I am trying the below logic to get the timestamp and syncing it on my particle argon every one hour. But it gets proper response sometimes and remaining time getting -1 as response and time sync fails. Kindly provide the suggestions and fixes.

Other Details:
Current Os version used : 3.0.0


#include <HttpClient.h>
byte mac[6];

SYSTEM_MODE(MANUAL);
SerialLogHandler logHandler(LOG_LEVEL_TRACE);


#define ONE_DAY_MILLIS (1 * 60 * 60 * 1000)
unsigned long lastSync;


HttpClient http;
http_header_t headers[] = {
{ "Accept" , "*/*"},
{ NULL, NULL } // NOTE: Always terminate headers will NULL
};

http_request_t request;
http_response_t response;
IPAddress timeServerIP(192, 168, 1, 125);

void setup() {
    (void)logHandler;// Does nothing, just to eliminate warning for unused variable
    
    
    BLE.setScanTimeout(6);
    syncTime();


}



void loop() {
    if (millis() - lastSync >= ONE_DAY_MILLIS) {
        syncTime();

    }
	
	//other Logics of code ...........
    
} 



void syncTime(){

    WiFi.on();
    WiFi.connect();
    waitFor(WiFi.ready,60000);
    
    WiFi.macAddress(mac);
    
    request.ip = timeServerIP;
    request.port = 5002;
    request.path = "/getTime";
    
    http.get(request, response, headers);
    Time.setTime((response.body).toInt());
    lastSync = millis();
    Particle.disconnect();
    WiFi.disconnect();
    WiFi.off();

}

To find out what’s going on, you could first check response.body for its string value before unconditionally converting it into a numeric value.
That might give you some clue of what may be going on. We don’t know what your time server sends in these cases.

Whenever the status code is 200 I am getting response.body as timestamp like “1676379388” in UTC. When the code is -1 it is blank.

Also don’t forget to check response.status :wink:

You could also enable logging in the HttpClient library to give you some extra insight.
response.status == -1 indicates that there was some other issue
see the implementation of the request() function

This time Response code is 200 but blank body. In addition to this it shows recv error = 128

Sure Let me have a look. Thanks for the suggestions :slightly_smiling_face:

1 Like

This is either named wrongly and should be named one hour or there should be a factor of 24 for the hours in day. Maybe this is debugging code?

I certainly agree with @ScruffR that blindly accepting the response body is not a good idea. I am also not sure using toInt() will work well since you want an unsigned representation there.

3 Likes

I modified the function like this and it is working good now. Checking Wifi.ready and status before setting time solves the problem.

void syncCloudTime(){


    WiFi.on();
    WiFi.connect();
    waitFor(WiFi.ready,60000);
    
    WiFi.macAddress(mac);
    
    request.ip = timeServerIP;
    request.port = 5002;
    request.path = "/getTime";
    
    if(WiFi.ready()){
    
        http.get(request, response, headers);
    
   
        if (response.status == 200){
            
        Time.setTime((response.body).toInt());
        lastSync = millis();
        Particle.disconnect();
        WiFi.disconnect();
        WiFi.off();
        }
        else{
        Particle.disconnect();
        WiFi.disconnect();
        WiFi.off();    
            
            
        }
        
   
    }
    
    else{
        Particle.disconnect();
        WiFi.disconnect();
        WiFi.off();
    
    }
    
   
}

You have a waitFor(WiFi.ready,60000); in your code already.
If that returns false you already know that the connection attempt timed out, so any subsequent WiFi action will be futile anyway. In that case you could either skip the rest of the function entirely or give it another try.

e.g.

void syncCloudTime() {
    WiFi.on();
    WiFi.connect();
    if (waitFor(WiFi.ready,60000)) {
      // success
      WiFi.disconnect();
    }
    else {
      // no connection
    }
  // unconditional needs
  WiFi.off();
}

BTW, you never call Particle.connect() hence I don't see the need for Particle.disconnect() in your code :confused:
You also have that entire block ...

... three times - once in each and every code path.
So it is unconditional and hence should be kept out of the conditional paths and be placed only once in the common path.

2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.