Copyright © https://mongoose-os.com

Mongoose OS Forum

frame

Set time of day from source other than SNTP using Javascript

My ESP32 device will not have access to an SNTP server. Occasionally, an SNTP synchronized system will connect to my device, and will deliver a timestamp which will be stored in an RTC chip on my device. How can I load the timestamp (received as a Javascript variable) into Mongoose so that I can retrieve it with Timer.now? Required resolution is 1 second. Errors of +/- 25 seconds from actual time are OK. I am trying to use mgos_settimeofday in an FFI call , but I am not sure whether this is the right approach, and I am getting the following error at bootup:

[Apr 19 10:37:20.979] MJS error: bad ffi signature: "int mgos_settimeofday(double, struct* timezone)": dlsym('mgos_settimeofday') failed

(and I have no idea what to do with the timezone structure).

Any ideas?

Thanks All,

JSW

Comments

  • edited April 19

    Is the ESP going to be constantly on and not using any power saving modes? If so, you might be able to get away with using epoch time, having a one second timer, and then just incrementing that number by 1 every time the timer goes off. Also try putting void* instead of "struct* timezone". That might work based upon past experience with this.

    https://mongoose-os.com/docs/api/api_timer.js.html

    Thanked by 1jstevewood
  • jstevewoodjstevewood California

    Hi applecrusher, Thanks for the suggestion, I'll try it. My device will essentially be off, with only battery backup to the RTC chip, for long periods of time (weeks to months). When the power comes back on, the ESP32 comes back to life, but because it may not have access to SNTP at power on, it needs to figure out the time by other means.

    Thanks,

    JSW

  • nliviunliviu Romania

    Assuming you can compute the unixtime, you can try this:

    function updateTimeFromUnixtime(unixtime)
    {
      /*
       struct timezone {
       int tz_minuteswest;
       int tz_dsttime;
       };
       */
      //allocate the struct tm and fill with zero
      let structTimezone = ffi('void *calloc(int, int)')(1, 2 * 4);
      let res = ffi('int mgos_settimeofday(double, void*)')(unixtime, structTimezone);
      Sys.free(structTimezone);
      return res;
    }
    

    Don't forget to add load('api_sys.js');.

    Thanked by 1jstevewood
  • jstevewoodjstevewood California

    Hi nliviu, Thanks for looking at this. I tried your code example (api_sys.js has always been loaded). The bad signature error moves one line earlier. I think that this is some kind of link or library problem. Can you publish YML and main.c includes? Thanks, JSW

    [Apr 20 09:52:26.359] MJS error: bad ffi signature: "void *calloc(int, int)": dlsym('calloc') failed

  • nliviunliviu Romania

    Strange, I'll create a simple project to test this.

  • nliviunliviu Romania

    Created a new project based on empty and it builds and runs as expected.
    You have to rebuild the app, not only upload the init.js.

  • jstevewoodjstevewood California

    Hi nliviu, It's solved! In my YML file, I had loaded demo-bundle first, followed by three rpc libraries the wifi library, and finally mjs. After I changed the demo-bundle to js-demobundle (or if I leave demo-bundle there and add js-demobundle), the symbols resolve. I tried updateTimeFromUnix, and it works as desired. Thank you for the help. JSW

  • nliviunliviu Romania

    NP :)
    js-demo-bundle includes demo-bundle + mjs.

Sign In or Register to comment.