OK I verified that that's the case. It seems to have to do with the reference clock in use.
I verified that __wrap_clock_gettime(CLOCK_REALTIME, ...) or __wrap_clock_gettime(CLOCK_MONOTONIC, ...) give a similar result. However, there seems to be a CLOCK_HOST_REALTIME defined by Xenomai which seems to return the correct date. That define evaluates to 32, so you could do this:

extern int __wrap_clock_gettime(clockid_t clk_id, struct timespec *tp);
...

    struct timespec tp;
    __wrap_clock_gettime(32, &tp);
    secondes = tp.tv_sec;
   ...

this should give you the desired result.

BTW, there's plenty of duplicated code in your external that you may want to tidy up all in one place (namely, the calls to time() and localtime_r()). Also, it looks like when you call ahora_bang() the behaviour is to output values from all outputs starting from the one set in the creation argument. Is that expected/desired or are should you have a break at the end of each case statement?

    giuliomoro Also, it looks like when you call ahora_bang() the behaviour is to output values from all outputs starting from the one set in the creation argument. Is that expected/desired or are should you have a break at the end of each case statement?

    The compiler too warned me about that, but it is the purpose: you choose to trigger the last n outputs. I confess it is a bit redundant since you can also trigger the desired outputs banging messages... But for who wants only the time, most of user a guess, it's convenient.

    I'll check about duplicated code, and try CLOCK_HOST_REALTIME...

    It's worth mentioning that for any of this to yield accurate results over time you'll need to have Bela connected to the internet or a local ntp server so that it can keep its clock up to date...

      giuliomoro It's worth mentioning that for any of this to yield accurate results over time you'll need to have Bela connected to the internet or a local ntp server so that it can keep its clock up to date...

      sure... and setup timezone:
      #timedatectl set-timezone [timezone name]
      found with:
      #timedatectl list-timezones

      It is working finally, thank you! I confess I'm not sure I understood everything I did with xenomai, but I'll dig that...
      here is the code and the bin

        The factoring out of x->getTime() looks good.

        There are some errors in the file, it won't build as is. Among others, you are forward-declaring __wrap_time() but then using __wrap_clock_gettime().

        rph-r I confess I'm not sure I understood everything I did with xenomai, but I'll dig that...

        __wrap_SOMEFUNCTION() calls the Xenomai version of SOMEFUNCTION (if available). The forward declaration (extern someret __wrap_SOMEFUNCTION(someargs)) is a lazy workaround so that you don't need to find the correct file to include and add it to the include path or modify the #include statements).

        Now the issue we encountered is that Xenomai's time() or clock_gettime(CLOCK_REALTIME, ...) gives unexpected results (it probably reports the time since boot?). This is probably a bug in Xenomai (or a feature, but I can't find it docuemented) and propagates to the use of time() - which also uses CLOCK_REALTIME under the hood. By trial and error I figured out that CLOCK_HOST_REALTIME yields correct results. However, time() doesn't support specifying the clock, so we have to use clock_gettime(CLOCK_HOST_REALTIME, ...) instead, and extract the seconds from the value it returns. As CLOCK_HOST_REALTIME is defined in the Xenomai include, we once more work around it by hardcoding its value 32.

        Now that things work, if you wanted to tidy things up in a way that your external can be built on any platform but picks up Xenomai includes and functions if available, you could do the following:

        • add this line to the Makefile before including the pdlibbuilder makefile:
          CPPFLAGS=-I/usr/xenomai/include/cobalt -I/usr/xenomai/include
          This will tell it to look for the Xenomai includes and it will pick up time.h from there, declaring __wrap_clock_gettime() and defining CLOCK_HOST_REALTIME
        • then in the C file you can do simply:
          #ifdef CLOCK_HOST_REALTIME
            // Xenomai clock, if available
            __wrap_clock_gettime(CLOCK_HOST_REALTIME , &tp);
          #else
            clock_gettime(CLOCK_REALTIME , &tp);
          #endif

        This is a bit nicer and doesn't require much platform detection: on most systems, /usr/xenomai/ won't exist and so the include paths you set in CPPFLAGS will be ignored. Note: in principle a change like this would also require to add a library to the list of shared libraries to link the external against. However, we rely on the host (the Bela core in this case) to load that library for us. That's not as neat, but it allows to keep things simple in the Makefile.


        Further refactoring could see using a class_addanything instead of individual methods for the various year, month, day etc, but as that's so poorly documented (i.e.: undocumented) in Pd I don't blame you.

        It would probably look something like:

        void ahora_anything(t_ahora *x, t_symbol* s, int argc, t_atom* argv)
        {
          x->get_time(x);
          if(s == gensym("year"))
            outlet_float(x->year_out , 1900+x->instant.tm_year) ;
         else if(s == gensym("month"))
            outlet_float(x->month_out , 1+x->instant.tm_mon) ;
        else if ...
        //
        else
          pd_error(x, "no method for %s\n", s->s_name);
        }
        
        
        // in ahora_setup(), instead of all the individual ahora_addmethod() calls:
        class_addanything(ahora_class, (t_anymethod)ahora_anything);

        Not sure if's worth anyone's time, but it would look nicer -- if it works. I hope the bang method still works, otherwise you need to add it as a case in the chain of ifs in ahora_anything().

        Btw, you may also want to make the creation argument a symbol instead of a float and convert that to a number internally before storing it into x->whichout, that would make it more user-friendly.

        20 days later

        I had to focus on the core of my sound installation past two weeks, but after that I'll finish this object for sure!
        By the way: doe's Beaglebone/Bela sync the time periodically when connected to internet or should I write a cron job?

          rph-r doe's Beaglebone/Bela sync the time periodically when connected to internet or should I write a cron job?

          It automatically synchronises.